diff --git a/[refs] b/[refs] index c60daf0fab88..a66362658938 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 70a3075d40154053ad90d342b3dcb1b795c73dbb +refs/heads/master: 891cffbd6bcba26409869c19c07ecd4bfc0c2460 diff --git a/trunk/Documentation/00-INDEX b/trunk/Documentation/00-INDEX index 7286ad090db7..73060819ed99 100644 --- a/trunk/Documentation/00-INDEX +++ b/trunk/Documentation/00-INDEX @@ -21,9 +21,6 @@ Changes - list of changes that break older software packages. CodingStyle - how the boss likes the C code in the kernel to look. -development-process/ - - An extended tutorial on how to work with the kernel development - process. DMA-API.txt - DMA API, pci_ API & extensions for non-consistent memory machines. DMA-ISA-LPC.txt @@ -162,6 +159,8 @@ hayes-esp.txt - info on using the Hayes ESP serial driver. highuid.txt - notes on the change from 16 bit to 32 bit user/group IDs. +hpet.txt + - High Precision Event Timer Driver for Linux. timers/ - info on the timer related topics hw_random.txt diff --git a/trunk/Documentation/ABI/testing/sysfs-class-regulator b/trunk/Documentation/ABI/testing/sysfs-class-regulator index 3731f6f29bcb..79a4a75b2d2c 100644 --- a/trunk/Documentation/ABI/testing/sysfs-class-regulator +++ b/trunk/Documentation/ABI/testing/sysfs-class-regulator @@ -1,7 +1,7 @@ What: /sys/class/regulator/.../state Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called state. This holds the regulator output state. @@ -27,7 +27,7 @@ Description: What: /sys/class/regulator/.../type Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called type. This holds the regulator type. @@ -51,7 +51,7 @@ Description: What: /sys/class/regulator/.../microvolts Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called microvolts. This holds the regulator output voltage setting @@ -65,7 +65,7 @@ Description: What: /sys/class/regulator/.../microamps Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called microamps. This holds the regulator output current limit @@ -79,7 +79,7 @@ Description: What: /sys/class/regulator/.../opmode Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called opmode. This holds the regulator operating mode setting. @@ -102,7 +102,7 @@ Description: What: /sys/class/regulator/.../min_microvolts Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called min_microvolts. This holds the minimum safe working regulator @@ -116,7 +116,7 @@ Description: What: /sys/class/regulator/.../max_microvolts Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called max_microvolts. This holds the maximum safe working regulator @@ -130,7 +130,7 @@ Description: What: /sys/class/regulator/.../min_microamps Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called min_microamps. This holds the minimum safe working regulator @@ -145,7 +145,7 @@ Description: What: /sys/class/regulator/.../max_microamps Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called max_microamps. This holds the maximum safe working regulator @@ -157,23 +157,10 @@ Description: platform code. -What: /sys/class/regulator/.../name -Date: October 2008 -KernelVersion: 2.6.28 -Contact: Liam Girdwood -Description: - Each regulator directory will contain a field called - name. This holds a string identifying the regulator for - display purposes. - - NOTE: this will be empty if no suitable name is provided - by platform or regulator drivers. - - What: /sys/class/regulator/.../num_users Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called num_users. This holds the number of consumer devices that @@ -183,7 +170,7 @@ Description: What: /sys/class/regulator/.../requested_microamps Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called requested_microamps. This holds the total requested load @@ -194,7 +181,7 @@ Description: What: /sys/class/regulator/.../parent Date: April 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Some regulator directories will contain a link called parent. This points to the parent or supply regulator if one exists. @@ -202,7 +189,7 @@ Description: What: /sys/class/regulator/.../suspend_mem_microvolts Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_mem_microvolts. This holds the regulator output @@ -216,7 +203,7 @@ Description: What: /sys/class/regulator/.../suspend_disk_microvolts Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_disk_microvolts. This holds the regulator output @@ -230,7 +217,7 @@ Description: What: /sys/class/regulator/.../suspend_standby_microvolts Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_standby_microvolts. This holds the regulator output @@ -244,7 +231,7 @@ Description: What: /sys/class/regulator/.../suspend_mem_mode Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_mem_mode. This holds the regulator operating mode @@ -258,7 +245,7 @@ Description: What: /sys/class/regulator/.../suspend_disk_mode Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_disk_mode. This holds the regulator operating mode @@ -271,7 +258,7 @@ Description: What: /sys/class/regulator/.../suspend_standby_mode Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_standby_mode. This holds the regulator operating mode @@ -285,7 +272,7 @@ Description: What: /sys/class/regulator/.../suspend_mem_state Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_mem_state. This holds the regulator operating state @@ -300,7 +287,7 @@ Description: What: /sys/class/regulator/.../suspend_disk_state Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_disk_state. This holds the regulator operating state @@ -315,7 +302,7 @@ Description: What: /sys/class/regulator/.../suspend_standby_state Date: May 2008 KernelVersion: 2.6.26 -Contact: Liam Girdwood +Contact: Liam Girdwood Description: Each regulator directory will contain a field called suspend_standby_state. This holds the regulator operating diff --git a/trunk/Documentation/ABI/testing/sysfs-profiling b/trunk/Documentation/ABI/testing/sysfs-profiling deleted file mode 100644 index b02d8b8c173a..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-profiling +++ /dev/null @@ -1,13 +0,0 @@ -What: /sys/kernel/profile -Date: September 2008 -Contact: Dave Hansen -Description: - /sys/kernel/profile is the runtime equivalent - of the boot-time profile= option. - - You can get the same effect running: - - echo 2 > /sys/kernel/profile - - as you would by issuing profile=2 on the boot - command line. diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index fabc06466b93..1615350b7b53 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -6,7 +6,7 @@ # To add a new book the only step required is to add the book to the # list of DOCBOOKS. -DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml \ +DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml networking.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ diff --git a/trunk/Documentation/DocBook/procfs-guide.tmpl b/trunk/Documentation/DocBook/procfs-guide.tmpl index 9eba4b7af73d..8a5dc6e021ff 100644 --- a/trunk/Documentation/DocBook/procfs-guide.tmpl +++ b/trunk/Documentation/DocBook/procfs-guide.tmpl @@ -14,20 +14,17 @@ (J.A.K.) Mouw + Delft University of Technology + Faculty of Information Technology and Systems
- mouw@nl.linux.org + J.A.K.Mouw@its.tudelft.nl + PO BOX 5031 + 2600 GA + Delft + The Netherlands
- - - This software and documentation were written while working on the - LART computing board - (http://www.lartmaker.nl/), - which was sponsored by the Delt University of Technology projects - Mobile Multi-media Communications and Ubiquitous Communications. - - @@ -111,6 +108,18 @@ proofreading. + + This documentation was written while working on the LART + computing board (http://www.lart.tudelft.nl/), + which is sponsored by the Mobile Multi-media Communications + (http://www.mmc.tudelft.nl/) + and Ubiquitous Communications (http://www.ubicom.tudelft.nl/) + projects. + + Erik diff --git a/trunk/Documentation/DocBook/procfs_example.c b/trunk/Documentation/DocBook/procfs_example.c index 8c6396e4bf31..2f3de0fb8365 100644 --- a/trunk/Documentation/DocBook/procfs_example.c +++ b/trunk/Documentation/DocBook/procfs_example.c @@ -1,16 +1,28 @@ /* * procfs_example.c: an example proc interface * - * Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org) + * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl) * * This file accompanies the procfs-guide in the Linux kernel * source. Its main use is to demonstrate the concepts and * functions described in the guide. * * This software has been developed while working on the LART - * computing board (http://www.lartmaker.nl), which was sponsored - * by the Delt University of Technology projects Mobile Multi-media - * Communications and Ubiquitous Communications. + * computing board (http://www.lart.tudelft.nl/), which is + * sponsored by the Mobile Multi-media Communications + * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications + * (http://www.ubicom.tudelft.nl/) projects. + * + * The author can be reached at: + * + * Erik Mouw + * Information and Communication Theory Group + * Faculty of Information Technology and Systems + * Delft University of Technology + * P.O. Box 5031 + * 2600 GA Delft + * The Netherlands + * * * This program is free software; you can redistribute * it and/or modify it under the terms of the GNU General diff --git a/trunk/Documentation/DocBook/videobook.tmpl b/trunk/Documentation/DocBook/videobook.tmpl new file mode 100644 index 000000000000..0bc25949b668 --- /dev/null +++ b/trunk/Documentation/DocBook/videobook.tmpl @@ -0,0 +1,1654 @@ + + + + + + Video4Linux Programming + + + + Alan + Cox + +
+ alan@redhat.com +
+
+
+
+ + + 2000 + Alan Cox + + + + + This documentation 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 + + + + For more details see the file COPYING in the source + distribution of Linux. + + +
+ + + + + Introduction + + Parts of this document first appeared in Linux Magazine under a + ninety day exclusivity. + + + Video4Linux is intended to provide a common programming interface + for the many TV and capture cards now on the market, as well as + parallel port and USB video cameras. Radio, teletext decoders and + vertical blanking data interfaces are also provided. + + + + Radio Devices + + There are a wide variety of radio interfaces available for PC's, and these + are generally very simple to program. The biggest problem with supporting + such devices is normally extracting documentation from the vendor. + + + The radio interface supports a simple set of control ioctls standardised + across all radio and tv interfaces. It does not support read or write, which + are used for video streams. The reason radio cards do not allow you to read + the audio stream into an application is that without exception they provide + a connection on to a soundcard. Soundcards can be used to read the radio + data just fine. + + + Registering Radio Devices + + The Video4linux core provides an interface for registering devices. The + first step in writing our radio card driver is to register it. + + + + +static struct video_device my_radio +{ + "My radio", + VID_TYPE_TUNER, + radio_open. + radio_close, + NULL, /* no read */ + NULL, /* no write */ + NULL, /* no poll */ + radio_ioctl, + NULL, /* no special init function */ + NULL /* no private data */ +}; + + + + + This declares our video4linux device driver interface. The VID_TYPE_ value + defines what kind of an interface we are, and defines basic capabilities. + + + The only defined value relevant for a radio card is VID_TYPE_TUNER which + indicates that the device can be tuned. Clearly our radio is going to have some + way to change channel so it is tuneable. + + + We declare an open and close routine, but we do not need read or write, + which are used to read and write video data to or from the card itself. As + we have no read or write there is no poll function. + + + The private initialise function is run when the device is registered. In + this driver we've already done all the work needed. The final pointer is a + private data pointer that can be used by the device driver to attach and + retrieve private data structures. We set this field "priv" to NULL for + the moment. + + + Having the structure defined is all very well but we now need to register it + with the kernel. + + + + +static int io = 0x320; + +int __init myradio_init(struct video_init *v) +{ + if(!request_region(io, MY_IO_SIZE, "myradio")) + { + printk(KERN_ERR + "myradio: port 0x%03X is in use.\n", io); + return -EBUSY; + } + + if(video_device_register(&my_radio, VFL_TYPE_RADIO)==-1) { + release_region(io, MY_IO_SIZE); + return -EINVAL; + } + return 0; +} + + + + The first stage of the initialisation, as is normally the case, is to check + that the I/O space we are about to fiddle with doesn't belong to some other + driver. If it is we leave well alone. If the user gives the address of the + wrong device then we will spot this. These policies will generally avoid + crashing the machine. + + + Now we ask the Video4Linux layer to register the device for us. We hand it + our carefully designed video_device structure and also tell it which group + of devices we want it registered with. In this case VFL_TYPE_RADIO. + + + The types available are + + Device Types + + + + VFL_TYPE_RADIO/dev/radio{n} + + Radio devices are assigned in this block. As with all of these + selections the actual number assignment is done by the video layer + accordijng to what is free. + + VFL_TYPE_GRABBER/dev/video{n} + Video capture devices and also -- counter-intuitively for the name -- + hardware video playback devices such as MPEG2 cards. + + VFL_TYPE_VBI/dev/vbi{n} + The VBI devices capture the hidden lines on a television picture + that carry further information like closed caption data, teletext + (primarily in Europe) and now Intercast and the ATVEC internet + television encodings. + + VFL_TYPE_VTX/dev/vtx[n} + VTX is 'Videotext' also known as 'Teletext'. This is a system for + sending numbered, 40x25, mostly textual page images over the hidden + lines. Unlike the /dev/vbi interfaces, this is for 'smart' decoder + chips. (The use of the word smart here has to be taken in context, + the smartest teletext chips are fairly dumb pieces of technology). + + + + +
+ + We are most definitely a radio. + + + Finally we allocate our I/O space so that nobody treads on us and return 0 + to signify general happiness with the state of the universe. + +
+ + Opening And Closing The Radio + + + The functions we declared in our video_device are mostly very simple. + Firstly we can drop in what is basically standard code for open and close. + + + + +static int users = 0; + +static int radio_open(struct video_device *dev, int flags) +{ + if(users) + return -EBUSY; + users++; + return 0; +} + + + + At open time we need to do nothing but check if someone else is also using + the radio card. If nobody is using it we make a note that we are using it, + then we ensure that nobody unloads our driver on us. + + + + +static int radio_close(struct video_device *dev) +{ + users--; +} + + + + At close time we simply need to reduce the user count and allow the module + to become unloadable. + + + If you are sharp you will have noticed neither the open nor the close + routines attempt to reset or change the radio settings. This is intentional. + It allows an application to set up the radio and exit. It avoids a user + having to leave an application running all the time just to listen to the + radio. + + + + The Ioctl Interface + + This leaves the ioctl routine, without which the driver will not be + terribly useful to anyone. + + + + +static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + switch(cmd) + { + case VIDIOCGCAP: + { + struct video_capability v; + v.type = VID_TYPE_TUNER; + v.channels = 1; + v.audios = 1; + v.maxwidth = 0; + v.minwidth = 0; + v.maxheight = 0; + v.minheight = 0; + strcpy(v.name, "My Radio"); + if(copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + + + + VIDIOCGCAP is the first ioctl all video4linux devices must support. It + allows the applications to find out what sort of a card they have found and + to figure out what they want to do about it. The fields in the structure are + + struct video_capability fields + + + + nameThe device text name. This is intended for the user. + + channelsThe number of different channels you can tune on + this card. It could even by zero for a card that has + no tuning capability. For our simple FM radio it is 1. + An AM/FM radio would report 2. + + audiosThe number of audio inputs on this device. For our + radio there is only one audio input. + + minwidth,minheightThe smallest size the card is capable of capturing + images in. We set these to zero. Radios do not + capture pictures + + maxwidth,maxheightThe largest image size the card is capable of + capturing. For our radio we report 0. + + + typeThis reports the capabilities of the device, and + matches the field we filled in in the struct + video_device when registering. + + + +
+ + Having filled in the fields, we use copy_to_user to copy the structure into + the users buffer. If the copy fails we return an EFAULT to the application + so that it knows it tried to feed us garbage. + + + The next pair of ioctl operations select which tuner is to be used and let + the application find the tuner properties. We have only a single FM band + tuner in our example device. + + + + + case VIDIOCGTUNER: + { + struct video_tuner v; + if(copy_from_user(&v, arg, sizeof(v))!=0) + return -EFAULT; + if(v.tuner) + return -EINVAL; + v.rangelow=(87*16000); + v.rangehigh=(108*16000); + v.flags = VIDEO_TUNER_LOW; + v.mode = VIDEO_MODE_AUTO; + v.signal = 0xFFFF; + strcpy(v.name, "FM"); + if(copy_to_user(&v, arg, sizeof(v))!=0) + return -EFAULT; + return 0; + } + + + + The VIDIOCGTUNER ioctl allows applications to query a tuner. The application + sets the tuner field to the tuner number it wishes to query. The query does + not change the tuner that is being used, it merely enquires about the tuner + in question. + + + We have exactly one tuner so after copying the user buffer to our temporary + structure we complain if they asked for a tuner other than tuner 0. + + + The video_tuner structure has the following fields + + struct video_tuner fields + + + + int tunerThe number of the tuner in question + + char name[32]A text description of this tuner. "FM" will do fine. + This is intended for the application. + + u32 flags + Tuner capability flags + + + u16 modeThe current reception mode + + + u16 signalThe signal strength scaled between 0 and 65535. If + a device cannot tell the signal strength it should + report 65535. Many simple cards contain only a + signal/no signal bit. Such cards will report either + 0 or 65535. + + + u32 rangelow, rangehigh + The range of frequencies supported by the radio + or TV. It is scaled according to the VIDEO_TUNER_LOW + flag. + + + + +
+ + struct video_tuner flags + + + + VIDEO_TUNER_PALA PAL TV tuner + + VIDEO_TUNER_NTSCAn NTSC (US) TV tuner + + VIDEO_TUNER_SECAMA SECAM (French) TV tuner + + VIDEO_TUNER_LOW + The tuner frequency is scaled in 1/16th of a KHz + steps. If not it is in 1/16th of a MHz steps + + + VIDEO_TUNER_NORMThe tuner can set its format + + VIDEO_TUNER_STEREO_ONThe tuner is currently receiving a stereo signal + + + +
+ + struct video_tuner modes + + + + VIDEO_MODE_PALPAL Format + + VIDEO_MODE_NTSCNTSC Format (USA) + + VIDEO_MODE_SECAMFrench Format + + VIDEO_MODE_AUTOA device that does not need to do + TV format switching + + + +
+ + The settings for the radio card are thus fairly simple. We report that we + are a tuner called "FM" for FM radio. In order to get the best tuning + resolution we report VIDEO_TUNER_LOW and select tuning to 1/16th of KHz. Its + unlikely our card can do that resolution but it is a fair bet the card can + do better than 1/16th of a MHz. VIDEO_TUNER_LOW is appropriate to almost all + radio usage. + + + We report that the tuner automatically handles deciding what format it is + receiving - true enough as it only handles FM radio. Our example card is + also incapable of detecting stereo or signal strengths so it reports a + strength of 0xFFFF (maximum) and no stereo detected. + + + To finish off we set the range that can be tuned to be 87-108Mhz, the normal + FM broadcast radio range. It is important to find out what the card is + actually capable of tuning. It is easy enough to simply use the FM broadcast + range. Unfortunately if you do this you will discover the FM broadcast + ranges in the USA, Europe and Japan are all subtly different and some users + cannot receive all the stations they wish. + + + The application also needs to be able to set the tuner it wishes to use. In + our case, with a single tuner this is rather simple to arrange. + + + + case VIDIOCSTUNER: + { + struct video_tuner v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.tuner != 0) + return -EINVAL; + return 0; + } + + + + We copy the user supplied structure into kernel memory so we can examine it. + If the user has selected a tuner other than zero we reject the request. If + they wanted tuner 0 then, surprisingly enough, that is the current tuner already. + + + The next two ioctls we need to provide are to get and set the frequency of + the radio. These both use an unsigned long argument which is the frequency. + The scale of the frequency depends on the VIDEO_TUNER_LOW flag as I + mentioned earlier on. Since we have VIDEO_TUNER_LOW set this will be in + 1/16ths of a KHz. + + + +static unsigned long current_freq; + + + + case VIDIOCGFREQ: + if(copy_to_user(arg, &current_freq, + sizeof(unsigned long)) + return -EFAULT; + return 0; + + + + Querying the frequency in our case is relatively simple. Our radio card is + too dumb to let us query the signal strength so we remember our setting if + we know it. All we have to do is copy it to the user. + + + + + case VIDIOCSFREQ: + { + u32 freq; + if(copy_from_user(arg, &freq, + sizeof(unsigned long))!=0) + return -EFAULT; + if(hardware_set_freq(freq)<0) + return -EINVAL; + current_freq = freq; + return 0; + } + + + + Setting the frequency is a little more complex. We begin by copying the + desired frequency into kernel space. Next we call a hardware specific routine + to set the radio up. This might be as simple as some scaling and a few + writes to an I/O port. For most radio cards it turns out a good deal more + complicated and may involve programming things like a phase locked loop on + the card. This is what documentation is for. + + + The final set of operations we need to provide for our radio are the + volume controls. Not all radio cards can even do volume control. After all + there is a perfectly good volume control on the sound card. We will assume + our radio card has a simple 4 step volume control. + + + There are two ioctls with audio we need to support + + + +static int current_volume=0; + + case VIDIOCGAUDIO: + { + struct video_audio v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.audio != 0) + return -EINVAL; + v.volume = 16384*current_volume; + v.step = 16384; + strcpy(v.name, "Radio"); + v.mode = VIDEO_SOUND_MONO; + v.balance = 0; + v.base = 0; + v.treble = 0; + + if(copy_to_user(arg. &v, sizeof(v))) + return -EFAULT; + return 0; + } + + + + Much like the tuner we start by copying the user structure into kernel + space. Again we check if the user has asked for a valid audio input. We have + only input 0 and we punt if they ask for another input. + + + Then we fill in the video_audio structure. This has the following format + + struct video_audio fields + + + + audioThe input the user wishes to query + + volumeThe volume setting on a scale of 0-65535 + + baseThe base level on a scale of 0-65535 + + trebleThe treble level on a scale of 0-65535 + + flagsThe features this audio device supports + + + nameA text name to display to the user. We picked + "Radio" as it explains things quite nicely. + + modeThe current reception mode for the audio + + We report MONO because our card is too stupid to know if it is in + mono or stereo. + + + balanceThe stereo balance on a scale of 0-65535, 32768 is + middle. + + stepThe step by which the volume control jumps. This is + used to help make it easy for applications to set + slider behaviour. + + + +
+ + struct video_audio flags + + + + VIDEO_AUDIO_MUTEThe audio is currently muted. We + could fake this in our driver but we + choose not to bother. + + VIDEO_AUDIO_MUTABLEThe input has a mute option + + VIDEO_AUDIO_TREBLEThe input has a treble control + + VIDEO_AUDIO_BASSThe input has a base control + + + +
+ + struct video_audio modes + + + + VIDEO_SOUND_MONOMono sound + + VIDEO_SOUND_STEREOStereo sound + + VIDEO_SOUND_LANG1Alternative language 1 (TV specific) + + VIDEO_SOUND_LANG2Alternative language 2 (TV specific) + + + +
+ + Having filled in the structure we copy it back to user space. + + + The VIDIOCSAUDIO ioctl allows the user to set the audio parameters in the + video_audio structure. The driver does its best to honour the request. + + + + case VIDIOCSAUDIO: + { + struct video_audio v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.audio) + return -EINVAL; + current_volume = v/16384; + hardware_set_volume(current_volume); + return 0; + } + + + + In our case there is very little that the user can set. The volume is + basically the limit. Note that we could pretend to have a mute feature + by rewriting this to + + + + case VIDIOCSAUDIO: + { + struct video_audio v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.audio) + return -EINVAL; + current_volume = v/16384; + if(v.flags&VIDEO_AUDIO_MUTE) + hardware_set_volume(0); + else + hardware_set_volume(current_volume); + current_muted = v.flags & + VIDEO_AUDIO_MUTE; + return 0; + } + + + + This with the corresponding changes to the VIDIOCGAUDIO code to report the + state of the mute flag we save and to report the card has a mute function, + will allow applications to use a mute facility with this card. It is + questionable whether this is a good idea however. User applications can already + fake this themselves and kernel space is precious. + + + We now have a working radio ioctl handler. So we just wrap up the function + + + + + } + return -ENOIOCTLCMD; +} + + + + and pass the Video4Linux layer back an error so that it knows we did not + understand the request we got passed. + +
+ + Module Wrapper + + Finally we add in the usual module wrapping and the driver is done. + + + +#ifndef MODULE + +static int io = 0x300; + +#else + +static int io = -1; + +#endif + +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("A driver for an imaginary radio card."); +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address of the card."); + +static int __init init(void) +{ + if(io==-1) + { + printk(KERN_ERR + "You must set an I/O address with io=0x???\n"); + return -EINVAL; + } + return myradio_init(NULL); +} + +static void __exit cleanup(void) +{ + video_unregister_device(&my_radio); + release_region(io, MY_IO_SIZE); +} + +module_init(init); +module_exit(cleanup); + + + + In this example we set the IO base by default if the driver is compiled into + the kernel: you can still set it using "my_radio.irq" if this file is called my_radio.c. For the module we require the + user sets the parameter. We set io to a nonsense port (-1) so that we can + tell if the user supplied an io parameter or not. + + + We use MODULE_ defines to give an author for the card driver and a + description. We also use them to declare that io is an integer and it is the + address of the card, and can be read by anyone from sysfs. + + + The clean-up routine unregisters the video_device we registered, and frees + up the I/O space. Note that the unregister takes the actual video_device + structure as its argument. Unlike the file operations structure which can be + shared by all instances of a device a video_device structure as an actual + instance of the device. If you are registering multiple radio devices you + need to fill in one structure per device (most likely by setting up a + template and copying it to each of the actual device structures). + + +
+ + Video Capture Devices + + Video Capture Device Types + + The video capture devices share the same interfaces as radio devices. In + order to explain the video capture interface I will use the example of a + camera that has no tuners or audio input. This keeps the example relatively + clean. To get both combine the two driver examples. + + + Video capture devices divide into four categories. A little technology + backgrounder. Full motion video even at television resolution (which is + actually fairly low) is pretty resource-intensive. You are continually + passing megabytes of data every second from the capture card to the display. + several alternative approaches have emerged because copying this through the + processor and the user program is a particularly bad idea . + + + The first is to add the television image onto the video output directly. + This is also how some 3D cards work. These basic cards can generally drop the + video into any chosen rectangle of the display. Cards like this, which + include most mpeg1 cards that used the feature connector, aren't very + friendly in a windowing environment. They don't understand windows or + clipping. The video window is always on the top of the display. + + + Chroma keying is a technique used by cards to get around this. It is an old + television mixing trick where you mark all the areas you wish to replace + with a single clear colour that isn't used in the image - TV people use an + incredibly bright blue while computing people often use a particularly + virulent purple. Bright blue occurs on the desktop. Anyone with virulent + purple windows has another problem besides their TV overlay. + + + The third approach is to copy the data from the capture card to the video + card, but to do it directly across the PCI bus. This relieves the processor + from doing the work but does require some smartness on the part of the video + capture chip, as well as a suitable video card. Programming this kind of + card and more so debugging it can be extremely tricky. There are some quite + complicated interactions with the display and you may also have to cope with + various chipset bugs that show up when PCI cards start talking to each + other. + + + To keep our example fairly simple we will assume a card that supports + overlaying a flat rectangular image onto the frame buffer output, and which + can also capture stuff into processor memory. + + + + Registering Video Capture Devices + + This time we need to add more functions for our camera device. + + +static struct video_device my_camera +{ + "My Camera", + VID_TYPE_OVERLAY|VID_TYPE_SCALES|\ + VID_TYPE_CAPTURE|VID_TYPE_CHROMAKEY, + camera_open. + camera_close, + camera_read, /* no read */ + NULL, /* no write */ + camera_poll, /* no poll */ + camera_ioctl, + NULL, /* no special init function */ + NULL /* no private data */ +}; + + + We need a read() function which is used for capturing data from + the card, and we need a poll function so that a driver can wait for the next + frame to be captured. + + + We use the extra video capability flags that did not apply to the + radio interface. The video related flags are + + Capture Capabilities + + + +VID_TYPE_CAPTUREWe support image capture + +VID_TYPE_TELETEXTA teletext capture device (vbi{n]) + +VID_TYPE_OVERLAYThe image can be directly overlaid onto the + frame buffer + +VID_TYPE_CHROMAKEYChromakey can be used to select which parts + of the image to display + +VID_TYPE_CLIPPINGIt is possible to give the board a list of + rectangles to draw around. + +VID_TYPE_FRAMERAMThe video capture goes into the video memory + and actually changes it. Applications need + to know this so they can clean up after the + card + +VID_TYPE_SCALESThe image can be scaled to various sizes, + rather than being a single fixed size. + +VID_TYPE_MONOCHROMEThe capture will be monochrome. This isn't a + complete answer to the question since a mono + camera on a colour capture card will still + produce mono output. + +VID_TYPE_SUBCAPTUREThe card allows only part of its field of + view to be captured. This enables + applications to avoid copying all of a large + image into memory when only some section is + relevant. + + + +
+ + We set VID_TYPE_CAPTURE so that we are seen as a capture card, + VID_TYPE_CHROMAKEY so the application knows it is time to draw in virulent + purple, and VID_TYPE_SCALES because we can be resized. + + + Our setup is fairly similar. This time we also want an interrupt line + for the 'frame captured' signal. Not all cards have this so some of them + cannot handle poll(). + + + + +static int io = 0x320; +static int irq = 11; + +int __init mycamera_init(struct video_init *v) +{ + if(!request_region(io, MY_IO_SIZE, "mycamera")) + { + printk(KERN_ERR + "mycamera: port 0x%03X is in use.\n", io); + return -EBUSY; + } + + if(video_device_register(&my_camera, + VFL_TYPE_GRABBER)==-1) { + release_region(io, MY_IO_SIZE); + return -EINVAL; + } + return 0; +} + + + + This is little changed from the needs of the radio card. We specify + VFL_TYPE_GRABBER this time as we want to be allocated a /dev/video name. + +
+ + Opening And Closing The Capture Device + + + +static int users = 0; + +static int camera_open(struct video_device *dev, int flags) +{ + if(users) + return -EBUSY; + if(request_irq(irq, camera_irq, 0, "camera", dev)<0) + return -EBUSY; + users++; + return 0; +} + + +static int camera_close(struct video_device *dev) +{ + users--; + free_irq(irq, dev); +} + + + The open and close routines are also quite similar. The only real change is + that we now request an interrupt for the camera device interrupt line. If we + cannot get the interrupt we report EBUSY to the application and give up. + + + + Interrupt Handling + + Our example handler is for an ISA bus device. If it was PCI you would be + able to share the interrupt and would have set IRQF_SHARED to indicate a + shared IRQ. We pass the device pointer as the interrupt routine argument. We + don't need to since we only support one card but doing this will make it + easier to upgrade the driver for multiple devices in the future. + + + Our interrupt routine needs to do little if we assume the card can simply + queue one frame to be read after it captures it. + + + + +static struct wait_queue *capture_wait; +static int capture_ready = 0; + +static void camera_irq(int irq, void *dev_id, + struct pt_regs *regs) +{ + capture_ready=1; + wake_up_interruptible(&capture_wait); +} + + + The interrupt handler is nice and simple for this card as we are assuming + the card is buffering the frame for us. This means we have little to do but + wake up anybody interested. We also set a capture_ready flag, as we may + capture a frame before an application needs it. In this case we need to know + that a frame is ready. If we had to collect the frame on the interrupt life + would be more complex. + + + The two new routines we need to supply are camera_read which returns a + frame, and camera_poll which waits for a frame to become ready. + + + + +static int camera_poll(struct video_device *dev, + struct file *file, struct poll_table *wait) +{ + poll_wait(file, &capture_wait, wait); + if(capture_read) + return POLLIN|POLLRDNORM; + return 0; +} + + + + Our wait queue for polling is the capture_wait queue. This will cause the + task to be woken up by our camera_irq routine. We check capture_read to see + if there is an image present and if so report that it is readable. + + + + Reading The Video Image + + + +static long camera_read(struct video_device *dev, char *buf, + unsigned long count) +{ + struct wait_queue wait = { current, NULL }; + u8 *ptr; + int len; + int i; + + add_wait_queue(&capture_wait, &wait); + + while(!capture_ready) + { + if(file->flags&O_NDELAY) + { + remove_wait_queue(&capture_wait, &wait); + current->state = TASK_RUNNING; + return -EWOULDBLOCK; + } + if(signal_pending(current)) + { + remove_wait_queue(&capture_wait, &wait); + current->state = TASK_RUNNING; + return -ERESTARTSYS; + } + schedule(); + current->state = TASK_INTERRUPTIBLE; + } + remove_wait_queue(&capture_wait, &wait); + current->state = TASK_RUNNING; + + + + The first thing we have to do is to ensure that the application waits until + the next frame is ready. The code here is almost identical to the mouse code + we used earlier in this chapter. It is one of the common building blocks of + Linux device driver code and probably one which you will find occurs in any + drivers you write. + + + We wait for a frame to be ready, or for a signal to interrupt our waiting. If a + signal occurs we need to return from the system call so that the signal can + be sent to the application itself. We also check to see if the user actually + wanted to avoid waiting - ie if they are using non-blocking I/O and have other things + to get on with. + + + Next we copy the data from the card to the user application. This is rarely + as easy as our example makes out. We will add capture_w, and capture_h here + to hold the width and height of the captured image. We assume the card only + supports 24bit RGB for now. + + + + + + capture_ready = 0; + + ptr=(u8 *)buf; + len = capture_w * 3 * capture_h; /* 24bit RGB */ + + if(len>count) + len=count; /* Doesn't all fit */ + + for(i=0; i<len; i++) + { + put_user(inb(io+IMAGE_DATA), ptr); + ptr++; + } + + hardware_restart_capture(); + + return i; +} + + + + For a real hardware device you would try to avoid the loop with put_user(). + Each call to put_user() has a time overhead checking whether the accesses to user + space are allowed. It would be better to read a line into a temporary buffer + then copy this to user space in one go. + + + Having captured the image and put it into user space we can kick the card to + get the next frame acquired. + + + + Video Ioctl Handling + + As with the radio driver the major control interface is via the ioctl() + function. Video capture devices support the same tuner calls as a radio + device and also support additional calls to control how the video functions + are handled. In this simple example the card has no tuners to avoid making + the code complex. + + + + + +static int camera_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + switch(cmd) + { + case VIDIOCGCAP: + { + struct video_capability v; + v.type = VID_TYPE_CAPTURE|\ + VID_TYPE_CHROMAKEY|\ + VID_TYPE_SCALES|\ + VID_TYPE_OVERLAY; + v.channels = 1; + v.audios = 0; + v.maxwidth = 640; + v.minwidth = 16; + v.maxheight = 480; + v.minheight = 16; + strcpy(v.name, "My Camera"); + if(copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + + + + + The first ioctl we must support and which all video capture and radio + devices are required to support is VIDIOCGCAP. This behaves exactly the same + as with a radio device. This time, however, we report the extra capabilities + we outlined earlier on when defining our video_dev structure. + + + We now set the video flags saying that we support overlay, capture, + scaling and chromakey. We also report size limits - our smallest image is + 16x16 pixels, our largest is 640x480. + + + To keep things simple we report no audio and no tuning capabilities at all. + + + + case VIDIOCGCHAN: + { + struct video_channel v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.channel != 0) + return -EINVAL; + v.flags = 0; + v.tuners = 0; + v.type = VIDEO_TYPE_CAMERA; + v.norm = VIDEO_MODE_AUTO; + strcpy(v.name, "Camera Input");break; + if(copy_to_user(&v, arg, sizeof(v))) + return -EFAULT; + return 0; + } + + + + + This follows what is very much the standard way an ioctl handler looks + in Linux. We copy the data into a kernel space variable and we check that the + request is valid (in this case that the input is 0). Finally we copy the + camera info back to the user. + + + The VIDIOCGCHAN ioctl allows a user to ask about video channels (that is + inputs to the video card). Our example card has a single camera input. The + fields in the structure are + + struct video_channel fields + + + + + channelThe channel number we are selecting + + nameThe name for this channel. This is intended + to describe the port to the user. + Appropriate names are therefore things like + "Camera" "SCART input" + + flagsChannel properties + + typeInput type + + normThe current television encoding being used + if relevant for this channel. + + + + +
+ struct video_channel flags + + + + VIDEO_VC_TUNERChannel has a tuner. + + VIDEO_VC_AUDIOChannel has audio. + + + +
+ struct video_channel types + + + + VIDEO_TYPE_TVTelevision input. + + VIDEO_TYPE_CAMERAFixed camera input. + + 0Type is unknown. + + + +
+ struct video_channel norms + + + + VIDEO_MODE_PALPAL encoded Television + + VIDEO_MODE_NTSCNTSC (US) encoded Television + + VIDEO_MODE_SECAMSECAM (French) Television + + VIDEO_MODE_AUTOAutomatic switching, or format does not + matter + + + +
+ + The corresponding VIDIOCSCHAN ioctl allows a user to change channel and to + request the norm is changed - for example to switch between a PAL or an NTSC + format camera. + + + + + case VIDIOCSCHAN: + { + struct video_channel v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.channel != 0) + return -EINVAL; + if(v.norm != VIDEO_MODE_AUTO) + return -EINVAL; + return 0; + } + + + + + The implementation of this call in our driver is remarkably easy. Because we + are assuming fixed format hardware we need only check that the user has not + tried to change anything. + + + The user also needs to be able to configure and adjust the picture they are + seeing. This is much like adjusting a television set. A user application + also needs to know the palette being used so that it knows how to display + the image that has been captured. The VIDIOCGPICT and VIDIOCSPICT ioctl + calls provide this information. + + + + + case VIDIOCGPICT + { + struct video_picture v; + v.brightness = hardware_brightness(); + v.hue = hardware_hue(); + v.colour = hardware_saturation(); + v.contrast = hardware_brightness(); + /* Not settable */ + v.whiteness = 32768; + v.depth = 24; /* 24bit */ + v.palette = VIDEO_PALETTE_RGB24; + if(copy_to_user(&v, arg, + sizeof(v))) + return -EFAULT; + return 0; + } + + + + + The brightness, hue, color, and contrast provide the picture controls that + are akin to a conventional television. Whiteness provides additional + control for greyscale images. All of these values are scaled between 0-65535 + and have 32768 as the mid point setting. The scaling means that applications + do not have to worry about the capability range of the hardware but can let + it make a best effort attempt. + + + Our depth is 24, as this is in bits. We will be returning RGB24 format. This + has one byte of red, then one of green, then one of blue. This then repeats + for every other pixel in the image. The other common formats the interface + defines are + + Framebuffer Encodings + + + + GREYLinear greyscale. This is for simple cameras and the + like + + RGB565The top 5 bits hold 32 red levels, the next six bits + hold green and the low 5 bits hold blue. + + RGB555The top bit is clear. The red green and blue levels + each occupy five bits. + + + +
+ + Additional modes are support for YUV capture formats. These are common for + TV and video conferencing applications. + + + The VIDIOCSPICT ioctl allows a user to set some of the picture parameters. + Exactly which ones are supported depends heavily on the card itself. It is + possible to support many modes and effects in software. In general doing + this in the kernel is a bad idea. Video capture is a performance-sensitive + application and the programs can often do better if they aren't being + 'helped' by an overkeen driver writer. Thus for our device we will report + RGB24 only and refuse to allow a change. + + + + + case VIDIOCSPICT: + { + struct video_picture v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.depth!=24 || + v.palette != VIDEO_PALETTE_RGB24) + return -EINVAL; + set_hardware_brightness(v.brightness); + set_hardware_hue(v.hue); + set_hardware_saturation(v.colour); + set_hardware_brightness(v.contrast); + return 0; + } + + + + + We check the user has not tried to change the palette or the depth. We do + not want to carry out some of the changes and then return an error. This may + confuse the application which will be assuming no change occurred. + + + In much the same way as you need to be able to set the picture controls to + get the right capture images, many cards need to know what they are + displaying onto when generating overlay output. In some cases getting this + wrong even makes a nasty mess or may crash the computer. For that reason + the VIDIOCSBUF ioctl used to set up the frame buffer information may well + only be usable by root. + + + We will assume our card is one of the old ISA devices with feature connector + and only supports a couple of standard video modes. Very common for older + cards although the PCI devices are way smarter than this. + + + + +static struct video_buffer capture_fb; + + case VIDIOCGFBUF: + { + if(copy_to_user(arg, &capture_fb, + sizeof(capture_fb))) + return -EFAULT; + return 0; + + } + + + + + We keep the frame buffer information in the format the ioctl uses. This + makes it nice and easy to work with in the ioctl calls. + + + + case VIDIOCSFBUF: + { + struct video_buffer v; + + if(!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.width!=320 && v.width!=640) + return -EINVAL; + if(v.height!=200 && v.height!=240 + && v.height!=400 + && v.height !=480) + return -EINVAL; + memcpy(&capture_fb, &v, sizeof(v)); + hardware_set_fb(&v); + return 0; + } + + + + + + The capable() function checks a user has the required capability. The Linux + operating system has a set of about 30 capabilities indicating privileged + access to services. The default set up gives the superuser (uid 0) all of + them and nobody else has any. + + + We check that the user has the SYS_ADMIN capability, that is they are + allowed to operate as the machine administrator. We don't want anyone but + the administrator making a mess of the display. + + + Next we check for standard PC video modes (320 or 640 wide with either + EGA or VGA depths). If the mode is not a standard video mode we reject it as + not supported by our card. If the mode is acceptable we save it so that + VIDIOCFBUF will give the right answer next time it is called. The + hardware_set_fb() function is some undescribed card specific function to + program the card for the desired mode. + + + Before the driver can display an overlay window it needs to know where the + window should be placed, and also how large it should be. If the card + supports clipping it needs to know which rectangles to omit from the + display. The video_window structure is used to describe the way the image + should be displayed. + + struct video_window fields + + + + widthThe width in pixels of the desired image. The card + may use a smaller size if this size is not available + + heightThe height of the image. The card may use a smaller + size if this size is not available. + + x The X position of the top left of the window. This + is in pixels relative to the left hand edge of the + picture. Not all cards can display images aligned on + any pixel boundary. If the position is unsuitable + the card adjusts the image right and reduces the + width. + + y The Y position of the top left of the window. This + is counted in pixels relative to the top edge of the + picture. As with the width if the card cannot + display starting on this line it will adjust the + values. + + chromakeyThe colour (expressed in RGB32 format) for the + chromakey colour if chroma keying is being used. + + clipsAn array of rectangles that must not be drawn + over. + + clipcountThe number of clips in this array. + + + +
+ + Each clip is a struct video_clip which has the following fields + + video_clip fields + + + + x, yCo-ordinates relative to the display + + width, heightWidth and height in pixels + + nextA spare field for the application to use + + + +
+ + The driver is required to ensure it always draws in the area requested or a smaller area, and that it never draws in any of the areas that are clipped. + This may well mean it has to leave alone. small areas the application wished to be + drawn. + + + Our example card uses chromakey so does not have to address most of the + clipping. We will add a video_window structure to our global variables to + remember our parameters, as we did with the frame buffer. + + + + + case VIDIOCGWIN: + { + if(copy_to_user(arg, &capture_win, + sizeof(capture_win))) + return -EFAULT; + return 0; + } + + + case VIDIOCSWIN: + { + struct video_window v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.width > 640 || v.height > 480) + return -EINVAL; + if(v.width < 16 || v.height < 16) + return -EINVAL; + hardware_set_key(v.chromakey); + hardware_set_window(v); + memcpy(&capture_win, &v, sizeof(v)); + capture_w = v.width; + capture_h = v.height; + return 0; + } + + + + + Because we are using Chromakey our setup is fairly simple. Mostly we have to + check the values are sane and load them into the capture card. + + + With all the setup done we can now turn on the actual capture/overlay. This + is done with the VIDIOCCAPTURE ioctl. This takes a single integer argument + where 0 is on and 1 is off. + + + + + case VIDIOCCAPTURE: + { + int v; + if(get_user(v, (int *)arg)) + return -EFAULT; + if(v==0) + hardware_capture_off(); + else + { + if(capture_fb.width == 0 + || capture_w == 0) + return -EINVAL; + hardware_capture_on(); + } + return 0; + } + + + + + We grab the flag from user space and either enable or disable according to + its value. There is one small corner case we have to consider here. Suppose + that the capture was requested before the video window or the frame buffer + had been set up. In those cases there will be unconfigured fields in our + card data, as well as unconfigured hardware settings. We check for this case and + return an error if the frame buffer or the capture window width is zero. + + + + + default: + return -ENOIOCTLCMD; + } +} + + + + We don't need to support any other ioctls, so if we get this far, it is time + to tell the video layer that we don't now what the user is talking about. + +
+ + Other Functionality + + The Video4Linux layer supports additional features, including a high + performance mmap() based capture mode and capturing part of the image. + These features are out of the scope of the book. You should however have enough + example code to implement most simple video4linux devices for radio and TV + cards. + + +
+ + Known Bugs And Assumptions + + + Multiple Opens + + + The driver assumes multiple opens should not be allowed. A driver + can work around this but not cleanly. + + + + API Deficiencies + + + The existing API poorly reflects compression capable devices. There + are plans afoot to merge V4L, V4L2 and some other ideas into a + better interface. + + + + + + + + + Public Functions Provided +!Edrivers/media/video/v4l2-dev.c + + +
diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index 8495fc970391..48a3955f05fc 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -112,7 +112,7 @@ required reading: Other excellent descriptions of how to create patches properly are: "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt "Linux kernel patch submission format" http://linux.yyz.us/patch-format.html @@ -620,7 +620,7 @@ all time. It should describe the patch completely, containing: For more details on what this should all look like, please see the ChangeLog section of the document: "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt diff --git a/trunk/Documentation/SAK.txt b/trunk/Documentation/SAK.txt index 74be14679ed8..b9019ca872ea 100644 --- a/trunk/Documentation/SAK.txt +++ b/trunk/Documentation/SAK.txt @@ -1,5 +1,5 @@ Linux 2.4.2 Secure Attention Key (SAK) handling -18 March 2001, Andrew Morton +18 March 2001, Andrew Morton An operating system's Secure Attention Key is a security tool which is provided as protection against trojan password capturing programs. It diff --git a/trunk/Documentation/SubmitChecklist b/trunk/Documentation/SubmitChecklist index ac5e0b2f1097..21f0795af20f 100644 --- a/trunk/Documentation/SubmitChecklist +++ b/trunk/Documentation/SubmitChecklist @@ -85,6 +85,3 @@ kernel patches. 23: Tested after it has been merged into the -mm patchset to make sure that it still works with all of the other queued patches and various changes in the VM, VFS, and other subsystems. - -24: All memory barriers {e.g., barrier(), rmb(), wmb()} need a comment in the - source code that explains the logic of what they are doing and why. diff --git a/trunk/Documentation/SubmittingDrivers b/trunk/Documentation/SubmittingDrivers index 99e72a81fa2f..24f2eb40cae5 100644 --- a/trunk/Documentation/SubmittingDrivers +++ b/trunk/Documentation/SubmittingDrivers @@ -41,7 +41,7 @@ Linux 2.4: Linux 2.6: The same rules apply as 2.4 except that you should follow linux-kernel to track changes in API's. The final contact point for Linux 2.6 - submissions is Andrew Morton. + submissions is Andrew Morton . What Criteria Determine Acceptance ---------------------------------- diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index f309d3c6221c..f79ad9ff6031 100644 --- a/trunk/Documentation/SubmittingPatches +++ b/trunk/Documentation/SubmittingPatches @@ -77,7 +77,7 @@ Quilt: http://savannah.nongnu.org/projects/quilt Andrew Morton's patch scripts: -http://userweb.kernel.org/~akpm/stuff/patch-scripts.tar.gz +http://www.zip.com.au/~akpm/linux/patches/ Instead of these scripts, quilt is the recommended patch management tool (see above). @@ -405,7 +405,7 @@ person it names. This tag documents that potentially interested parties have been included in the discussion -14) Using Tested-by: and Reviewed-by: +14) Using Test-by: and Reviewed-by: A Tested-by: tag indicates that the patch has been successfully tested (in some environment) by the person named. This tag informs maintainers that @@ -653,7 +653,7 @@ SECTION 3 - REFERENCES ---------------------- Andrew Morton, "The perfect patch" (tpp). - + Jeff Garzik, "Linux kernel patch submission format". @@ -672,9 +672,4 @@ Kernel Documentation/CodingStyle: Linus Torvalds's mail on the canonical patch format: - -Andi Kleen, "On submitting kernel patches" - Some strategies to get difficult or controversal changes in. - http://halobates.de/on-submitting-patches.pdf - -- diff --git a/trunk/Documentation/blackfin/kgdb.txt b/trunk/Documentation/blackfin/kgdb.txt new file mode 100644 index 000000000000..84f6a484ae9a --- /dev/null +++ b/trunk/Documentation/blackfin/kgdb.txt @@ -0,0 +1,155 @@ + A Simple Guide to Configure KGDB + + Sonic Zhang + Aug. 24th 2006 + + +This KGDB patch enables the kernel developer to do source level debugging on +the kernel for the Blackfin architecture. The debugging works over either the +ethernet interface or one of the uarts. Both software breakpoints and +hardware breakpoints are supported in this version. +http://docs.blackfin.uclinux.org/doku.php?id=kgdb + + +2 known issues: +1. This bug: + http://blackfin.uclinux.org/tracker/index.php?func=detail&aid=544&group_id=18&atid=145 + The GDB client for Blackfin uClinux causes incorrect values of local + variables to be displayed when the user breaks the running of kernel in GDB. +2. Because of a hardware bug in Blackfin 533 v1.0.3: + 05000067 - Watchpoints (Hardware Breakpoints) are not supported + Hardware breakpoints cannot be set properly. + + +Debug over Ethernet: + +1. Compile and install the cross platform version of gdb for blackfin, which + can be found at $(BINROOT)/bfin-elf-gdb. + +2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under + "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb". + With this selected, option "Full Symbolic/Source Debugging support" and + "Compile the kernel with frame pointers" are also selected. + +3. Select option "KGDB: connect over (Ethernet)". Add "kgdboe=@target-IP/,@host-IP/" to + the option "Compiled-in Kernel Boot Parameter" under "Kernel hacking". + +4. Connect minicom to the serial port and boot the kernel image. + +5. Configure the IP "/> ifconfig eth0 target-IP" + +6. Start GDB client "bfin-elf-gdb vmlinux". + +7. Connect to the target "(gdb) target remote udp:target-IP:6443". + +8. Set software breakpoint "(gdb) break sys_open". + +9. Continue "(gdb) c". + +10. Run ls in the target console "/> ls". + +11. Breakpoint hits. "Breakpoint 1: sys_open(..." + +12. Display local variables and function paramters. + (*) This operation gives wrong results, see known issue 1. + +13. Single stepping "(gdb) si". + +14. Remove breakpoint 1. "(gdb) del 1" + +15. Set hardware breakpoint "(gdb) hbreak sys_open". + +16. Continue "(gdb) c". + +17. Run ls in the target console "/> ls". + +18. Hardware breakpoint hits. "Breakpoint 1: sys_open(...". + (*) This hardware breakpoint will not be hit, see known issue 2. + +19. Continue "(gdb) c". + +20. Interrupt the target in GDB "Ctrl+C". + +21. Detach from the target "(gdb) detach". + +22. Exit GDB "(gdb) quit". + + +Debug over the UART: + +1. Compile and install the cross platform version of gdb for blackfin, which + can be found at $(BINROOT)/bfin-elf-gdb. + +2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under + "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb". + With this selected, option "Full Symbolic/Source Debugging support" and + "Compile the kernel with frame pointers" are also selected. + +3. Select option "KGDB: connect over (UART)". Set "KGDB: UART port number" to be + a different one from the console. Don't forget to change the mode of + blackfin serial driver to PIO. Otherwise kgdb works incorrectly on UART. + +4. If you want connect to kgdb when the kernel boots, enable + "KGDB: Wait for gdb connection early" + +5. Compile kernel. + +6. Connect minicom to the serial port of the console and boot the kernel image. + +7. Start GDB client "bfin-elf-gdb vmlinux". + +8. Set the baud rate in GDB "(gdb) set remotebaud 57600". + +9. Connect to the target on the second serial port "(gdb) target remote /dev/ttyS1". + +10. Set software breakpoint "(gdb) break sys_open". + +11. Continue "(gdb) c". + +12. Run ls in the target console "/> ls". + +13. A breakpoint is hit. "Breakpoint 1: sys_open(..." + +14. All other operations are the same as that in KGDB over Ethernet. + + +Debug over the same UART as console: + +1. Compile and install the cross platform version of gdb for blackfin, which + can be found at $(BINROOT)/bfin-elf-gdb. + +2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under + "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb". + With this selected, option "Full Symbolic/Source Debugging support" and + "Compile the kernel with frame pointers" are also selected. + +3. Select option "KGDB: connect over UART". Set "KGDB: UART port number" to console. + Don't forget to change the mode of blackfin serial driver to PIO. + Otherwise kgdb works incorrectly on UART. + +4. If you want connect to kgdb when the kernel boots, enable + "KGDB: Wait for gdb connection early" + +5. Connect minicom to the serial port and boot the kernel image. + +6. (Optional) Ask target to wait for gdb connection by entering Ctrl+A. In minicom, you should enter Ctrl+A+A. + +7. Start GDB client "bfin-elf-gdb vmlinux". + +8. Set the baud rate in GDB "(gdb) set remotebaud 57600". + +9. Connect to the target "(gdb) target remote /dev/ttyS0". + +10. Set software breakpoint "(gdb) break sys_open". + +11. Continue "(gdb) c". Then enter Ctrl+C twice to stop GDB connection. + +12. Run ls in the target console "/> ls". Dummy string can be seen on the console. + +13. Then connect the gdb to target again. "(gdb) target remote /dev/ttyS0". + Now you will find a breakpoint is hit. "Breakpoint 1: sys_open(..." + +14. All other operations are the same as that in KGDB over Ethernet. The only + difference is that after continue command in GDB, please stop GDB + connection by 2 "Ctrl+C"s and connect again after breakpoints are hit or + Ctrl+A is entered. diff --git a/trunk/Documentation/block/data-integrity.txt b/trunk/Documentation/block/data-integrity.txt index e8ca040ba2cf..e9dc8d86adc7 100644 --- a/trunk/Documentation/block/data-integrity.txt +++ b/trunk/Documentation/block/data-integrity.txt @@ -246,7 +246,7 @@ will require extra work due to the application tag. retrieve the tag buffer using bio_integrity_get_tag(). -5.3 PASSING EXISTING INTEGRITY METADATA +6.3 PASSING EXISTING INTEGRITY METADATA Filesystems that either generate their own integrity metadata or are capable of transferring IMD from user space can use the @@ -283,7 +283,7 @@ will require extra work due to the application tag. integrity upon completion. -5.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY +6.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY METADATA To enable integrity exchange on a block device the gendisk must be diff --git a/trunk/Documentation/cris/README b/trunk/Documentation/cris/README index d9b086869a60..795a1dabe6c7 100644 --- a/trunk/Documentation/cris/README +++ b/trunk/Documentation/cris/README @@ -27,7 +27,7 @@ operating system. The ETRAX 100LX chip -------------------- -For reference, please see the press-release: +For reference, plase see the press-release: http://www.axis.com/news/us/001101_etrax.htm diff --git a/trunk/Documentation/development-process/1.Intro b/trunk/Documentation/development-process/1.Intro deleted file mode 100644 index 8cc2cba2b10d..000000000000 --- a/trunk/Documentation/development-process/1.Intro +++ /dev/null @@ -1,274 +0,0 @@ -1: A GUIDE TO THE KERNEL DEVELOPMENT PROCESS - -The purpose of this document is to help developers (and their managers) -work with the development community with a minimum of frustration. It is -an attempt to document how this community works in a way which is -accessible to those who are not intimately familiar with Linux kernel -development (or, indeed, free software development in general). While -there is some technical material here, this is very much a process-oriented -discussion which does not require a deep knowledge of kernel programming to -understand. - - -1.1: EXECUTIVE SUMMARY - -The rest of this section covers the scope of the kernel development process -and the kinds of frustrations that developers and their employers can -encounter there. There are a great many reasons why kernel code should be -merged into the official ("mainline") kernel, including automatic -availability to users, community support in many forms, and the ability to -influence the direction of kernel development. Code contributed to the -Linux kernel must be made available under a GPL-compatible license. - -Section 2 introduces the development process, the kernel release cycle, and -the mechanics of the merge window. The various phases in the patch -development, review, and merging cycle are covered. There is some -discussion of tools and mailing lists. Developers wanting to get started -with kernel development are encouraged to track down and fix bugs as an -initial exercise. - -Section 3 covers early-stage project planning, with an emphasis on -involving the development community as soon as possible. - -Section 4 is about the coding process; several pitfalls which have been -encountered by other developers are discussed. Some requirements for -patches are covered, and there is an introduction to some of the tools -which can help to ensure that kernel patches are correct. - -Section 5 talks about the process of posting patches for review. To be -taken seriously by the development community, patches must be properly -formatted and described, and they must be sent to the right place. -Following the advice in this section should help to ensure the best -possible reception for your work. - -Section 6 covers what happens after posting patches; the job is far from -done at that point. Working with reviewers is a crucial part of the -development process; this section offers a number of tips on how to avoid -problems at this important stage. Developers are cautioned against -assuming that the job is done when a patch is merged into the mainline. - -Section 7 introduces a couple of "advanced" topics: managing patches with -git and reviewing patches posted by others. - -Section 8 concludes the document with pointers to sources for more -information on kernel development. - - -1.2: WHAT THIS DOCUMENT IS ABOUT - -The Linux kernel, at over 6 million lines of code and well over 1000 active -contributors, is one of the largest and most active free software projects -in existence. Since its humble beginning in 1991, this kernel has evolved -into a best-of-breed operating system component which runs on pocket-sized -digital music players, desktop PCs, the largest supercomputers in -existence, and all types of systems in between. It is a robust, efficient, -and scalable solution for almost any situation. - -With the growth of Linux has come an increase in the number of developers -(and companies) wishing to participate in its development. Hardware -vendors want to ensure that Linux supports their products well, making -those products attractive to Linux users. Embedded systems vendors, who -use Linux as a component in an integrated product, want Linux to be as -capable and well-suited to the task at hand as possible. Distributors and -other software vendors who base their products on Linux have a clear -interest in the capabilities, performance, and reliability of the Linux -kernel. And end users, too, will often wish to change Linux to make it -better suit their needs. - -One of the most compelling features of Linux is that it is accessible to -these developers; anybody with the requisite skills can improve Linux and -influence the direction of its development. Proprietary products cannot -offer this kind of openness, which is a characteristic of the free software -process. But, if anything, the kernel is even more open than most other -free software projects. A typical three-month kernel development cycle can -involve over 1000 developers working for more than 100 different companies -(or for no company at all). - -Working with the kernel development community is not especially hard. But, -that notwithstanding, many potential contributors have experienced -difficulties when trying to do kernel work. The kernel community has -evolved its own distinct ways of operating which allow it to function -smoothly (and produce a high-quality product) in an environment where -thousands of lines of code are being changed every day. So it is not -surprising that Linux kernel development process differs greatly from -proprietary development methods. - -The kernel's development process may come across as strange and -intimidating to new developers, but there are good reasons and solid -experience behind it. A developer who does not understand the kernel -community's ways (or, worse, who tries to flout or circumvent them) will -have a frustrating experience in store. The development community, while -being helpful to those who are trying to learn, has little time for those -who will not listen or who do not care about the development process. - -It is hoped that those who read this document will be able to avoid that -frustrating experience. There is a lot of material here, but the effort -involved in reading it will be repaid in short order. The development -community is always in need of developers who will help to make the kernel -better; the following text should help you - or those who work for you - -join our community. - - -1.3: CREDITS - -This document was written by Jonathan Corbet, corbet@lwn.net. It has been -improved by comments from Johannes Berg, James Berry, Alex Chiang, Roland -Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh, -Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata, and -Jochen Voß. - -This work was supported by the Linux Foundation; thanks especially to -Amanda McPherson, who saw the value of this effort and made it all happen. - - -1.4: THE IMPORTANCE OF GETTING CODE INTO THE MAINLINE - -Some companies and developers occasionally wonder why they should bother -learning how to work with the kernel community and get their code into the -mainline kernel (the "mainline" being the kernel maintained by Linus -Torvalds and used as a base by Linux distributors). In the short term, -contributing code can look like an avoidable expense; it seems easier to -just keep the code separate and support users directly. The truth of the -matter is that keeping code separate ("out of tree") is a false economy. - -As a way of illustrating the costs of out-of-tree code, here are a few -relevant aspects of the kernel development process; most of these will be -discussed in greater detail later in this document. Consider: - -- Code which has been merged into the mainline kernel is available to all - Linux users. It will automatically be present on all distributions which - enable it. There is no need for driver disks, downloads, or the hassles - of supporting multiple versions of multiple distributions; it all just - works, for the developer and for the user. Incorporation into the - mainline solves a large number of distribution and support problems. - -- While kernel developers strive to maintain a stable interface to user - space, the internal kernel API is in constant flux. The lack of a stable - internal interface is a deliberate design decision; it allows fundamental - improvements to be made at any time and results in higher-quality code. - But one result of that policy is that any out-of-tree code requires - constant upkeep if it is to work with new kernels. Maintaining - out-of-tree code requires significant amounts of work just to keep that - code working. - - Code which is in the mainline, instead, does not require this work as the - result of a simple rule requiring any developer who makes an API change - to also fix any code that breaks as the result of that change. So code - which has been merged into the mainline has significantly lower - maintenance costs. - -- Beyond that, code which is in the kernel will often be improved by other - developers. Surprising results can come from empowering your user - community and customers to improve your product. - -- Kernel code is subjected to review, both before and after merging into - the mainline. No matter how strong the original developer's skills are, - this review process invariably finds ways in which the code can be - improved. Often review finds severe bugs and security problems. This is - especially true for code which has been developed in a closed - environment; such code benefits strongly from review by outside - developers. Out-of-tree code is lower-quality code. - -- Participation in the development process is your way to influence the - direction of kernel development. Users who complain from the sidelines - are heard, but active developers have a stronger voice - and the ability - to implement changes which make the kernel work better for their needs. - -- When code is maintained separately, the possibility that a third party - will contribute a different implementation of a similar feature always - exists. Should that happen, getting your code merged will become much - harder - to the point of impossibility. Then you will be faced with the - unpleasant alternatives of either (1) maintaining a nonstandard feature - out of tree indefinitely, or (2) abandoning your code and migrating your - users over to the in-tree version. - -- Contribution of code is the fundamental action which makes the whole - process work. By contributing your code you can add new functionality to - the kernel and provide capabilities and examples which are of use to - other kernel developers. If you have developed code for Linux (or are - thinking about doing so), you clearly have an interest in the continued - success of this platform; contributing code is one of the best ways to - help ensure that success. - -All of the reasoning above applies to any out-of-tree kernel code, -including code which is distributed in proprietary, binary-only form. -There are, however, additional factors which should be taken into account -before considering any sort of binary-only kernel code distribution. These -include: - -- The legal issues around the distribution of proprietary kernel modules - are cloudy at best; quite a few kernel copyright holders believe that - most binary-only modules are derived products of the kernel and that, as - a result, their distribution is a violation of the GNU General Public - license (about which more will be said below). Your author is not a - lawyer, and nothing in this document can possibly be considered to be - legal advice. The true legal status of closed-source modules can only be - determined by the courts. But the uncertainty which haunts those modules - is there regardless. - -- Binary modules greatly increase the difficulty of debugging kernel - problems, to the point that most kernel developers will not even try. So - the distribution of binary-only modules will make it harder for your - users to get support from the community. - -- Support is also harder for distributors of binary-only modules, who must - provide a version of the module for every distribution and every kernel - version they wish to support. Dozens of builds of a single module can - be required to provide reasonably comprehensive coverage, and your users - will have to upgrade your module separately every time they upgrade their - kernel. - -- Everything that was said above about code review applies doubly to - closed-source code. Since this code is not available at all, it cannot - have been reviewed by the community and will, beyond doubt, have serious - problems. - -Makers of embedded systems, in particular, may be tempted to disregard much -of what has been said in this section in the belief that they are shipping -a self-contained product which uses a frozen kernel version and requires no -more development after its release. This argument misses the value of -widespread code review and the value of allowing your users to add -capabilities to your product. But these products, too, have a limited -commercial life, after which a new version must be released. At that -point, vendors whose code is in the mainline and well maintained will be -much better positioned to get the new product ready for market quickly. - - -1.5: LICENSING - -Code is contributed to the Linux kernel under a number of licenses, but all -code must be compatible with version 2 of the GNU General Public License -(GPLv2), which is the license covering the kernel distribution as a whole. -In practice, that means that all code contributions are covered either by -GPLv2 (with, optionally, language allowing distribution under later -versions of the GPL) or the three-clause BSD license. Any contributions -which are not covered by a compatible license will not be accepted into the -kernel. - -Copyright assignments are not required (or requested) for code contributed -to the kernel. All code merged into the mainline kernel retains its -original ownership; as a result, the kernel now has thousands of owners. - -One implication of this ownership structure is that any attempt to change -the licensing of the kernel is doomed to almost certain failure. There are -few practical scenarios where the agreement of all copyright holders could -be obtained (or their code removed from the kernel). So, in particular, -there is no prospect of a migration to version 3 of the GPL in the -foreseeable future. - -It is imperative that all code contributed to the kernel be legitimately -free software. For that reason, code from anonymous (or pseudonymous) -contributors will not be accepted. All contributors are required to "sign -off" on their code, stating that the code can be distributed with the -kernel under the GPL. Code which has not been licensed as free software by -its owner, or which risks creating copyright-related problems for the -kernel (such as code which derives from reverse-engineering efforts lacking -proper safeguards) cannot be contributed. - -Questions about copyright-related issues are common on Linux development -mailing lists. Such questions will normally receive no shortage of -answers, but one should bear in mind that the people answering those -questions are not lawyers and cannot provide legal advice. If you have -legal questions relating to Linux source code, there is no substitute for -talking with a lawyer who understands this field. Relying on answers -obtained on technical mailing lists is a risky affair. diff --git a/trunk/Documentation/development-process/2.Process b/trunk/Documentation/development-process/2.Process deleted file mode 100644 index d750321acd5a..000000000000 --- a/trunk/Documentation/development-process/2.Process +++ /dev/null @@ -1,459 +0,0 @@ -2: HOW THE DEVELOPMENT PROCESS WORKS - -Linux kernel development in the early 1990's was a pretty loose affair, -with relatively small numbers of users and developers involved. With a -user base in the millions and with some 2,000 developers involved over the -course of one year, the kernel has since had to evolve a number of -processes to keep development happening smoothly. A solid understanding of -how the process works is required in order to be an effective part of it. - - -2.1: THE BIG PICTURE - -The kernel developers use a loosely time-based release process, with a new -major kernel release happening every two or three months. The recent -release history looks like this: - - 2.6.26 July 13, 2008 - 2.6.25 April 16, 2008 - 2.6.24 January 24, 2008 - 2.6.23 October 9, 2007 - 2.6.22 July 8, 2007 - 2.6.21 April 25, 2007 - 2.6.20 February 4, 2007 - -Every 2.6.x release is a major kernel release with new features, internal -API changes, and more. A typical 2.6 release can contain over 10,000 -changesets with changes to several hundred thousand lines of code. 2.6 is -thus the leading edge of Linux kernel development; the kernel uses a -rolling development model which is continually integrating major changes. - -A relatively straightforward discipline is followed with regard to the -merging of patches for each release. At the beginning of each development -cycle, the "merge window" is said to be open. At that time, code which is -deemed to be sufficiently stable (and which is accepted by the development -community) is merged into the mainline kernel. The bulk of changes for a -new development cycle (and all of the major changes) will be merged during -this time, at a rate approaching 1,000 changes ("patches," or "changesets") -per day. - -(As an aside, it is worth noting that the changes integrated during the -merge window do not come out of thin air; they have been collected, tested, -and staged ahead of time. How that process works will be described in -detail later on). - -The merge window lasts for two weeks. At the end of this time, Linus -Torvalds will declare that the window is closed and release the first of -the "rc" kernels. For the kernel which is destined to be 2.6.26, for -example, the release which happens at the end of the merge window will be -called 2.6.26-rc1. The -rc1 release is the signal that the time to merge -new features has passed, and that the time to stabilize the next kernel has -begun. - -Over the next six to ten weeks, only patches which fix problems should be -submitted to the mainline. On occasion a more significant change will be -allowed, but such occasions are rare; developers who try to merge new -features outside of the merge window tend to get an unfriendly reception. -As a general rule, if you miss the merge window for a given feature, the -best thing to do is to wait for the next development cycle. (An occasional -exception is made for drivers for previously-unsupported hardware; if they -touch no in-tree code, they cannot cause regressions and should be safe to -add at any time). - -As fixes make their way into the mainline, the patch rate will slow over -time. Linus releases new -rc kernels about once a week; a normal series -will get up to somewhere between -rc6 and -rc9 before the kernel is -considered to be sufficiently stable and the final 2.6.x release is made. -At that point the whole process starts over again. - -As an example, here is how the 2.6.25 development cycle went (all dates in -2008): - - January 24 2.6.24 stable release - February 10 2.6.25-rc1, merge window closes - February 15 2.6.25-rc2 - February 24 2.6.25-rc3 - March 4 2.6.25-rc4 - March 9 2.6.25-rc5 - March 16 2.6.25-rc6 - March 25 2.6.25-rc7 - April 1 2.6.25-rc8 - April 11 2.6.25-rc9 - April 16 2.6.25 stable release - -How do the developers decide when to close the development cycle and create -the stable release? The most significant metric used is the list of -regressions from previous releases. No bugs are welcome, but those which -break systems which worked in the past are considered to be especially -serious. For this reason, patches which cause regressions are looked upon -unfavorably and are quite likely to be reverted during the stabilization -period. - -The developers' goal is to fix all known regressions before the stable -release is made. In the real world, this kind of perfection is hard to -achieve; there are just too many variables in a project of this size. -There comes a point where delaying the final release just makes the problem -worse; the pile of changes waiting for the next merge window will grow -larger, creating even more regressions the next time around. So most 2.6.x -kernels go out with a handful of known regressions though, hopefully, none -of them are serious. - -Once a stable release is made, its ongoing maintenance is passed off to the -"stable team," currently comprised of Greg Kroah-Hartman and Chris Wright. -The stable team will release occasional updates to the stable release using -the 2.6.x.y numbering scheme. To be considered for an update release, a -patch must (1) fix a significant bug, and (2) already be merged into the -mainline for the next development kernel. Continuing our 2.6.25 example, -the history (as of this writing) is: - - May 1 2.6.25.1 - May 6 2.6.25.2 - May 9 2.6.25.3 - May 15 2.6.25.4 - June 7 2.6.25.5 - June 9 2.6.25.6 - June 16 2.6.25.7 - June 21 2.6.25.8 - June 24 2.6.25.9 - -Stable updates for a given kernel are made for approximately six months; -after that, the maintenance of stable releases is solely the responsibility -of the distributors which have shipped that particular kernel. - - -2.2: THE LIFECYCLE OF A PATCH - -Patches do not go directly from the developer's keyboard into the mainline -kernel. There is, instead, a somewhat involved (if somewhat informal) -process designed to ensure that each patch is reviewed for quality and that -each patch implements a change which is desirable to have in the mainline. -This process can happen quickly for minor fixes, or, in the case of large -and controversial changes, go on for years. Much developer frustration -comes from a lack of understanding of this process or from attempts to -circumvent it. - -In the hopes of reducing that frustration, this document will describe how -a patch gets into the kernel. What follows below is an introduction which -describes the process in a somewhat idealized way. A much more detailed -treatment will come in later sections. - -The stages that a patch goes through are, generally: - - - Design. This is where the real requirements for the patch - and the way - those requirements will be met - are laid out. Design work is often - done without involving the community, but it is better to do this work - in the open if at all possible; it can save a lot of time redesigning - things later. - - - Early review. Patches are posted to the relevant mailing list, and - developers on that list reply with any comments they may have. This - process should turn up any major problems with a patch if all goes - well. - - - Wider review. When the patch is getting close to ready for mainline - inclusion, it will be accepted by a relevant subsystem maintainer - - though this acceptance is not a guarantee that the patch will make it - all the way to the mainline. The patch will show up in the maintainer's - subsystem tree and into the staging trees (described below). When the - process works, this step leads to more extensive review of the patch and - the discovery of any problems resulting from the integration of this - patch with work being done by others. - - - Merging into the mainline. Eventually, a successful patch will be - merged into the mainline repository managed by Linus Torvalds. More - comments and/or problems may surface at this time; it is important that - the developer be responsive to these and fix any issues which arise. - - - Stable release. The number of users potentially affected by the patch - is now large, so, once again, new problems may arise. - - - Long-term maintenance. While it is certainly possible for a developer - to forget about code after merging it, that sort of behavior tends to - leave a poor impression in the development community. Merging code - eliminates some of the maintenance burden, in that others will fix - problems caused by API changes. But the original developer should - continue to take responsibility for the code if it is to remain useful - in the longer term. - -One of the largest mistakes made by kernel developers (or their employers) -is to try to cut the process down to a single "merging into the mainline" -step. This approach invariably leads to frustration for everybody -involved. - - -2.3: HOW PATCHES GET INTO THE KERNEL - -There is exactly one person who can merge patches into the mainline kernel -repository: Linus Torvalds. But, of the over 12,000 patches which went -into the 2.6.25 kernel, only 250 (around 2%) were directly chosen by Linus -himself. The kernel project has long since grown to a size where no single -developer could possibly inspect and select every patch unassisted. The -way the kernel developers have addressed this growth is through the use of -a lieutenant system built around a chain of trust. - -The kernel code base is logically broken down into a set of subsystems: -networking, specific architecture support, memory management, video -devices, etc. Most subsystems have a designated maintainer, a developer -who has overall responsibility for the code within that subsystem. These -subsystem maintainers are the gatekeepers (in a loose way) for the portion -of the kernel they manage; they are the ones who will (usually) accept a -patch for inclusion into the mainline kernel. - -Subsystem maintainers each manage their own version of the kernel source -tree, usually (but certainly not always) using the git source management -tool. Tools like git (and related tools like quilt or mercurial) allow -maintainers to track a list of patches, including authorship information -and other metadata. At any given time, the maintainer can identify which -patches in his or her repository are not found in the mainline. - -When the merge window opens, top-level maintainers will ask Linus to "pull" -the patches they have selected for merging from their repositories. If -Linus agrees, the stream of patches will flow up into his repository, -becoming part of the mainline kernel. The amount of attention that Linus -pays to specific patches received in a pull operation varies. It is clear -that, sometimes, he looks quite closely. But, as a general rule, Linus -trusts the subsystem maintainers to not send bad patches upstream. - -Subsystem maintainers, in turn, can pull patches from other maintainers. -For example, the networking tree is built from patches which accumulated -first in trees dedicated to network device drivers, wireless networking, -etc. This chain of repositories can be arbitrarily long, though it rarely -exceeds two or three links. Since each maintainer in the chain trusts -those managing lower-level trees, this process is known as the "chain of -trust." - -Clearly, in a system like this, getting patches into the kernel depends on -finding the right maintainer. Sending patches directly to Linus is not -normally the right way to go. - - -2.4: STAGING TREES - -The chain of subsystem trees guides the flow of patches into the kernel, -but it also raises an interesting question: what if somebody wants to look -at all of the patches which are being prepared for the next merge window? -Developers will be interested in what other changes are pending to see -whether there are any conflicts to worry about; a patch which changes a -core kernel function prototype, for example, will conflict with any other -patches which use the older form of that function. Reviewers and testers -want access to the changes in their integrated form before all of those -changes land in the mainline kernel. One could pull changes from all of -the interesting subsystem trees, but that would be a big and error-prone -job. - -The answer comes in the form of staging trees, where subsystem trees are -collected for testing and review. The older of these trees, maintained by -Andrew Morton, is called "-mm" (for memory management, which is how it got -started). The -mm tree integrates patches from a long list of subsystem -trees; it also has some patches aimed at helping with debugging. - -Beyond that, -mm contains a significant collection of patches which have -been selected by Andrew directly. These patches may have been posted on a -mailing list, or they may apply to a part of the kernel for which there is -no designated subsystem tree. As a result, -mm operates as a sort of -subsystem tree of last resort; if there is no other obvious path for a -patch into the mainline, it is likely to end up in -mm. Miscellaneous -patches which accumulate in -mm will eventually either be forwarded on to -an appropriate subsystem tree or be sent directly to Linus. In a typical -development cycle, approximately 10% of the patches going into the mainline -get there via -mm. - -The current -mm patch can always be found from the front page of - - http://kernel.org/ - -Those who want to see the current state of -mm can get the "-mm of the -moment" tree, found at: - - http://userweb.kernel.org/~akpm/mmotm/ - -Use of the MMOTM tree is likely to be a frustrating experience, though; -there is a definite chance that it will not even compile. - -The other staging tree, started more recently, is linux-next, maintained by -Stephen Rothwell. The linux-next tree is, by design, a snapshot of what -the mainline is expected to look like after the next merge window closes. -Linux-next trees are announced on the linux-kernel and linux-next mailing -lists when they are assembled; they can be downloaded from: - - http://www.kernel.org/pub/linux/kernel/people/sfr/linux-next/ - -Some information about linux-next has been gathered at: - - http://linux.f-seidel.de/linux-next/pmwiki/ - -How the linux-next tree will fit into the development process is still -changing. As of this writing, the first full development cycle involving -linux-next (2.6.26) is coming to an end; thus far, it has proved to be a -valuable resource for finding and fixing integration problems before the -beginning of the merge window. See http://lwn.net/Articles/287155/ for -more information on how linux-next has worked to set up the 2.6.27 merge -window. - -Some developers have begun to suggest that linux-next should be used as the -target for future development as well. The linux-next tree does tend to be -far ahead of the mainline and is more representative of the tree into which -any new work will be merged. The downside to this idea is that the -volatility of linux-next tends to make it a difficult development target. -See http://lwn.net/Articles/289013/ for more information on this topic, and -stay tuned; much is still in flux where linux-next is involved. - - -2.5: TOOLS - -As can be seen from the above text, the kernel development process depends -heavily on the ability to herd collections of patches in various -directions. The whole thing would not work anywhere near as well as it -does without suitably powerful tools. Tutorials on how to use these tools -are well beyond the scope of this document, but there is space for a few -pointers. - -By far the dominant source code management system used by the kernel -community is git. Git is one of a number of distributed version control -systems being developed in the free software community. It is well tuned -for kernel development, in that it performs quite well when dealing with -large repositories and large numbers of patches. It also has a reputation -for being difficult to learn and use, though it has gotten better over -time. Some sort of familiarity with git is almost a requirement for kernel -developers; even if they do not use it for their own work, they'll need git -to keep up with what other developers (and the mainline) are doing. - -Git is now packaged by almost all Linux distributions. There is a home -page at - - http://git.or.cz/ - -That page has pointers to documentation and tutorials. One should be -aware, in particular, of the Kernel Hacker's Guide to git, which has -information specific to kernel development: - - http://linux.yyz.us/git-howto.html - -Among the kernel developers who do not use git, the most popular choice is -almost certainly Mercurial: - - http://www.selenic.com/mercurial/ - -Mercurial shares many features with git, but it provides an interface which -many find easier to use. - -The other tool worth knowing about is Quilt: - - http://savannah.nongnu.org/projects/quilt/ - -Quilt is a patch management system, rather than a source code management -system. It does not track history over time; it is, instead, oriented -toward tracking a specific set of changes against an evolving code base. -Some major subsystem maintainers use quilt to manage patches intended to go -upstream. For the management of certain kinds of trees (-mm, for example), -quilt is the best tool for the job. - - -2.6: MAILING LISTS - -A great deal of Linux kernel development work is done by way of mailing -lists. It is hard to be a fully-functioning member of the community -without joining at least one list somewhere. But Linux mailing lists also -represent a potential hazard to developers, who risk getting buried under a -load of electronic mail, running afoul of the conventions used on the Linux -lists, or both. - -Most kernel mailing lists are run on vger.kernel.org; the master list can -be found at: - - http://vger.kernel.org/vger-lists.html - -There are lists hosted elsewhere, though; a number of them are at -lists.redhat.com. - -The core mailing list for kernel development is, of course, linux-kernel. -This list is an intimidating place to be; volume can reach 500 messages per -day, the amount of noise is high, the conversation can be severely -technical, and participants are not always concerned with showing a high -degree of politeness. But there is no other place where the kernel -development community comes together as a whole; developers who avoid this -list will miss important information. - -There are a few hints which can help with linux-kernel survival: - -- Have the list delivered to a separate folder, rather than your main - mailbox. One must be able to ignore the stream for sustained periods of - time. - -- Do not try to follow every conversation - nobody else does. It is - important to filter on both the topic of interest (though note that - long-running conversations can drift away from the original subject - without changing the email subject line) and the people who are - participating. - -- Do not feed the trolls. If somebody is trying to stir up an angry - response, ignore them. - -- When responding to linux-kernel email (or that on other lists) preserve - the Cc: header for all involved. In the absence of a strong reason (such - as an explicit request), you should never remove recipients. Always make - sure that the person you are responding to is in the Cc: list. This - convention also makes it unnecessary to explicitly ask to be copied on - replies to your postings. - -- Search the list archives (and the net as a whole) before asking - questions. Some developers can get impatient with people who clearly - have not done their homework. - -- Avoid top-posting (the practice of putting your answer above the quoted - text you are responding to). It makes your response harder to read and - makes a poor impression. - -- Ask on the correct mailing list. Linux-kernel may be the general meeting - point, but it is not the best place to find developers from all - subsystems. - -The last point - finding the correct mailing list - is a common place for -beginning developers to go wrong. Somebody who asks a networking-related -question on linux-kernel will almost certainly receive a polite suggestion -to ask on the netdev list instead, as that is the list frequented by most -networking developers. Other lists exist for the SCSI, video4linux, IDE, -filesystem, etc. subsystems. The best place to look for mailing lists is -in the MAINTAINERS file packaged with the kernel source. - - -2.7: GETTING STARTED WITH KERNEL DEVELOPMENT - -Questions about how to get started with the kernel development process are -common - from both individuals and companies. Equally common are missteps -which make the beginning of the relationship harder than it has to be. - -Companies often look to hire well-known developers to get a development -group started. This can, in fact, be an effective technique. But it also -tends to be expensive and does not do much to grow the pool of experienced -kernel developers. It is possible to bring in-house developers up to speed -on Linux kernel development, given the investment of a bit of time. Taking -this time can endow an employer with a group of developers who understand -the kernel and the company both, and who can help to train others as well. -Over the medium term, this is often the more profitable approach. - -Individual developers are often, understandably, at a loss for a place to -start. Beginning with a large project can be intimidating; one often wants -to test the waters with something smaller first. This is the point where -some developers jump into the creation of patches fixing spelling errors or -minor coding style issues. Unfortunately, such patches create a level of -noise which is distracting for the development community as a whole, so, -increasingly, they are looked down upon. New developers wishing to -introduce themselves to the community will not get the sort of reception -they wish for by these means. - -Andrew Morton gives this advice for aspiring kernel developers - - The #1 project for all kernel beginners should surely be "make sure - that the kernel runs perfectly at all times on all machines which - you can lay your hands on". Usually the way to do this is to work - with others on getting things fixed up (this can require - persistence!) but that's fine - it's a part of kernel development. - -(http://lwn.net/Articles/283982/). - -In the absence of obvious problems to fix, developers are advised to look -at the current lists of regressions and open bugs in general. There is -never any shortage of issues in need of fixing; by addressing these issues, -developers will gain experience with the process while, at the same time, -building respect with the rest of the development community. diff --git a/trunk/Documentation/development-process/3.Early-stage b/trunk/Documentation/development-process/3.Early-stage deleted file mode 100644 index 307a159a70ca..000000000000 --- a/trunk/Documentation/development-process/3.Early-stage +++ /dev/null @@ -1,195 +0,0 @@ -3: EARLY-STAGE PLANNING - -When contemplating a Linux kernel development project, it can be tempting -to jump right in and start coding. As with any significant project, -though, much of the groundwork for success is best laid before the first -line of code is written. Some time spent in early planning and -communication can save far more time later on. - - -3.1: SPECIFYING THE PROBLEM - -Like any engineering project, a successful kernel enhancement starts with a -clear description of the problem to be solved. In some cases, this step is -easy: when a driver is needed for a specific piece of hardware, for -example. In others, though, it is tempting to confuse the real problem -with the proposed solution, and that can lead to difficulties. - -Consider an example: some years ago, developers working with Linux audio -sought a way to run applications without dropouts or other artifacts caused -by excessive latency in the system. The solution they arrived at was a -kernel module intended to hook into the Linux Security Module (LSM) -framework; this module could be configured to give specific applications -access to the realtime scheduler. This module was implemented and sent to -the linux-kernel mailing list, where it immediately ran into problems. - -To the audio developers, this security module was sufficient to solve their -immediate problem. To the wider kernel community, though, it was seen as a -misuse of the LSM framework (which is not intended to confer privileges -onto processes which they would not otherwise have) and a risk to system -stability. Their preferred solutions involved realtime scheduling access -via the rlimit mechanism for the short term, and ongoing latency reduction -work in the long term. - -The audio community, however, could not see past the particular solution -they had implemented; they were unwilling to accept alternatives. The -resulting disagreement left those developers feeling disillusioned with the -entire kernel development process; one of them went back to an audio list -and posted this: - - There are a number of very good Linux kernel developers, but they - tend to get outshouted by a large crowd of arrogant fools. Trying - to communicate user requirements to these people is a waste of - time. They are much too "intelligent" to listen to lesser mortals. - -(http://lwn.net/Articles/131776/). - -The reality of the situation was different; the kernel developers were far -more concerned about system stability, long-term maintenance, and finding -the right solution to the problem than they were with a specific module. -The moral of the story is to focus on the problem - not a specific solution -- and to discuss it with the development community before investing in the -creation of a body of code. - -So, when contemplating a kernel development project, one should obtain -answers to a short set of questions: - - - What, exactly, is the problem which needs to be solved? - - - Who are the users affected by this problem? Which use cases should the - solution address? - - - How does the kernel fall short in addressing that problem now? - -Only then does it make sense to start considering possible solutions. - - -3.2: EARLY DISCUSSION - -When planning a kernel development project, it makes great sense to hold -discussions with the community before launching into implementation. Early -communication can save time and trouble in a number of ways: - - - It may well be that the problem is addressed by the kernel in ways which - you have not understood. The Linux kernel is large and has a number of - features and capabilities which are not immediately obvious. Not all - kernel capabilities are documented as well as one might like, and it is - easy to miss things. Your author has seen the posting of a complete - driver which duplicated an existing driver that the new author had been - unaware of. Code which reinvents existing wheels is not only wasteful; - it will also not be accepted into the mainline kernel. - - - There may be elements of the proposed solution which will not be - acceptable for mainline merging. It is better to find out about - problems like this before writing the code. - - - It's entirely possible that other developers have thought about the - problem; they may have ideas for a better solution, and may be willing - to help in the creation of that solution. - -Years of experience with the kernel development community have taught a -clear lesson: kernel code which is designed and developed behind closed -doors invariably has problems which are only revealed when the code is -released into the community. Sometimes these problems are severe, -requiring months or years of effort before the code can be brought up to -the kernel community's standards. Some examples include: - - - The Devicescape network stack was designed and implemented for - single-processor systems. It could not be merged into the mainline - until it was made suitable for multiprocessor systems. Retrofitting - locking and such into code is a difficult task; as a result, the merging - of this code (now called mac80211) was delayed for over a year. - - - The Reiser4 filesystem included a number of capabilities which, in the - core kernel developers' opinion, should have been implemented in the - virtual filesystem layer instead. It also included features which could - not easily be implemented without exposing the system to user-caused - deadlocks. The late revelation of these problems - and refusal to - address some of them - has caused Reiser4 to stay out of the mainline - kernel. - - - The AppArmor security module made use of internal virtual filesystem - data structures in ways which were considered to be unsafe and - unreliable. This code has since been significantly reworked, but - remains outside of the mainline. - -In each of these cases, a great deal of pain and extra work could have been -avoided with some early discussion with the kernel developers. - - -3.3: WHO DO YOU TALK TO? - -When developers decide to take their plans public, the next question will -be: where do we start? The answer is to find the right mailing list(s) and -the right maintainer. For mailing lists, the best approach is to look in -the MAINTAINERS file for a relevant place to post. If there is a suitable -subsystem list, posting there is often preferable to posting on -linux-kernel; you are more likely to reach developers with expertise in the -relevant subsystem and the environment may be more supportive. - -Finding maintainers can be a bit harder. Again, the MAINTAINERS file is -the place to start. That file tends to not always be up to date, though, -and not all subsystems are represented there. The person listed in the -MAINTAINERS file may, in fact, not be the person who is actually acting in -that role currently. So, when there is doubt about who to contact, a -useful trick is to use git (and "git log" in particular) to see who is -currently active within the subsystem of interest. Look at who is writing -patches, and who, if anybody, is attaching Signed-off-by lines to those -patches. Those are the people who will be best placed to help with a new -development project. - -If all else fails, talking to Andrew Morton can be an effective way to -track down a maintainer for a specific piece of code. - - -3.4: WHEN TO POST? - -If possible, posting your plans during the early stages can only be -helpful. Describe the problem being solved and any plans that have been -made on how the implementation will be done. Any information you can -provide can help the development community provide useful input on the -project. - -One discouraging thing which can happen at this stage is not a hostile -reaction, but, instead, little or no reaction at all. The sad truth of the -matter is (1) kernel developers tend to be busy, (2) there is no shortage -of people with grand plans and little code (or even prospect of code) to -back them up, and (3) nobody is obligated to review or comment on ideas -posted by others. If a request-for-comments posting yields little in the -way of comments, do not assume that it means there is no interest in the -project. Unfortunately, you also cannot assume that there are no problems -with your idea. The best thing to do in this situation is to proceed, -keeping the community informed as you go. - - -3.5: GETTING OFFICIAL BUY-IN - -If your work is being done in a corporate environment - as most Linux -kernel work is - you must, obviously, have permission from suitably -empowered managers before you can post your company's plans or code to a -public mailing list. The posting of code which has not been cleared for -release under a GPL-compatible license can be especially problematic; the -sooner that a company's management and legal staff can agree on the posting -of a kernel development project, the better off everybody involved will be. - -Some readers may be thinking at this point that their kernel work is -intended to support a product which does not yet have an officially -acknowledged existence. Revealing their employer's plans on a public -mailing list may not be a viable option. In cases like this, it is worth -considering whether the secrecy is really necessary; there is often no real -need to keep development plans behind closed doors. - -That said, there are also cases where a company legitimately cannot -disclose its plans early in the development process. Companies with -experienced kernel developers may choose to proceed in an open-loop manner -on the assumption that they will be able to avoid serious integration -problems later. For companies without that sort of in-house expertise, the -best option is often to hire an outside developer to review the plans under -a non-disclosure agreement. The Linux Foundation operates an NDA program -designed to help with this sort of situation; more information can be found -at: - - http://www.linuxfoundation.org/en/NDA_program - -This kind of review is often enough to avoid serious problems later on -without requiring public disclosure of the project. diff --git a/trunk/Documentation/development-process/4.Coding b/trunk/Documentation/development-process/4.Coding deleted file mode 100644 index 014aca8f14e2..000000000000 --- a/trunk/Documentation/development-process/4.Coding +++ /dev/null @@ -1,384 +0,0 @@ -4: GETTING THE CODE RIGHT - -While there is much to be said for a solid and community-oriented design -process, the proof of any kernel development project is in the resulting -code. It is the code which will be examined by other developers and merged -(or not) into the mainline tree. So it is the quality of this code which -will determine the ultimate success of the project. - -This section will examine the coding process. We'll start with a look at a -number of ways in which kernel developers can go wrong. Then the focus -will shift toward doing things right and the tools which can help in that -quest. - - -4.1: PITFALLS - -* Coding style - -The kernel has long had a standard coding style, described in -Documentation/CodingStyle. For much of that time, the policies described -in that file were taken as being, at most, advisory. As a result, there is -a substantial amount of code in the kernel which does not meet the coding -style guidelines. The presence of that code leads to two independent -hazards for kernel developers. - -The first of these is to believe that the kernel coding standards do not -matter and are not enforced. The truth of the matter is that adding new -code to the kernel is very difficult if that code is not coded according to -the standard; many developers will request that the code be reformatted -before they will even review it. A code base as large as the kernel -requires some uniformity of code to make it possible for developers to -quickly understand any part of it. So there is no longer room for -strangely-formatted code. - -Occasionally, the kernel's coding style will run into conflict with an -employer's mandated style. In such cases, the kernel's style will have to -win before the code can be merged. Putting code into the kernel means -giving up a degree of control in a number of ways - including control over -how the code is formatted. - -The other trap is to assume that code which is already in the kernel is -urgently in need of coding style fixes. Developers may start to generate -reformatting patches as a way of gaining familiarity with the process, or -as a way of getting their name into the kernel changelogs - or both. But -pure coding style fixes are seen as noise by the development community; -they tend to get a chilly reception. So this type of patch is best -avoided. It is natural to fix the style of a piece of code while working -on it for other reasons, but coding style changes should not be made for -their own sake. - -The coding style document also should not be read as an absolute law which -can never be transgressed. If there is a good reason to go against the -style (a line which becomes far less readable if split to fit within the -80-column limit, for example), just do it. - - -* Abstraction layers - -Computer Science professors teach students to make extensive use of -abstraction layers in the name of flexibility and information hiding. -Certainly the kernel makes extensive use of abstraction; no project -involving several million lines of code could do otherwise and survive. -But experience has shown that excessive or premature abstraction can be -just as harmful as premature optimization. Abstraction should be used to -the level required and no further. - -At a simple level, consider a function which has an argument which is -always passed as zero by all callers. One could retain that argument just -in case somebody eventually needs to use the extra flexibility that it -provides. By that time, though, chances are good that the code which -implements this extra argument has been broken in some subtle way which was -never noticed - because it has never been used. Or, when the need for -extra flexibility arises, it does not do so in a way which matches the -programmer's early expectation. Kernel developers will routinely submit -patches to remove unused arguments; they should, in general, not be added -in the first place. - -Abstraction layers which hide access to hardware - often to allow the bulk -of a driver to be used with multiple operating systems - are especially -frowned upon. Such layers obscure the code and may impose a performance -penalty; they do not belong in the Linux kernel. - -On the other hand, if you find yourself copying significant amounts of code -from another kernel subsystem, it is time to ask whether it would, in fact, -make sense to pull out some of that code into a separate library or to -implement that functionality at a higher level. There is no value in -replicating the same code throughout the kernel. - - -* #ifdef and preprocessor use in general - -The C preprocessor seems to present a powerful temptation to some C -programmers, who see it as a way to efficiently encode a great deal of -flexibility into a source file. But the preprocessor is not C, and heavy -use of it results in code which is much harder for others to read and -harder for the compiler to check for correctness. Heavy preprocessor use -is almost always a sign of code which needs some cleanup work. - -Conditional compilation with #ifdef is, indeed, a powerful feature, and it -is used within the kernel. But there is little desire to see code which is -sprinkled liberally with #ifdef blocks. As a general rule, #ifdef use -should be confined to header files whenever possible. -Conditionally-compiled code can be confined to functions which, if the code -is not to be present, simply become empty. The compiler will then quietly -optimize out the call to the empty function. The result is far cleaner -code which is easier to follow. - -C preprocessor macros present a number of hazards, including possible -multiple evaluation of expressions with side effects and no type safety. -If you are tempted to define a macro, consider creating an inline function -instead. The code which results will be the same, but inline functions are -easier to read, do not evaluate their arguments multiple times, and allow -the compiler to perform type checking on the arguments and return value. - - -* Inline functions - -Inline functions present a hazard of their own, though. Programmers can -become enamored of the perceived efficiency inherent in avoiding a function -call and fill a source file with inline functions. Those functions, -however, can actually reduce performance. Since their code is replicated -at each call site, they end up bloating the size of the compiled kernel. -That, in turn, creates pressure on the processor's memory caches, which can -slow execution dramatically. Inline functions, as a rule, should be quite -small and relatively rare. The cost of a function call, after all, is not -that high; the creation of large numbers of inline functions is a classic -example of premature optimization. - -In general, kernel programmers ignore cache effects at their peril. The -classic time/space tradeoff taught in beginning data structures classes -often does not apply to contemporary hardware. Space *is* time, in that a -larger program will run slower than one which is more compact. - - -* Locking - -In May, 2006, the "Devicescape" networking stack was, with great -fanfare, released under the GPL and made available for inclusion in the -mainline kernel. This donation was welcome news; support for wireless -networking in Linux was considered substandard at best, and the Devicescape -stack offered the promise of fixing that situation. Yet, this code did not -actually make it into the mainline until June, 2007 (2.6.22). What -happened? - -This code showed a number of signs of having been developed behind -corporate doors. But one large problem in particular was that it was not -designed to work on multiprocessor systems. Before this networking stack -(now called mac80211) could be merged, a locking scheme needed to be -retrofitted onto it. - -Once upon a time, Linux kernel code could be developed without thinking -about the concurrency issues presented by multiprocessor systems. Now, -however, this document is being written on a dual-core laptop. Even on -single-processor systems, work being done to improve responsiveness will -raise the level of concurrency within the kernel. The days when kernel -code could be written without thinking about locking are long past. - -Any resource (data structures, hardware registers, etc.) which could be -accessed concurrently by more than one thread must be protected by a lock. -New code should be written with this requirement in mind; retrofitting -locking after the fact is a rather more difficult task. Kernel developers -should take the time to understand the available locking primitives well -enough to pick the right tool for the job. Code which shows a lack of -attention to concurrency will have a difficult path into the mainline. - - -* Regressions - -One final hazard worth mentioning is this: it can be tempting to make a -change (which may bring big improvements) which causes something to break -for existing users. This kind of change is called a "regression," and -regressions have become most unwelcome in the mainline kernel. With few -exceptions, changes which cause regressions will be backed out if the -regression cannot be fixed in a timely manner. Far better to avoid the -regression in the first place. - -It is often argued that a regression can be justified if it causes things -to work for more people than it creates problems for. Why not make a -change if it brings new functionality to ten systems for each one it -breaks? The best answer to this question was expressed by Linus in July, -2007: - - So we don't fix bugs by introducing new problems. That way lies - madness, and nobody ever knows if you actually make any real - progress at all. Is it two steps forwards, one step back, or one - step forward and two steps back? - -(http://lwn.net/Articles/243460/). - -An especially unwelcome type of regression is any sort of change to the -user-space ABI. Once an interface has been exported to user space, it must -be supported indefinitely. This fact makes the creation of user-space -interfaces particularly challenging: since they cannot be changed in -incompatible ways, they must be done right the first time. For this -reason, a great deal of thought, clear documentation, and wide review for -user-space interfaces is always required. - - - -4.2: CODE CHECKING TOOLS - -For now, at least, the writing of error-free code remains an ideal that few -of us can reach. What we can hope to do, though, is to catch and fix as -many of those errors as possible before our code goes into the mainline -kernel. To that end, the kernel developers have put together an impressive -array of tools which can catch a wide variety of obscure problems in an -automated way. Any problem caught by the computer is a problem which will -not afflict a user later on, so it stands to reason that the automated -tools should be used whenever possible. - -The first step is simply to heed the warnings produced by the compiler. -Contemporary versions of gcc can detect (and warn about) a large number of -potential errors. Quite often, these warnings point to real problems. -Code submitted for review should, as a rule, not produce any compiler -warnings. When silencing warnings, take care to understand the real cause -and try to avoid "fixes" which make the warning go away without addressing -its cause. - -Note that not all compiler warnings are enabled by default. Build the -kernel with "make EXTRA_CFLAGS=-W" to get the full set. - -The kernel provides several configuration options which turn on debugging -features; most of these are found in the "kernel hacking" submenu. Several -of these options should be turned on for any kernel used for development or -testing purposes. In particular, you should turn on: - - - ENABLE_WARN_DEPRECATED, ENABLE_MUST_CHECK, and FRAME_WARN to get an - extra set of warnings for problems like the use of deprecated interfaces - or ignoring an important return value from a function. The output - generated by these warnings can be verbose, but one need not worry about - warnings from other parts of the kernel. - - - DEBUG_OBJECTS will add code to track the lifetime of various objects - created by the kernel and warn when things are done out of order. If - you are adding a subsystem which creates (and exports) complex objects - of its own, consider adding support for the object debugging - infrastructure. - - - DEBUG_SLAB can find a variety of memory allocation and use errors; it - should be used on most development kernels. - - - DEBUG_SPINLOCK, DEBUG_SPINLOCK_SLEEP, and DEBUG_MUTEXES will find a - number of common locking errors. - -There are quite a few other debugging options, some of which will be -discussed below. Some of them have a significant performance impact and -should not be used all of the time. But some time spent learning the -available options will likely be paid back many times over in short order. - -One of the heavier debugging tools is the locking checker, or "lockdep." -This tool will track the acquisition and release of every lock (spinlock or -mutex) in the system, the order in which locks are acquired relative to -each other, the current interrupt environment, and more. It can then -ensure that locks are always acquired in the same order, that the same -interrupt assumptions apply in all situations, and so on. In other words, -lockdep can find a number of scenarios in which the system could, on rare -occasion, deadlock. This kind of problem can be painful (for both -developers and users) in a deployed system; lockdep allows them to be found -in an automated manner ahead of time. Code with any sort of non-trivial -locking should be run with lockdep enabled before being submitted for -inclusion. - -As a diligent kernel programmer, you will, beyond doubt, check the return -status of any operation (such as a memory allocation) which can fail. The -fact of the matter, though, is that the resulting failure recovery paths -are, probably, completely untested. Untested code tends to be broken code; -you could be much more confident of your code if all those error-handling -paths had been exercised a few times. - -The kernel provides a fault injection framework which can do exactly that, -especially where memory allocations are involved. With fault injection -enabled, a configurable percentage of memory allocations will be made to -fail; these failures can be restricted to a specific range of code. -Running with fault injection enabled allows the programmer to see how the -code responds when things go badly. See -Documentation/fault-injection/fault-injection.text for more information on -how to use this facility. - -Other kinds of errors can be found with the "sparse" static analysis tool. -With sparse, the programmer can be warned about confusion between -user-space and kernel-space addresses, mixture of big-endian and -small-endian quantities, the passing of integer values where a set of bit -flags is expected, and so on. Sparse must be installed separately (it can -be found at http://www.kernel.org/pub/software/devel/sparse/ if your -distributor does not package it); it can then be run on the code by adding -"C=1" to your make command. - -Other kinds of portability errors are best found by compiling your code for -other architectures. If you do not happen to have an S/390 system or a -Blackfin development board handy, you can still perform the compilation -step. A large set of cross compilers for x86 systems can be found at - - http://www.kernel.org/pub/tools/crosstool/ - -Some time spent installing and using these compilers will help avoid -embarrassment later. - - -4.3: DOCUMENTATION - -Documentation has often been more the exception than the rule with kernel -development. Even so, adequate documentation will help to ease the merging -of new code into the kernel, make life easier for other developers, and -will be helpful for your users. In many cases, the addition of -documentation has become essentially mandatory. - -The first piece of documentation for any patch is its associated -changelog. Log entries should describe the problem being solved, the form -of the solution, the people who worked on the patch, any relevant -effects on performance, and anything else that might be needed to -understand the patch. - -Any code which adds a new user-space interface - including new sysfs or -/proc files - should include documentation of that interface which enables -user-space developers to know what they are working with. See -Documentation/ABI/README for a description of how this documentation should -be formatted and what information needs to be provided. - -The file Documentation/kernel-parameters.txt describes all of the kernel's -boot-time parameters. Any patch which adds new parameters should add the -appropriate entries to this file. - -Any new configuration options must be accompanied by help text which -clearly explains the options and when the user might want to select them. - -Internal API information for many subsystems is documented by way of -specially-formatted comments; these comments can be extracted and formatted -in a number of ways by the "kernel-doc" script. If you are working within -a subsystem which has kerneldoc comments, you should maintain them and add -them, as appropriate, for externally-available functions. Even in areas -which have not been so documented, there is no harm in adding kerneldoc -comments for the future; indeed, this can be a useful activity for -beginning kernel developers. The format of these comments, along with some -information on how to create kerneldoc templates can be found in the file -Documentation/kernel-doc-nano-HOWTO.txt. - -Anybody who reads through a significant amount of existing kernel code will -note that, often, comments are most notable by their absence. Once again, -the expectations for new code are higher than they were in the past; -merging uncommented code will be harder. That said, there is little desire -for verbosely-commented code. The code should, itself, be readable, with -comments explaining the more subtle aspects. - -Certain things should always be commented. Uses of memory barriers should -be accompanied by a line explaining why the barrier is necessary. The -locking rules for data structures generally need to be explained somewhere. -Major data structures need comprehensive documentation in general. -Non-obvious dependencies between separate bits of code should be pointed -out. Anything which might tempt a code janitor to make an incorrect -"cleanup" needs a comment saying why it is done the way it is. And so on. - - -4.4: INTERNAL API CHANGES - -The binary interface provided by the kernel to user space cannot be broken -except under the most severe circumstances. The kernel's internal -programming interfaces, instead, are highly fluid and can be changed when -the need arises. If you find yourself having to work around a kernel API, -or simply not using a specific functionality because it does not meet your -needs, that may be a sign that the API needs to change. As a kernel -developer, you are empowered to make such changes. - -There are, of course, some catches. API changes can be made, but they need -to be well justified. So any patch making an internal API change should be -accompanied by a description of what the change is and why it is -necessary. This kind of change should also be broken out into a separate -patch, rather than buried within a larger patch. - -The other catch is that a developer who changes an internal API is -generally charged with the task of fixing any code within the kernel tree -which is broken by the change. For a widely-used function, this duty can -lead to literally hundreds or thousands of changes - many of which are -likely to conflict with work being done by other developers. Needless to -say, this can be a large job, so it is best to be sure that the -justification is solid. - -When making an incompatible API change, one should, whenever possible, -ensure that code which has not been updated is caught by the compiler. -This will help you to be sure that you have found all in-tree uses of that -interface. It will also alert developers of out-of-tree code that there is -a change that they need to respond to. Supporting out-of-tree code is not -something that kernel developers need to be worried about, but we also do -not have to make life harder for out-of-tree developers than it it needs to -be. diff --git a/trunk/Documentation/development-process/5.Posting b/trunk/Documentation/development-process/5.Posting deleted file mode 100644 index dd48132a74dd..000000000000 --- a/trunk/Documentation/development-process/5.Posting +++ /dev/null @@ -1,278 +0,0 @@ -5: POSTING PATCHES - -Sooner or later, the time comes when your work is ready to be presented to -the community for review and, eventually, inclusion into the mainline -kernel. Unsurprisingly, the kernel development community has evolved a set -of conventions and procedures which are used in the posting of patches; -following them will make life much easier for everybody involved. This -document will attempt to cover these expectations in reasonable detail; -more information can also be found in the files SubmittingPatches, -SubmittingDrivers, and SubmitChecklist in the kernel documentation -directory. - - -5.1: WHEN TO POST - -There is a constant temptation to avoid posting patches before they are -completely "ready." For simple patches, that is not a problem. If the -work being done is complex, though, there is a lot to be gained by getting -feedback from the community before the work is complete. So you should -consider posting in-progress work, or even making a git tree available so -that interested developers can catch up with your work at any time. - -When posting code which is not yet considered ready for inclusion, it is a -good idea to say so in the posting itself. Also mention any major work -which remains to be done and any known problems. Fewer people will look at -patches which are known to be half-baked, but those who do will come in -with the idea that they can help you drive the work in the right direction. - - -5.2: BEFORE CREATING PATCHES - -There are a number of things which should be done before you consider -sending patches to the development community. These include: - - - Test the code to the extent that you can. Make use of the kernel's - debugging tools, ensure that the kernel will build with all reasonable - combinations of configuration options, use cross-compilers to build for - different architectures, etc. - - - Make sure your code is compliant with the kernel coding style - guidelines. - - - Does your change have performance implications? If so, you should run - benchmarks showing what the impact (or benefit) of your change is; a - summary of the results should be included with the patch. - - - Be sure that you have the right to post the code. If this work was done - for an employer, the employer likely has a right to the work and must be - agreeable with its release under the GPL. - -As a general rule, putting in some extra thought before posting code almost -always pays back the effort in short order. - - -5.3: PATCH PREPARATION - -The preparation of patches for posting can be a surprising amount of work, -but, once again, attempting to save time here is not generally advisable -even in the short term. - -Patches must be prepared against a specific version of the kernel. As a -general rule, a patch should be based on the current mainline as found in -Linus's git tree. It may become necessary to make versions against -mm, -linux-next, or a subsystem tree, though, to facilitate wider testing and -review. Depending on the area of your patch and what is going on -elsewhere, basing a patch against these other trees can require a -significant amount of work resolving conflicts and dealing with API -changes. - -Only the most simple changes should be formatted as a single patch; -everything else should be made as a logical series of changes. Splitting -up patches is a bit of an art; some developers spend a long time figuring -out how to do it in the way that the community expects. There are a few -rules of thumb, however, which can help considerably: - - - The patch series you post will almost certainly not be the series of - changes found in your working revision control system. Instead, the - changes you have made need to be considered in their final form, then - split apart in ways which make sense. The developers are interested in - discrete, self-contained changes, not the path you took to get to those - changes. - - - Each logically independent change should be formatted as a separate - patch. These changes can be small ("add a field to this structure") or - large (adding a significant new driver, for example), but they should be - conceptually small and amenable to a one-line description. Each patch - should make a specific change which can be reviewed on its own and - verified to do what it says it does. - - - As a way of restating the guideline above: do not mix different types of - changes in the same patch. If a single patch fixes a critical security - bug, rearranges a few structures, and reformats the code, there is a - good chance that it will be passed over and the important fix will be - lost. - - - Each patch should yield a kernel which builds and runs properly; if your - patch series is interrupted in the middle, the result should still be a - working kernel. Partial application of a patch series is a common - scenario when the "git bisect" tool is used to find regressions; if the - result is a broken kernel, you will make life harder for developers and - users who are engaging in the noble work of tracking down problems. - - - Do not overdo it, though. One developer recently posted a set of edits - to a single file as 500 separate patches - an act which did not make him - the most popular person on the kernel mailing list. A single patch can - be reasonably large as long as it still contains a single *logical* - change. - - - It can be tempting to add a whole new infrastructure with a series of - patches, but to leave that infrastructure unused until the final patch - in the series enables the whole thing. This temptation should be - avoided if possible; if that series adds regressions, bisection will - finger the last patch as the one which caused the problem, even though - the real bug is elsewhere. Whenever possible, a patch which adds new - code should make that code active immediately. - -Working to create the perfect patch series can be a frustrating process -which takes quite a bit of time and thought after the "real work" has been -done. When done properly, though, it is time well spent. - - -5.4: PATCH FORMATTING - -So now you have a perfect series of patches for posting, but the work is -not done quite yet. Each patch needs to be formatted into a message which -quickly and clearly communicates its purpose to the rest of the world. To -that end, each patch will be composed of the following: - - - An optional "From" line naming the author of the patch. This line is - only necessary if you are passing on somebody else's patch via email, - but it never hurts to add it when in doubt. - - - A one-line description of what the patch does. This message should be - enough for a reader who sees it with no other context to figure out the - scope of the patch; it is the line that will show up in the "short form" - changelogs. This message is usually formatted with the relevant - subsystem name first, followed by the purpose of the patch. For - example: - - gpio: fix build on CONFIG_GPIO_SYSFS=n - - - A blank line followed by a detailed description of the contents of the - patch. This description can be as long as is required; it should say - what the patch does and why it should be applied to the kernel. - - - One or more tag lines, with, at a minimum, one Signed-off-by: line from - the author of the patch. Tags will be described in more detail below. - -The above three items should, normally, be the text used when committing -the change to a revision control system. They are followed by: - - - The patch itself, in the unified ("-u") patch format. Using the "-p" - option to diff will associate function names with changes, making the - resulting patch easier for others to read. - -You should avoid including changes to irrelevant files (those generated by -the build process, for example, or editor backup files) in the patch. The -file "dontdiff" in the Documentation directory can help in this regard; -pass it to diff with the "-X" option. - -The tags mentioned above are used to describe how various developers have -been associated with the development of this patch. They are described in -detail in the SubmittingPatches document; what follows here is a brief -summary. Each of these lines has the format: - - tag: Full Name optional-other-stuff - -The tags in common use are: - - - Signed-off-by: this is a developer's certification that he or she has - the right to submit the patch for inclusion into the kernel. It is an - agreement to the Developer's Certificate of Origin, the full text of - which can be found in Documentation/SubmittingPatches. Code without a - proper signoff cannot be merged into the mainline. - - - Acked-by: indicates an agreement by another developer (often a - maintainer of the relevant code) that the patch is appropriate for - inclusion into the kernel. - - - Tested-by: states that the named person has tested the patch and found - it to work. - - - Reviewed-by: the named developer has reviewed the patch for correctness; - see the reviewer's statement in Documentation/SubmittingPatches for more - detail. - - - Reported-by: names a user who reported a problem which is fixed by this - patch; this tag is used to give credit to the (often underappreciated) - people who test our code and let us know when things do not work - correctly. - - - Cc: the named person received a copy of the patch and had the - opportunity to comment on it. - -Be careful in the addition of tags to your patches: only Cc: is appropriate -for addition without the explicit permission of the person named. - - -5.5: SENDING THE PATCH - -Before you mail your patches, there are a couple of other things you should -take care of: - - - Are you sure that your mailer will not corrupt the patches? Patches - which have had gratuitous white-space changes or line wrapping performed - by the mail client will not apply at the other end, and often will not - be examined in any detail. If there is any doubt at all, mail the patch - to yourself and convince yourself that it shows up intact. - - Documentation/email-clients.txt has some helpful hints on making - specific mail clients work for sending patches. - - - Are you sure your patch is free of silly mistakes? You should always - run patches through scripts/checkpatch.pl and address the complaints it - comes up with. Please bear in mind that checkpatch.pl, while being the - embodiment of a fair amount of thought about what kernel patches should - look like, is not smarter than you. If fixing a checkpatch.pl complaint - would make the code worse, don't do it. - -Patches should always be sent as plain text. Please do not send them as -attachments; that makes it much harder for reviewers to quote sections of -the patch in their replies. Instead, just put the patch directly into your -message. - -When mailing patches, it is important to send copies to anybody who might -be interested in it. Unlike some other projects, the kernel encourages -people to err on the side of sending too many copies; don't assume that the -relevant people will see your posting on the mailing lists. In particular, -copies should go to: - - - The maintainer(s) of the affected subsystem(s). As described earlier, - the MAINTAINERS file is the first place to look for these people. - - - Other developers who have been working in the same area - especially - those who might be working there now. Using git to see who else has - modified the files you are working on can be helpful. - - - If you are responding to a bug report or a feature request, copy the - original poster as well. - - - Send a copy to the relevant mailing list, or, if nothing else applies, - the linux-kernel list. - - - If you are fixing a bug, think about whether the fix should go into the - next stable update. If so, stable@kernel.org should get a copy of the - patch. Also add a "Cc: stable@kernel.org" to the tags within the patch - itself; that will cause the stable team to get a notification when your - fix goes into the mainline. - -When selecting recipients for a patch, it is good to have an idea of who -you think will eventually accept the patch and get it merged. While it -is possible to send patches directly to Linus Torvalds and have him merge -them, things are not normally done that way. Linus is busy, and there are -subsystem maintainers who watch over specific parts of the kernel. Usually -you will be wanting that maintainer to merge your patches. If there is no -obvious maintainer, Andrew Morton is often the patch target of last resort. - -Patches need good subject lines. The canonical format for a patch line is -something like: - - [PATCH nn/mm] subsys: one-line description of the patch - -where "nn" is the ordinal number of the patch, "mm" is the total number of -patches in the series, and "subsys" is the name of the affected subsystem. -Clearly, nn/mm can be omitted for a single, standalone patch. - -If you have a significant series of patches, it is customary to send an -introductory description as part zero. This convention is not universally -followed though; if you use it, remember that information in the -introduction does not make it into the kernel changelogs. So please ensure -that the patches, themselves, have complete changelog information. - -In general, the second and following parts of a multi-part patch should be -sent as a reply to the first part so that they all thread together at the -receiving end. Tools like git and quilt have commands to mail out a set of -patches with the proper threading. If you have a long series, though, and -are using git, please provide the --no-chain-reply-to option to avoid -creating exceptionally deep nesting. diff --git a/trunk/Documentation/development-process/6.Followthrough b/trunk/Documentation/development-process/6.Followthrough deleted file mode 100644 index a8fba3d83a85..000000000000 --- a/trunk/Documentation/development-process/6.Followthrough +++ /dev/null @@ -1,202 +0,0 @@ -6: FOLLOWTHROUGH - -At this point, you have followed the guidelines given so far and, with the -addition of your own engineering skills, have posted a perfect series of -patches. One of the biggest mistakes that even experienced kernel -developers can make is to conclude that their work is now done. In truth, -posting patches indicates a transition into the next stage of the process, -with, possibly, quite a bit of work yet to be done. - -It is a rare patch which is so good at its first posting that there is no -room for improvement. The kernel development process recognizes this fact, -and, as a result, is heavily oriented toward the improvement of posted -code. You, as the author of that code, will be expected to work with the -kernel community to ensure that your code is up to the kernel's quality -standards. A failure to participate in this process is quite likely to -prevent the inclusion of your patches into the mainline. - - -6.1: WORKING WITH REVIEWERS - -A patch of any significance will result in a number of comments from other -developers as they review the code. Working with reviewers can be, for -many developers, the most intimidating part of the kernel development -process. Life can be made much easier, though, if you keep a few things in -mind: - - - If you have explained your patch well, reviewers will understand its - value and why you went to the trouble of writing it. But that value - will not keep them from asking a fundamental question: what will it be - like to maintain a kernel with this code in it five or ten years later? - Many of the changes you may be asked to make - from coding style tweaks - to substantial rewrites - come from the understanding that Linux will - still be around and under development a decade from now. - - - Code review is hard work, and it is a relatively thankless occupation; - people remember who wrote kernel code, but there is little lasting fame - for those who reviewed it. So reviewers can get grumpy, especially when - they see the same mistakes being made over and over again. If you get a - review which seems angry, insulting, or outright offensive, resist the - impulse to respond in kind. Code review is about the code, not about - the people, and code reviewers are not attacking you personally. - - - Similarly, code reviewers are not trying to promote their employers' - agendas at the expense of your own. Kernel developers often expect to - be working on the kernel years from now, but they understand that their - employer could change. They truly are, almost without exception, - working toward the creation of the best kernel they can; they are not - trying to create discomfort for their employers' competitors. - -What all of this comes down to is that, when reviewers send you comments, -you need to pay attention to the technical observations that they are -making. Do not let their form of expression or your own pride keep that -from happening. When you get review comments on a patch, take the time to -understand what the reviewer is trying to say. If possible, fix the things -that the reviewer is asking you to fix. And respond back to the reviewer: -thank them, and describe how you will answer their questions. - -Note that you do not have to agree with every change suggested by -reviewers. If you believe that the reviewer has misunderstood your code, -explain what is really going on. If you have a technical objection to a -suggested change, describe it and justify your solution to the problem. If -your explanations make sense, the reviewer will accept them. Should your -explanation not prove persuasive, though, especially if others start to -agree with the reviewer, take some time to think things over again. It can -be easy to become blinded by your own solution to a problem to the point -that you don't realize that something is fundamentally wrong or, perhaps, -you're not even solving the right problem. - -One fatal mistake is to ignore review comments in the hope that they will -go away. They will not go away. If you repost code without having -responded to the comments you got the time before, you're likely to find -that your patches go nowhere. - -Speaking of reposting code: please bear in mind that reviewers are not -going to remember all the details of the code you posted the last time -around. So it is always a good idea to remind reviewers of previously -raised issues and how you dealt with them; the patch changelog is a good -place for this kind of information. Reviewers should not have to search -through list archives to familiarize themselves with what was said last -time; if you help them get a running start, they will be in a better mood -when they revisit your code. - -What if you've tried to do everything right and things still aren't going -anywhere? Most technical disagreements can be resolved through discussion, -but there are times when somebody simply has to make a decision. If you -honestly believe that this decision is going against you wrongly, you can -always try appealing to a higher power. As of this writing, that higher -power tends to be Andrew Morton. Andrew has a great deal of respect in the -kernel development community; he can often unjam a situation which seems to -be hopelessly blocked. Appealing to Andrew should not be done lightly, -though, and not before all other alternatives have been explored. And bear -in mind, of course, that he may not agree with you either. - - -6.2: WHAT HAPPENS NEXT - -If a patch is considered to be a good thing to add to the kernel, and once -most of the review issues have been resolved, the next step is usually -entry into a subsystem maintainer's tree. How that works varies from one -subsystem to the next; each maintainer has his or her own way of doing -things. In particular, there may be more than one tree - one, perhaps, -dedicated to patches planned for the next merge window, and another for -longer-term work. - -For patches applying to areas for which there is no obvious subsystem tree -(memory management patches, for example), the default tree often ends up -being -mm. Patches which affect multiple subsystems can also end up going -through the -mm tree. - -Inclusion into a subsystem tree can bring a higher level of visibility to a -patch. Now other developers working with that tree will get the patch by -default. Subsystem trees typically feed into -mm and linux-next as well, -making their contents visible to the development community as a whole. At -this point, there's a good chance that you will get more comments from a -new set of reviewers; these comments need to be answered as in the previous -round. - -What may also happen at this point, depending on the nature of your patch, -is that conflicts with work being done by others turn up. In the worst -case, heavy patch conflicts can result in some work being put on the back -burner so that the remaining patches can be worked into shape and merged. -Other times, conflict resolution will involve working with the other -developers and, possibly, moving some patches between trees to ensure that -everything applies cleanly. This work can be a pain, but count your -blessings: before the advent of the linux-next tree, these conflicts often -only turned up during the merge window and had to be addressed in a hurry. -Now they can be resolved at leisure, before the merge window opens. - -Some day, if all goes well, you'll log on and see that your patch has been -merged into the mainline kernel. Congratulations! Once the celebration is -complete (and you have added yourself to the MAINTAINERS file), though, it -is worth remembering an important little fact: the job still is not done. -Merging into the mainline brings its own challenges. - -To begin with, the visibility of your patch has increased yet again. There -may be a new round of comments from developers who had not been aware of -the patch before. It may be tempting to ignore them, since there is no -longer any question of your code being merged. Resist that temptation, -though; you still need to be responsive to developers who have questions or -suggestions. - -More importantly, though: inclusion into the mainline puts your code into -the hands of a much larger group of testers. Even if you have contributed -a driver for hardware which is not yet available, you will be surprised by -how many people will build your code into their kernels. And, of course, -where there are testers, there will be bug reports. - -The worst sort of bug reports are regressions. If your patch causes a -regression, you'll find an uncomfortable number of eyes upon you; -regressions need to be fixed as soon as possible. If you are unwilling or -unable to fix the regression (and nobody else does it for you), your patch -will almost certainly be removed during the stabilization period. Beyond -negating all of the work you have done to get your patch into the mainline, -having a patch pulled as the result of a failure to fix a regression could -well make it harder for you to get work merged in the future. - -After any regressions have been dealt with, there may be other, ordinary -bugs to deal with. The stabilization period is your best opportunity to -fix these bugs and ensure that your code's debut in a mainline kernel -release is as solid as possible. So, please, answer bug reports, and fix -the problems if at all possible. That's what the stabilization period is -for; you can start creating cool new patches once any problems with the old -ones have been taken care of. - -And don't forget that there are other milestones which may also create bug -reports: the next mainline stable release, when prominent distributors pick -up a version of the kernel containing your patch, etc. Continuing to -respond to these reports is a matter of basic pride in your work. If that -is insufficient motivation, though, it's also worth considering that the -development community remembers developers who lose interest in their code -after it's merged. The next time you post a patch, they will be evaluating -it with the assumption that you will not be around to maintain it -afterward. - - -6.3: OTHER THINGS THAT CAN HAPPEN - -One day, you may open your mail client and see that somebody has mailed you -a patch to your code. That is one of the advantages of having your code -out there in the open, after all. If you agree with the patch, you can -either forward it on to the subsystem maintainer (be sure to include a -proper From: line so that the attribution is correct, and add a signoff of -your own), or send an Acked-by: response back and let the original poster -send it upward. - -If you disagree with the patch, send a polite response explaining why. If -possible, tell the author what changes need to be made to make the patch -acceptable to you. There is a certain resistance to merging patches which -are opposed by the author and maintainer of the code, but it only goes so -far. If you are seen as needlessly blocking good work, those patches will -eventually flow around you and get into the mainline anyway. In the Linux -kernel, nobody has absolute veto power over any code. Except maybe Linus. - -On very rare occasion, you may see something completely different: another -developer posts a different solution to your problem. At that point, -chances are that one of the two patches will not be merged, and "mine was -here first" is not considered to be a compelling technical argument. If -somebody else's patch displaces yours and gets into the mainline, there is -really only one way to respond: be pleased that your problem got solved and -get on with your work. Having one's work shoved aside in this manner can -be hurtful and discouraging, but the community will remember your reaction -long after they have forgotten whose patch actually got merged. diff --git a/trunk/Documentation/development-process/7.AdvancedTopics b/trunk/Documentation/development-process/7.AdvancedTopics deleted file mode 100644 index a2cf74093aa1..000000000000 --- a/trunk/Documentation/development-process/7.AdvancedTopics +++ /dev/null @@ -1,173 +0,0 @@ -7: ADVANCED TOPICS - -At this point, hopefully, you have a handle on how the development process -works. There is still more to learn, however! This section will cover a -number of topics which can be helpful for developers wanting to become a -regular part of the Linux kernel development process. - -7.1: MANAGING PATCHES WITH GIT - -The use of distributed version control for the kernel began in early 2002, -when Linus first started playing with the proprietary BitKeeper -application. While BitKeeper was controversial, the approach to software -version management it embodied most certainly was not. Distributed version -control enabled an immediate acceleration of the kernel development -project. In current times, there are several free alternatives to -BitKeeper. For better or for worse, the kernel project has settled on git -as its tool of choice. - -Managing patches with git can make life much easier for the developer, -especially as the volume of those patches grows. Git also has its rough -edges and poses certain hazards; it is a young and powerful tool which is -still being civilized by its developers. This document will not attempt to -teach the reader how to use git; that would be sufficient material for a -long document in its own right. Instead, the focus here will be on how git -fits into the kernel development process in particular. Developers who -wish to come up to speed with git will find more information at: - - http://git.or.cz/ - - http://www.kernel.org/pub/software/scm/git/docs/user-manual.html - -and on various tutorials found on the web. - -The first order of business is to read the above sites and get a solid -understanding of how git works before trying to use it to make patches -available to others. A git-using developer should be able to obtain a copy -of the mainline repository, explore the revision history, commit changes to -the tree, use branches, etc. An understanding of git's tools for the -rewriting of history (such as rebase) is also useful. Git comes with its -own terminology and concepts; a new user of git should know about refs, -remote branches, the index, fast-forward merges, pushes and pulls, detached -heads, etc. It can all be a little intimidating at the outset, but the -concepts are not that hard to grasp with a bit of study. - -Using git to generate patches for submission by email can be a good -exercise while coming up to speed. - -When you are ready to start putting up git trees for others to look at, you -will, of course, need a server that can be pulled from. Setting up such a -server with git-daemon is relatively straightforward if you have a system -which is accessible to the Internet. Otherwise, free, public hosting sites -(Github, for example) are starting to appear on the net. Established -developers can get an account on kernel.org, but those are not easy to come -by; see http://kernel.org/faq/ for more information. - -The normal git workflow involves the use of a lot of branches. Each line -of development can be separated into a separate "topic branch" and -maintained independently. Branches in git are cheap, there is no reason to -not make free use of them. And, in any case, you should not do your -development in any branch which you intend to ask others to pull from. -Publicly-available branches should be created with care; merge in patches -from development branches when they are in complete form and ready to go - -not before. - -Git provides some powerful tools which can allow you to rewrite your -development history. An inconvenient patch (one which breaks bisection, -say, or which has some other sort of obvious bug) can be fixed in place or -made to disappear from the history entirely. A patch series can be -rewritten as if it had been written on top of today's mainline, even though -you have been working on it for months. Changes can be transparently -shifted from one branch to another. And so on. Judicious use of git's -ability to revise history can help in the creation of clean patch sets with -fewer problems. - -Excessive use of this capability can lead to other problems, though, beyond -a simple obsession for the creation of the perfect project history. -Rewriting history will rewrite the changes contained in that history, -turning a tested (hopefully) kernel tree into an untested one. But, beyond -that, developers cannot easily collaborate if they do not have a shared -view of the project history; if you rewrite history which other developers -have pulled into their repositories, you will make life much more difficult -for those developers. So a simple rule of thumb applies here: history -which has been exported to others should generally be seen as immutable -thereafter. - -So, once you push a set of changes to your publicly-available server, those -changes should not be rewritten. Git will attempt to enforce this rule if -you try to push changes which do not result in a fast-forward merge -(i.e. changes which do not share the same history). It is possible to -override this check, and there may be times when it is necessary to rewrite -an exported tree. Moving changesets between trees to avoid conflicts in -linux-next is one example. But such actions should be rare. This is one -of the reasons why development should be done in private branches (which -can be rewritten if necessary) and only moved into public branches when -it's in a reasonably advanced state. - -As the mainline (or other tree upon which a set of changes is based) -advances, it is tempting to merge with that tree to stay on the leading -edge. For a private branch, rebasing can be an easy way to keep up with -another tree, but rebasing is not an option once a tree is exported to the -world. Once that happens, a full merge must be done. Merging occasionally -makes good sense, but overly frequent merges can clutter the history -needlessly. Suggested technique in this case is to merge infrequently, and -generally only at specific release points (such as a mainline -rc -release). If you are nervous about specific changes, you can always -perform test merges in a private branch. The git "rerere" tool can be -useful in such situations; it remembers how merge conflicts were resolved -so that you don't have to do the same work twice. - -One of the biggest recurring complaints about tools like git is this: the -mass movement of patches from one repository to another makes it easy to -slip in ill-advised changes which go into the mainline below the review -radar. Kernel developers tend to get unhappy when they see that kind of -thing happening; putting up a git tree with unreviewed or off-topic patches -can affect your ability to get trees pulled in the future. Quoting Linus: - - You can send me patches, but for me to pull a git patch from you, I - need to know that you know what you're doing, and I need to be able - to trust things *without* then having to go and check every - individual change by hand. - -(http://lwn.net/Articles/224135/). - -To avoid this kind of situation, ensure that all patches within a given -branch stick closely to the associated topic; a "driver fixes" branch -should not be making changes to the core memory management code. And, most -importantly, do not use a git tree to bypass the review process. Post an -occasional summary of the tree to the relevant list, and, when the time is -right, request that the tree be included in linux-next. - -If and when others start to send patches for inclusion into your tree, -don't forget to review them. Also ensure that you maintain the correct -authorship information; the git "am" tool does its best in this regard, but -you may have to add a "From:" line to the patch if it has been relayed to -you via a third party. - -When requesting a pull, be sure to give all the relevant information: where -your tree is, what branch to pull, and what changes will result from the -pull. The git request-pull command can be helpful in this regard; it will -format the request as other developers expect, and will also check to be -sure that you have remembered to push those changes to the public server. - - -7.2: REVIEWING PATCHES - -Some readers will certainly object to putting this section with "advanced -topics" on the grounds that even beginning kernel developers should be -reviewing patches. It is certainly true that there is no better way to -learn how to program in the kernel environment than by looking at code -posted by others. In addition, reviewers are forever in short supply; by -looking at code you can make a significant contribution to the process as a -whole. - -Reviewing code can be an intimidating prospect, especially for a new kernel -developer who may well feel nervous about questioning code - in public - -which has been posted by those with more experience. Even code written by -the most experienced developers can be improved, though. Perhaps the best -piece of advice for reviewers (all reviewers) is this: phrase review -comments as questions rather than criticisms. Asking "how does the lock -get released in this path?" will always work better than stating "the -locking here is wrong." - -Different developers will review code from different points of view. Some -are mostly concerned with coding style and whether code lines have trailing -white space. Others will focus primarily on whether the change implemented -by the patch as a whole is a good thing for the kernel or not. Yet others -will check for problematic locking, excessive stack usage, possible -security issues, duplication of code found elsewhere, adequate -documentation, adverse effects on performance, user-space ABI changes, etc. -All types of review, if they lead to better code going into the kernel, are -welcome and worthwhile. - - diff --git a/trunk/Documentation/development-process/8.Conclusion b/trunk/Documentation/development-process/8.Conclusion deleted file mode 100644 index 1990ab4b4949..000000000000 --- a/trunk/Documentation/development-process/8.Conclusion +++ /dev/null @@ -1,74 +0,0 @@ -8: FOR MORE INFORMATION - -There are numerous sources of information on Linux kernel development and -related topics. First among those will always be the Documentation -directory found in the kernel source distribution. The top-level HOWTO -file is an important starting point; SubmittingPatches and -SubmittingDrivers are also something which all kernel developers should -read. Many internal kernel APIs are documented using the kerneldoc -mechanism; "make htmldocs" or "make pdfdocs" can be used to generate those -documents in HTML or PDF format (though the version of TeX shipped by some -distributions runs into internal limits and fails to process the documents -properly). - -Various web sites discuss kernel development at all levels of detail. Your -author would like to humbly suggest http://lwn.net/ as a source; -information on many specific kernel topics can be found via the LWN kernel -index at: - - http://lwn.net/Kernel/Index/ - -Beyond that, a valuable resource for kernel developers is: - - http://kernelnewbies.org/ - -Information about the linux-next tree gathers at: - - http://linux.f-seidel.de/linux-next/pmwiki/ - -And, of course, one should not forget http://kernel.org/, the definitive -location for kernel release information. - -There are a number of books on kernel development: - - Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro - Rubini, and Greg Kroah-Hartman). Online at - http://lwn.net/Kernel/LDD3/. - - Linux Kernel Development (Robert Love). - - Understanding the Linux Kernel (Daniel Bovet and Marco Cesati). - -All of these books suffer from a common fault, though: they tend to be -somewhat obsolete by the time they hit the shelves, and they have been on -the shelves for a while now. Still, there is quite a bit of good -information to be found there. - -Documentation for git can be found at: - - http://www.kernel.org/pub/software/scm/git/docs/ - - http://www.kernel.org/pub/software/scm/git/docs/user-manual.html - - -9: CONCLUSION - -Congratulations to anybody who has made it through this long-winded -document. Hopefully it has provided a helpful understanding of how the -Linux kernel is developed and how you can participate in that process. - -In the end, it's the participation that matters. Any open source software -project is no more than the sum of what its contributors put into it. The -Linux kernel has progressed as quickly and as well as it has because it has -been helped by an impressively large group of developers, all of whom are -working to make it better. The kernel is a premier example of what can be -done when thousands of people work together toward a common goal. - -The kernel can always benefit from a larger developer base, though. There -is always more work to do. But, just as importantly, most other -participants in the Linux ecosystem can benefit through contributing to the -kernel. Getting code into the mainline is the key to higher code quality, -lower maintenance and distribution costs, a higher level of influence over -the direction of kernel development, and more. It is a situation where -everybody involved wins. Fire up your editor and come join us; you will be -more than welcome. diff --git a/trunk/Documentation/dontdiff b/trunk/Documentation/dontdiff index 1e89a51ea49b..27809357da58 100644 --- a/trunk/Documentation/dontdiff +++ b/trunk/Documentation/dontdiff @@ -2,13 +2,11 @@ *.aux *.bin *.cpio -*.csp -*.dsp +*.css *.dvi -*.elf *.eps +*.fw.gen.S *.fw -*.gen.S *.gif *.grep *.grp @@ -32,7 +30,6 @@ *.s *.sgml *.so -*.so.dbg *.symtypes *.tab.c *.tab.h @@ -41,17 +38,24 @@ *.xml *_MODULES *_vga16.c +*cscope* *~ *.9 *.9.gz .* +.cscope +.gitignore +.mailmap .mm 53c700_d.h +53c8xx_d.h* +COPYING +CREDITS CVS ChangeSet Image Kerntypes -Module.markers +MODS.txt Module.symvers PENDING SCCS @@ -69,9 +73,7 @@ autoconf.h* bbootsect bin2c binkernel.spec -binoffset bootsect -bounds.h bsetup btfixupprep build @@ -87,36 +89,39 @@ config_data.h* config_data.gz* conmakehash consolemap_deftbl.c* -cpustr.h crc32table.h* cscope.* -defkeymap.c +defkeymap.c* devlist.h* docproc +dummy_sym.c* elf2ecoff elfconfig.h* +filelist fixdep fore200e_mkfirm fore200e_pca_fw.c* gconf gen-devlist +gen-kdb_cmds.c* gen_crc32table gen_init_cpio genksyms +gentbl *_gray256.c -ihex2fw ikconfig.h* initramfs_data.cpio initramfs_data.cpio.gz initramfs_list kallsyms kconfig -keywords.c +kconfig.tk +keywords.c* ksym.c* ksym.h* kxgettext lkc_defs.h -lex.c +lex.c* lex.*.c logo_*.c logo_*_clut224.c @@ -125,6 +130,7 @@ lxdialog mach-types mach-types.h machtypes.h +make_times_h map maui_boot.h mconf @@ -132,7 +138,6 @@ miboot* mk_elfconfig mkboot mkbugboot -mkcpustr mkdep mkprep mktables @@ -140,12 +145,11 @@ mktree modpost modules.order modversions.h* -ncscope.* offset.h offsets.h oui.c* -parse.c -parse.h +parse.c* +parse.h* patches* pca200e.bin pca200e_ecd.bin2 @@ -153,7 +157,7 @@ piggy.gz piggyback pnmtologo ppc_defs.h* -promcon_tbl.c +promcon_tbl.c* pss_boot.h qconf raid6altivec*.c @@ -164,38 +168,27 @@ series setup setup.bin setup.elf +sim710_d.h* sImage sm_tbl* split-include -syscalltab.h tags tftpboot.img timeconst.h times.h* +tkparse trix_boot.h utsrelease.h* -vdso-syms.lds vdso.lds -vdso32-int80-syms.lds -vdso32-syms.lds -vdso32-syscall-syms.lds -vdso32-sysenter-syms.lds -vdso32.lds -vdso32.so.dbg -vdso64.lds -vdso64.so.dbg version.h* vmlinux vmlinux-* vmlinux.aout -vmlinux.lds +vmlinux*.lds* +vmlinux*.scr vsyscall.lds -vsyscall_32.lds wanxlfw.inc uImage unifdef -wakeup.bin -wakeup.elf -wakeup.lds zImage* zconf.hash.c diff --git a/trunk/Documentation/fb/intelfb.txt b/trunk/Documentation/fb/intelfb.txt index dd9e944ea628..27a3160650a4 100644 --- a/trunk/Documentation/fb/intelfb.txt +++ b/trunk/Documentation/fb/intelfb.txt @@ -14,7 +14,6 @@ graphics devices. These would include: Intel 915GM Intel 945G Intel 945GM - Intel 945GME Intel 965G Intel 965GM diff --git a/trunk/Documentation/fb/uvesafb.txt b/trunk/Documentation/fb/uvesafb.txt index 7ac3c4078ff9..bcfc233a0080 100644 --- a/trunk/Documentation/fb/uvesafb.txt +++ b/trunk/Documentation/fb/uvesafb.txt @@ -52,7 +52,7 @@ are either given on the kernel command line or as module parameters, e.g.: video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel) - # modprobe uvesafb mode_option=1024x768-32 mtrr=3 scroll=ywrap (module) + # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap (module) Accepted options: @@ -105,7 +105,7 @@ vtotal:n The mode you want to set, in the standard modedb format. Refer to modedb.txt for a detailed description. When uvesafb is compiled as a module, the mode string should be provided as a value of the - 'mode_option' option. + 'mode' option. vbemode:x Force the use of VBE mode x. The mode will only be set if it's diff --git a/trunk/Documentation/fb/viafb.modes b/trunk/Documentation/fb/viafb.modes deleted file mode 100644 index 02e5b487f00e..000000000000 --- a/trunk/Documentation/fb/viafb.modes +++ /dev/null @@ -1,870 +0,0 @@ -# -# -# These data are based on the CRTC parameters in -# -# VIA Integration Graphics Chip -# (C) 2004 VIA Technologies Inc. -# - -# -# 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) -# -# Horizontal Vertical -# Resolution 640 480 -# Scan Frequency 31.469 kHz 59.94 Hz -# Sync Width 3.813 us 0.064 ms -# 12 chars 2 lines -# Front Porch 0.636 us 0.318 ms -# 2 chars 10 lines -# Back Porch 1.907 us 1.048 ms -# 6 chars 33 lines -# Active Time 25.422 us 15.253 ms -# 80 chars 480 lines -# Blank Time 6.356 us 1.430 ms -# 20 chars 45 lines -# Polarity negative negative -# - -mode "640x480-60" -# D: 25.175 MHz, H: 31.469 kHz, V: 59.94 Hz - geometry 640 480 640 480 32 - timings 39722 48 16 33 10 96 2 endmode mode "480x640-60" -# D: 24.823 MHz, H: 39.780 kHz, V: 60.00 Hz - geometry 480 640 480 640 32 timings 39722 72 24 19 1 48 3 endmode -# -# 640x480, 75 Hz, Non-Interlaced (31.50 MHz dotclock) -# -# Horizontal Vertical -# Resolution 640 480 -# Scan Frequency 37.500 kHz 75.00 Hz -# Sync Width 2.032 us 0.080 ms -# 8 chars 3 lines -# Front Porch 0.508 us 0.027 ms -# 2 chars 1 lines -# Back Porch 3.810 us 0.427 ms -# 15 chars 16 lines -# Active Time 20.317 us 12.800 ms -# 80 chars 480 lines -# Blank Time 6.349 us 0.533 ms -# 25 chars 20 lines -# Polarity negative negative -# - mode "640x480-75" -# D: 31.50 MHz, H: 37.500 kHz, V: 75.00 Hz - geometry 640 480 640 480 32 timings 31747 120 16 16 1 64 3 endmode -# -# 640x480, 85 Hz, Non-Interlaced (36.000 MHz dotclock) -# -# Horizontal Vertical -# Resolution 640 480 -# Scan Frequency 43.269 kHz 85.00 Hz -# Sync Width 1.556 us 0.069 ms -# 7 chars 3 lines -# Front Porch 1.556 us 0.023 ms -# 7 chars 1 lines -# Back Porch 2.222 us 0.578 ms -# 10 chars 25 lines -# Active Time 17.778 us 11.093 ms -# 80 chars 480 lines -# Blank Time 5.333 us 0.670 ms -# 24 chars 29 lines -# Polarity negative negative -# - mode "640x480-85" -# D: 36.000 MHz, H: 43.269 kHz, V: 85.00 Hz - geometry 640 480 640 480 32 timings 27777 80 56 25 1 56 3 endmode -# -# 640x480, 100 Hz, Non-Interlaced (43.163 MHz dotclock) -# -# Horizontal Vertical -# Resolution 640 480 -# Scan Frequency 50.900 kHz 100.00 Hz -# Sync Width 1.483 us 0.058 ms -# 8 chars 3 lines -# Front Porch 0.927 us 0.019 ms -# 5 chars 1 lines -# Back Porch 2.409 us 0.475 ms -# 13 chars 25 lines -# Active Time 14.827 us 9.430 ms -# 80 chars 480 lines -# Blank Time 4.819 us 0.570 ms -# 26 chars 29 lines -# Polarity positive positive -# - mode "640x480-100" -# D: 43.163 MHz, H: 50.900 kHz, V: 100.00 Hz - geometry 640 480 640 480 32 timings 23168 104 40 25 1 64 3 endmode -# -# 640x480, 120 Hz, Non-Interlaced (52.406 MHz dotclock) -# -# Horizontal Vertical -# Resolution 640 480 -# Scan Frequency 61.800 kHz 120.00 Hz -# Sync Width 1.221 us 0.048 ms -# 8 chars 3 lines -# Front Porch 0.763 us 0.016 ms -# 5 chars 1 lines -# Back Porch 1.984 us 0.496 ms -# 13 chars 31 lines -# Active Time 12.212 us 7.767 ms -# 80 chars 480 lines -# Blank Time 3.969 us 0.566 ms -# 26 chars 35 lines -# Polarity positive positive -# - mode "640x480-120" -# D: 52.406 MHz, H: 61.800 kHz, V: 120.00 Hz - geometry 640 480 640 480 32 timings 19081 104 40 31 1 64 3 endmode -# -# 720x480, 60 Hz, Non-Interlaced (26.880 MHz dotclock) -# -# Horizontal Vertical -# Resolution 720 480 -# Scan Frequency 30.000 kHz 60.241 Hz -# Sync Width 2.679 us 0.099 ms -# 9 chars 3 lines -# Front Porch 0.595 us 0.033 ms -# 2 chars 1 lines -# Back Porch 3.274 us 0.462 ms -# 11 chars 14 lines -# Active Time 26.786 us 16.000 ms -# 90 chars 480 lines -# Blank Time 6.548 us 0.600 ms -# 22 chars 18 lines -# Polarity positive positive -# - mode "720x480-60" -# D: 26.880 MHz, H: 30.000 kHz, V: 60.24 Hz - geometry 720 480 720 480 32 timings 37202 88 16 14 1 72 3 endmode -# -# 800x480, 60 Hz, Non-Interlaced (29.581 MHz dotclock) -# -# Horizontal Vertical -# Resolution 800 480 -# Scan Frequency 29.892 kHz 60.00 Hz -# Sync Width 2.704 us 100.604 us -# 10 chars 3 lines -# Front Porch 0.541 us 33.535 us -# 2 chars 1 lines -# Back Porch 3.245 us 435.949 us -# 12 chars 13 lines -# Active Time 27.044 us 16.097 ms -# 100 chars 480 lines -# Blank Time 6.491 us 0.570 ms -# 24 chars 17 lines -# Polarity positive positive -# - mode "800x480-60" -# D: 29.500 MHz, H: 29.738 kHz, V: 60.00 Hz - geometry 800 480 800 480 32 timings 33805 96 24 10 3 72 7 endmode -# -# 720x576, 60 Hz, Non-Interlaced (32.668 MHz dotclock) -# -# Horizontal Vertical -# Resolution 720 576 -# Scan Frequency 35.820 kHz 60.00 Hz -# Sync Width 2.204 us 0.083 ms -# 9 chars 3 lines -# Front Porch 0.735 us 0.027 ms -# 3 chars 1 lines -# Back Porch 2.939 us 0.459 ms -# 12 chars 17 lines -# Active Time 22.040 us 16.080 ms -# 90 chars 476 lines -# Blank Time 5.877 us 0.586 ms -# 24 chars 21 lines -# Polarity positive positive -# - mode "720x576-60" -# D: 32.668 MHz, H: 35.820 kHz, V: 60.00 Hz - geometry 720 576 720 576 32 timings 30611 96 24 17 1 72 3 endmode -# -# 800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock) -# -# Horizontal Vertical -# Resolution 800 600 -# Scan Frequency 37.879 kHz 60.32 Hz -# Sync Width 3.200 us 0.106 ms -# 16 chars 4 lines -# Front Porch 1.000 us 0.026 ms -# 5 chars 1 lines -# Back Porch 2.200 us 0.607 ms -# 11 chars 23 lines -# Active Time 20.000 us 15.840 ms -# 100 chars 600 lines -# Blank Time 6.400 us 0.739 ms -# 32 chars 28 lines -# Polarity positive positive -# - mode "800x600-60" -# D: 40.00 MHz, H: 37.879 kHz, V: 60.32 Hz - geometry 800 600 800 600 32 - timings 25000 88 40 23 1 128 4 hsync high vsync high endmode -# -# 800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock) -# -# Horizontal Vertical -# Resolution 800 600 -# Scan Frequency 46.875 kHz 75.00 Hz -# Sync Width 1.616 us 0.064 ms -# 10 chars 3 lines -# Front Porch 0.323 us 0.021 ms -# 2 chars 1 lines -# Back Porch 3.232 us 0.448 ms -# 20 chars 21 lines -# Active Time 16.162 us 12.800 ms -# 100 chars 600 lines -# Blank Time 5.172 us 0.533 ms -# 32 chars 25 lines -# Polarity positive positive -# - mode "800x600-75" -# D: 49.50 MHz, H: 46.875 kHz, V: 75.00 Hz - geometry 800 600 800 600 32 - timings 20203 160 16 21 1 80 3 hsync high vsync high endmode -# -# 800x600, 85 Hz, Non-Interlaced (56.25 MHz dotclock) -# -# Horizontal Vertical -# Resolution 800 600 -# Scan Frequency 53.674 kHz 85.061 Hz -# Sync Width 1.138 us 0.056 ms -# 8 chars 3 lines -# Front Porch 0.569 us 0.019 ms -# 4 chars 1 lines -# Back Porch 2.702 us 0.503 ms -# 19 chars 27 lines -# Active Time 14.222 us 11.179 ms -# 100 chars 600 lines -# Blank Time 4.409 us 0.578 ms -# 31 chars 31 lines -# Polarity positive positive -# - mode "800x600-85" -# D: 56.25 MHz, H: 53.674 kHz, V: 85.061 Hz - geometry 800 600 800 600 32 - timings 17777 152 32 27 1 64 3 hsync high vsync high endmode -# -# 800x600, 100 Hz, Non-Interlaced (67.50 MHz dotclock) -# -# Horizontal Vertical -# Resolution 800 600 -# Scan Frequency 62.500 kHz 100.00 Hz -# Sync Width 0.948 us 0.064 ms -# 8 chars 4 lines -# Front Porch 0.000 us 0.112 ms -# 0 chars 7 lines -# Back Porch 3.200 us 0.224 ms -# 27 chars 14 lines -# Active Time 11.852 us 9.600 ms -# 100 chars 600 lines -# Blank Time 4.148 us 0.400 ms -# 35 chars 25 lines -# Polarity positive positive -# - mode "800x600-100" -# D: 67.50 MHz, H: 62.500 kHz, V: 100.00 Hz - geometry 800 600 800 600 32 - timings 14667 216 0 14 7 64 4 hsync high vsync high endmode -# -# 800x600, 120 Hz, Non-Interlaced (83.950 MHz dotclock) -# -# Horizontal Vertical -# Resolution 800 600 -# Scan Frequency 77.160 kHz 120.00 Hz -# Sync Width 1.048 us 0.039 ms -# 11 chars 3 lines -# Front Porch 0.667 us 0.013 ms -# 7 chars 1 lines -# Back Porch 1.715 us 0.507 ms -# 18 chars 39 lines -# Active Time 9.529 us 7.776 ms -# 100 chars 600 lines -# Blank Time 3.431 us 0.557 ms -# 36 chars 43 lines -# Polarity positive positive -# - mode "800x600-120" -# D: 83.950 MHz, H: 77.160 kHz, V: 120.00 Hz - geometry 800 600 800 600 32 - timings 11912 144 56 39 1 88 3 hsync high vsync high endmode -# -# 848x480, 60 Hz, Non-Interlaced (31.490 MHz dotclock) -# -# Horizontal Vertical -# Resolution 848 480 -# Scan Frequency 29.820 kHz 60.00 Hz -# Sync Width 2.795 us 0.099 ms -# 11 chars 3 lines -# Front Porch 0.508 us 0.033 ms -# 2 chars 1 lines -# Back Porch 3.303 us 0.429 ms -# 13 chars 13 lines -# Active Time 26.929 us 16.097 ms -# 106 chars 480 lines -# Blank Time 6.605 us 0.570 ms -# 26 chars 17 lines -# Polarity positive positive -# - mode "848x480-60" -# D: 31.500 MHz, H: 29.830 kHz, V: 60.00 Hz - geometry 848 480 848 480 32 - timings 31746 104 24 12 3 80 5 hsync high vsync high endmode -# -# 856x480, 60 Hz, Non-Interlaced (31.728 MHz dotclock) -# -# Horizontal Vertical -# Resolution 856 480 -# Scan Frequency 29.820 kHz 60.00 Hz -# Sync Width 2.774 us 0.099 ms -# 11 chars 3 lines -# Front Porch 0.504 us 0.033 ms -# 2 chars 1 lines -# Back Porch 3.728 us 0.429 ms -# 13 chars 13 lines -# Active Time 26.979 us 16.097 ms -# 107 chars 480 lines -# Blank Time 6.556 us 0.570 ms -# 26 chars 17 lines -# Polarity positive positive -# - mode "856x480-60" -# D: 31.728 MHz, H: 29.820 kHz, V: 60.00 Hz - geometry 856 480 856 480 32 - timings 31518 104 16 13 1 88 3 - hsync high vsync high endmode mode "960x600-60" -# D: 45.250 MHz, H: 37.212 kHz, V: 60.00 Hz - geometry 960 600 960 600 32 timings 22099 128 32 15 3 96 6 endmode -# -# 1000x600, 60 Hz, Non-Interlaced (48.068 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1000 600 -# Scan Frequency 37.320 kHz 60.00 Hz -# Sync Width 2.164 us 0.080 ms -# 13 chars 3 lines -# Front Porch 0.832 us 0.027 ms -# 5 chars 1 lines -# Back Porch 2.996 us 0.483 ms -# 18 chars 18 lines -# Active Time 20.804 us 16.077 ms -# 125 chars 600 lines -# Blank Time 5.991 us 0.589 ms -# 36 chars 22 lines -# Polarity negative positive -# - mode "1000x600-60" -# D: 48.068 MHz, H: 37.320 kHz, V: 60.00 Hz - geometry 1000 600 1000 600 32 - timings 20834 144 40 18 1 104 3 endmode mode "1024x576-60" -# D: 46.996 MHz, H: 35.820 kHz, V: 60.00 Hz - geometry 1024 576 1024 576 32 - timings 21278 144 40 17 1 104 3 endmode mode "1024x600-60" -# D: 48.964 MHz, H: 37.320 kHz, V: 60.00 Hz - geometry 1024 600 1024 600 32 - timings 20461 144 40 18 1 104 3 endmode mode "1088x612-60" -# D: 52.952 MHz, H: 38.040 kHz, V: 60.00 Hz - geometry 1088 612 1088 612 32 timings 18877 152 48 16 3 104 5 endmode -# -# 1024x512, 60 Hz, Non-Interlaced (41.291 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1024 512 -# Scan Frequency 31.860 kHz 60.00 Hz -# Sync Width 2.519 us 0.094 ms -# 13 chars 3 lines -# Front Porch 0.775 us 0.031 ms -# 4 chars 1 lines -# Back Porch 3.294 us 0.465 ms -# 17 chars 15 lines -# Active Time 24.800 us 16.070 ms -# 128 chars 512 lines -# Blank Time 6.587 us 0.596 ms -# 34 chars 19 lines -# Polarity positive positive -# - mode "1024x512-60" -# D: 41.291 MHz, H: 31.860 kHz, V: 60.00 Hz - geometry 1024 512 1024 512 32 - timings 24218 126 32 15 1 104 3 hsync high vsync high endmode -# -# 1024x600, 60 Hz, Non-Interlaced (48.875 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1024 768 -# Scan Frequency 37.252 kHz 60.00 Hz -# Sync Width 2.128 us 80.532us -# 13 chars 3 lines -# Front Porch 0.818 us 26.844 us -# 5 chars 1 lines -# Back Porch 2.946 us 483.192 us -# 18 chars 18 lines -# Active Time 20.951 us 16.697 ms -# 128 chars 622 lines -# Blank Time 5.893 us 0.591 ms -# 36 chars 22 lines -# Polarity negative positive -# -#mode "1024x600-60" -# # D: 48.875 MHz, H: 37.252 kHz, V: 60.00 Hz -# geometry 1024 600 1024 600 32 -# timings 20460 144 40 18 1 104 3 -# endmode -# -# 1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1024 768 -# Scan Frequency 48.363 kHz 60.00 Hz -# Sync Width 2.092 us 0.124 ms -# 17 chars 6 lines -# Front Porch 0.369 us 0.062 ms -# 3 chars 3 lines -# Back Porch 2.462 us 0.601 ms -# 20 chars 29 lines -# Active Time 15.754 us 15.880 ms -# 128 chars 768 lines -# Blank Time 4.923 us 0.786 ms -# 40 chars 38 lines -# Polarity negative negative -# - mode "1024x768-60" -# D: 65.00 MHz, H: 48.363 kHz, V: 60.00 Hz - geometry 1024 768 1024 768 32 timings 15385 160 24 29 3 136 6 endmode -# -# 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1024 768 -# Scan Frequency 60.023 kHz 75.03 Hz -# Sync Width 1.219 us 0.050 ms -# 12 chars 3 lines -# Front Porch 0.203 us 0.017 ms -# 2 chars 1 lines -# Back Porch 2.235 us 0.466 ms -# 22 chars 28 lines -# Active Time 13.003 us 12.795 ms -# 128 chars 768 lines -# Blank Time 3.657 us 0.533 ms -# 36 chars 32 lines -# Polarity positive positive -# - mode "1024x768-75" -# D: 78.75 MHz, H: 60.023 kHz, V: 75.03 Hz - geometry 1024 768 1024 768 32 - timings 12699 176 16 28 1 96 3 hsync high vsync high endmode -# -# 1024x768, 85 Hz, Non-Interlaced (94.50 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1024 768 -# Scan Frequency 68.677 kHz 85.00 Hz -# Sync Width 1.016 us 0.044 ms -# 12 chars 3 lines -# Front Porch 0.508 us 0.015 ms -# 6 chars 1 lines -# Back Porch 2.201 us 0.524 ms -# 26 chars 36 lines -# Active Time 10.836 us 11.183 ms -# 128 chars 768 lines -# Blank Time 3.725 us 0.582 ms -# 44 chars 40 lines -# Polarity positive positive -# - mode "1024x768-85" -# D: 94.50 MHz, H: 68.677 kHz, V: 85.00 Hz - geometry 1024 768 1024 768 32 - timings 10582 208 48 36 1 96 3 hsync high vsync high endmode -# -# 1024x768, 100 Hz, Non-Interlaced (110.0 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1024 768 -# Scan Frequency 79.023 kHz 99.78 Hz -# Sync Width 0.800 us 0.101 ms -# 11 chars 8 lines -# Front Porch 0.000 us 0.000 ms -# 0 chars 0 lines -# Back Porch 2.545 us 0.202 ms -# 35 chars 16 lines -# Active Time 9.309 us 9.719 ms -# 128 chars 768 lines -# Blank Time 3.345 us 0.304 ms -# 46 chars 24 lines -# Polarity negative negative -# - mode "1024x768-100" -# D: 113.3 MHz, H: 79.023 kHz, V: 99.78 Hz - geometry 1024 768 1024 768 32 - timings 8825 280 0 16 0 88 8 endmode mode "1152x720-60" -# D: 66.750 MHz, H: 44.859 kHz, V: 60.00 Hz - geometry 1152 720 1152 720 32 timings 14981 168 56 19 3 112 6 endmode -# -# 1152x864, 75 Hz, Non-Interlaced (110.0 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1152 864 -# Scan Frequency 75.137 kHz 74.99 Hz -# Sync Width 1.309 us 0.106 ms -# 18 chars 8 lines -# Front Porch 0.245 us 0.599 ms -# 3 chars 45 lines -# Back Porch 1.282 us 1.132 ms -# 18 chars 85 lines -# Active Time 10.473 us 11.499 ms -# 144 chars 864 lines -# Blank Time 2.836 us 1.837 ms -# 39 chars 138 lines -# Polarity positive positive -# - mode "1152x864-75" -# D: 110.0 MHz, H: 75.137 kHz, V: 74.99 Hz - geometry 1152 864 1152 864 32 - timings 9259 144 24 85 45 144 8 - hsync high vsync high endmode mode "1200x720-60" -# D: 70.184 MHz, H: 44.760 kHz, V: 60.00 Hz - geometry 1200 720 1200 720 32 - timings 14253 184 28 22 1 128 3 endmode mode "1280x600-60" -# D: 61.503 MHz, H: 37.320 kHz, V: 60.00 Hz - geometry 1280 600 1280 600 32 - timings 16260 184 28 18 1 128 3 endmode mode "1280x720-50" -# D: 60.466 MHz, H: 37.050 kHz, V: 50.00 Hz - geometry 1280 720 1280 720 32 - timings 16538 176 48 17 1 128 3 endmode mode "1280x768-50" -# D: 65.178 MHz, H: 39.550 kHz, V: 50.00 Hz - geometry 1280 768 1280 768 32 timings 15342 184 28 19 1 128 3 endmode -# -# 1280x768, 60 Hz, Non-Interlaced (80.136 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 768 -# Scan Frequency 47.700 kHz 60.00 Hz -# Sync Width 1.697 us 0.063 ms -# 17 chars 3 lines -# Front Porch 0.799 us 0.021 ms -# 8 chars 1 lines -# Back Porch 2.496 us 0.483 ms -# 25 chars 23 lines -# Active Time 15.973 us 16.101 ms -# 160 chars 768 lines -# Blank Time 4.992 us 0.566 ms -# 50 chars 27 lines -# Polarity positive positive -# - mode "1280x768-60" -# D: 80.13 MHz, H: 47.700 kHz, V: 60.00 Hz - geometry 1280 768 1280 768 32 - timings 12480 200 48 23 1 126 3 hsync high vsync high endmode -# -# 1280x800, 60 Hz, Non-Interlaced (83.375 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 800 -# Scan Frequency 49.628 kHz 60.00 Hz -# Sync Width 1.631 us 60.450 us -# 17 chars 3 lines -# Front Porch 0.768 us 20.15 us -# 8 chars 1 lines -# Back Porch 2.399 us 0.483 ms -# 25 chars 24 lines -# Active Time 15.352 us 16.120 ms -# 160 chars 800 lines -# Blank Time 4.798 us 0.564 ms -# 50 chars 28 lines -# Polarity negtive positive -# - mode "1280x800-60" -# D: 83.500 MHz, H: 49.702 kHz, V: 60.00 Hz - geometry 1280 800 1280 800 32 timings 11994 200 72 22 3 128 6 endmode -# -# 1280x960, 60 Hz, Non-Interlaced (108.00 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 960 -# Scan Frequency 60.000 kHz 60.00 Hz -# Sync Width 1.037 us 0.050 ms -# 14 chars 3 lines -# Front Porch 0.889 us 0.017 ms -# 12 chars 1 lines -# Back Porch 2.889 us 0.600 ms -# 39 chars 36 lines -# Active Time 11.852 us 16.000 ms -# 160 chars 960 lines -# Blank Time 4.815 us 0.667 ms -# 65 chars 40 lines -# Polarity positive positive -# - mode "1280x960-60" -# D: 108.00 MHz, H: 60.000 kHz, V: 60.00 Hz - geometry 1280 960 1280 960 32 - timings 9259 312 96 36 1 112 3 hsync high vsync high endmode -# -# 1280x1024, 60 Hz, Non-Interlaced (108.00 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 1024 -# Scan Frequency 63.981 kHz 60.02 Hz -# Sync Width 1.037 us 0.047 ms -# 14 chars 3 lines -# Front Porch 0.444 us 0.015 ms -# 6 chars 1 lines -# Back Porch 2.297 us 0.594 ms -# 31 chars 38 lines -# Active Time 11.852 us 16.005 ms -# 160 chars 1024 lines -# Blank Time 3.778 us 0.656 ms -# 51 chars 42 lines -# Polarity positive positive -# - mode "1280x1024-60" -# D: 108.00 MHz, H: 63.981 kHz, V: 60.02 Hz - geometry 1280 1024 1280 1024 32 - timings 9260 248 48 38 1 112 3 hsync high vsync high endmode -# -# 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 1024 -# Scan Frequency 79.976 kHz 75.02 Hz -# Sync Width 1.067 us 0.038 ms -# 18 chars 3 lines -# Front Porch 0.119 us 0.012 ms -# 2 chars 1 lines -# Back Porch 1.837 us 0.475 ms -# 31 chars 38 lines -# Active Time 9.481 us 12.804 ms -# 160 chars 1024 lines -# Blank Time 3.022 us 0.525 ms -# 51 chars 42 lines -# Polarity positive positive -# - mode "1280x1024-75" -# D: 135.00 MHz, H: 79.976 kHz, V: 75.02 Hz - geometry 1280 1024 1280 1024 32 - timings 7408 248 16 38 1 144 3 hsync high vsync high endmode -# -# 1280x1024, 85 Hz, Non-Interlaced (157.50 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 1024 -# Scan Frequency 91.146 kHz 85.02 Hz -# Sync Width 1.016 us 0.033 ms -# 20 chars 3 lines -# Front Porch 0.406 us 0.011 ms -# 8 chars 1 lines -# Back Porch 1.422 us 0.483 ms -# 28 chars 44 lines -# Active Time 8.127 us 11.235 ms -# 160 chars 1024 lines -# Blank Time 2.844 us 0.527 ms -# 56 chars 48 lines -# Polarity positive positive -# - mode "1280x1024-85" -# D: 157.50 MHz, H: 91.146 kHz, V: 85.02 Hz - geometry 1280 1024 1280 1024 32 - timings 6349 224 64 44 1 160 3 - hsync high vsync high endmode mode "1440x900-60" -# D: 106.500 MHz, H: 55.935 kHz, V: 60.00 Hz - geometry 1440 900 1440 900 32 - timings 9390 232 80 25 3 152 6 - hsync high vsync high endmode mode "1440x900-75" -# D: 136.750 MHz, H: 70.635 kHz, V: 75.00 Hz - geometry 1440 900 1440 900 32 - timings 7315 248 96 33 3 152 6 hsync high vsync high endmode -# -# 1440x1050, 60 Hz, Non-Interlaced (125.10 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1440 1050 -# Scan Frequency 65.220 kHz 60.00 Hz -# Sync Width 1.204 us 0.046 ms -# 19 chars 3 lines -# Front Porch 0.760 us 0.015 ms -# 12 chars 1 lines -# Back Porch 1.964 us 0.495 ms -# 31 chars 33 lines -# Active Time 11.405 us 16.099 ms -# 180 chars 1050 lines -# Blank Time 3.928 us 0.567 ms -# 62 chars 37 lines -# Polarity positive positive -# - mode "1440x1050-60" -# D: 125.10 MHz, H: 65.220 kHz, V: 60.00 Hz - geometry 1440 1050 1440 1050 32 - timings 7993 248 96 33 1 152 3 - hsync high vsync high endmode mode "1600x900-60" -# D: 118.250 MHz, H: 55.990 kHz, V: 60.00 Hz - geometry 1600 900 1600 900 32 - timings 8415 256 88 26 3 168 5 endmode mode "1600x1024-60" -# D: 136.358 MHz, H: 63.600 kHz, V: 60.00 Hz - geometry 1600 1024 1600 1024 32 timings 7315 272 104 32 1 168 3 endmode -# -# 1600x1200, 60 Hz, Non-Interlaced (156.00 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1600 1200 -# Scan Frequency 76.200 kHz 60.00 Hz -# Sync Width 1.026 us 0.105 ms -# 20 chars 8 lines -# Front Porch 0.205 us 0.131 ms -# 4 chars 10 lines -# Back Porch 1.636 us 0.682 ms -# 32 chars 52 lines -# Active Time 10.256 us 15.748 ms -# 200 chars 1200 lines -# Blank Time 2.872 us 0.866 ms -# 56 chars 66 lines -# Polarity negative negative -# - mode "1600x1200-60" -# D: 156.00 MHz, H: 76.200 kHz, V: 60.00 Hz - geometry 1600 1200 1600 1200 32 timings 6172 256 32 52 10 160 8 endmode -# -# 1600x1200, 75 Hz, Non-Interlaced (202.50 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1600 1200 -# Scan Frequency 93.750 kHz 75.00 Hz -# Sync Width 0.948 us 0.032 ms -# 24 chars 3 lines -# Front Porch 0.316 us 0.011 ms -# 8 chars 1 lines -# Back Porch 1.501 us 0.491 ms -# 38 chars 46 lines -# Active Time 7.901 us 12.800 ms -# 200 chars 1200 lines -# Blank Time 2.765 us 0.533 ms -# 70 chars 50 lines -# Polarity positive positive -# - mode "1600x1200-75" -# D: 202.50 MHz, H: 93.750 kHz, V: 75.00 Hz - geometry 1600 1200 1600 1200 32 - timings 4938 304 64 46 1 192 3 - hsync high vsync high endmode mode "1680x1050-60" -# D: 146.250 MHz, H: 65.290 kHz, V: 59.954 Hz - geometry 1680 1050 1680 1050 32 - timings 6814 280 104 30 3 176 6 - hsync high vsync high endmode mode "1680x1050-75" -# D: 187.000 MHz, H: 82.306 kHz, V: 74.892 Hz - geometry 1680 1050 1680 1050 32 - timings 5348 296 120 40 3 176 6 - hsync high vsync high endmode mode "1792x1344-60" -# D: 202.975 MHz, H: 83.460 kHz, V: 60.00 Hz - geometry 1792 1344 1792 1344 32 - timings 4902 320 128 43 1 192 3 - hsync high vsync high endmode mode "1856x1392-60" -# D: 218.571 MHz, H: 86.460 kHz, V: 60.00 Hz - geometry 1856 1392 1856 1392 32 - timings 4577 336 136 45 1 200 3 - hsync high vsync high endmode mode "1920x1200-60" -# D: 193.250 MHz, H: 74.556 kHz, V: 60.00 Hz - geometry 1920 1200 1920 1200 32 - timings 5173 336 136 36 3 200 6 - hsync high vsync high endmode mode "1920x1440-60" -# D: 234.000 MHz, H:90.000 kHz, V: 60.00 Hz - geometry 1920 1440 1920 1440 32 - timings 4274 344 128 56 1 208 3 - hsync high vsync high endmode mode "1920x1440-75" -# D: 297.000 MHz, H:112.500 kHz, V: 75.00 Hz - geometry 1920 1440 1920 1440 32 - timings 3367 352 144 56 1 224 3 - hsync high vsync high endmode mode "2048x1536-60" -# D: 267.250 MHz, H: 95.446 kHz, V: 60.00 Hz - geometry 2048 1536 2048 1536 32 - timings 3742 376 152 49 3 224 4 hsync high vsync high endmode -# -# 1280x720, 60 Hz, Non-Interlaced (74.481 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1280 720 -# Scan Frequency 44.760 kHz 60.00 Hz -# Sync Width 1.826 us 67.024 ms -# 17 chars 3 lines -# Front Porch 0.752 us 22.341 ms -# 7 chars 1 lines -# Back Porch 2.578 us 491.510 ms -# 24 chars 22 lines -# Active Time 17.186 us 16.086 ms -# 160 chars 720 lines -# Blank Time 5.156 us 0.581 ms -# 48 chars 26 lines -# Polarity negative negative -# - mode "1280x720-60" -# D: 74.481 MHz, H: 44.760 kHz, V: 60.00 Hz - geometry 1280 720 1280 720 32 timings 13426 192 64 22 1 136 3 endmode -# -# 1920x1080, 60 Hz, Non-Interlaced (172.798 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1920 1080 -# Scan Frequency 67.080 kHz 60.00 Hz -# Sync Width 1.204 us 44.723 ms -# 26 chars 3 lines -# Front Porch 0.694 us 14.908 ms -# 15 chars 1 lines -# Back Porch 1.898 us 506.857 ms -# 41 chars 34 lines -# Active Time 11.111 us 16.100 ms -# 240 chars 1080 lines -# Blank Time 3.796 us 0.566 ms -# 82 chars 38 lines -# Polarity negative negative -# - mode "1920x1080-60" -# D: 74.481 MHz, H: 67.080 kHz, V: 60.00 Hz - geometry 1920 1080 1920 1080 32 timings 5787 328 120 34 1 208 3 endmode -# -# 1400x1050, 60 Hz, Non-Interlaced (122.61 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1400 1050 -# Scan Frequency 65.218 kHz 59.99 Hz -# Sync Width 1.037 us 0.047 ms -# 19 chars 3 lines -# Front Porch 0.444 us 0.015 ms -# 11 chars 1 lines -# Back Porch 1.185 us 0.188 ms -# 30 chars 33 lines -# Active Time 12.963 us 16.411 ms -# 175 chars 1050 lines -# Blank Time 2.667 us 0.250 ms -# 60 chars 37 lines -# Polarity negative positive -# - mode "1400x1050-60" -# D: 122.750 MHz, H: 65.317 kHz, V: 59.99 Hz - geometry 1400 1050 1408 1050 32 - timings 8214 232 88 32 3 144 4 endmode mode "1400x1050-75" -# D: 156.000 MHz, H: 82.278 kHz, V: 74.867 Hz - geometry 1400 1050 1408 1050 32 timings 6410 248 104 42 3 144 4 endmode -# -# 1366x768, 60 Hz, Non-Interlaced (85.86 MHz dotclock) -# -# Horizontal Vertical -# Resolution 1366 768 -# Scan Frequency 47.700 kHz 60.00 Hz -# Sync Width 1.677 us 0.063 ms -# 18 chars 3 lines -# Front Porch 0.839 us 0.021 ms -# 9 chars 1 lines -# Back Porch 2.516 us 0.482 ms -# 27 chars 23 lines -# Active Time 15.933 us 16.101 ms -# 171 chars 768 lines -# Blank Time 5.031 us 0.566 ms -# 54 chars 27 lines -# Polarity negative positive -# - mode "1360x768-60" -# D: 84.750 MHz, H: 47.720 kHz, V: 60.00 Hz - geometry 1360 768 1360 768 32 - timings 11799 208 72 22 3 136 5 endmode mode "1366x768-60" -# D: 85.86 MHz, H: 47.700 kHz, V: 60.00 Hz - geometry 1366 768 1366 768 32 - timings 11647 216 72 23 1 144 3 endmode mode "1366x768-50" -# D: 69,924 MHz, H: 39.550 kHz, V: 50.00 Hz - geometry 1366 768 1366 768 32 timings 14301 200 56 19 1 144 3 endmode diff --git a/trunk/Documentation/fb/viafb.txt b/trunk/Documentation/fb/viafb.txt deleted file mode 100644 index 67dbf442b0b6..000000000000 --- a/trunk/Documentation/fb/viafb.txt +++ /dev/null @@ -1,214 +0,0 @@ - - VIA Integration Graphic Chip Console Framebuffer Driver - -[Platform] ------------------------ - The console framebuffer driver is for graphics chips of - VIA UniChrome Family(CLE266, PM800 / CN400 / CN300, - P4M800CE / P4M800Pro / CN700 / VN800, - CX700 / VX700, K8M890, P4M890, - CN896 / P4M900, VX800) - -[Driver features] ------------------------- - Device: CRT, LCD, DVI - - Support viafb_mode: - CRT: - 640x480(60, 75, 85, 100, 120 Hz), 720x480(60 Hz), - 720x576(60 Hz), 800x600(60, 75, 85, 100, 120 Hz), - 848x480(60 Hz), 856x480(60 Hz), 1024x512(60 Hz), - 1024x768(60, 75, 85, 100 Hz), 1152x864(75 Hz), - 1280x768(60 Hz), 1280x960(60 Hz), 1280x1024(60, 75, 85 Hz), - 1440x1050(60 Hz), 1600x1200(60, 75 Hz), 1280x720(60 Hz), - 1920x1080(60 Hz), 1400x1050(60 Hz), 800x480(60 Hz) - - color depth: 8 bpp, 16 bpp, 32 bpp supports. - - Support 2D hardware accelerator. - -[Using the viafb module] --- -- -------------------- - Start viafb with default settings: - #modprobe viafb - - Start viafb with with user options: - #modprobe viafb viafb_mode=800x600 viafb_bpp=16 viafb_refresh=60 - viafb_active_dev=CRT+DVI viafb_dvi_port=DVP1 - viafb_mode1=1024x768 viafb_bpp=16 viafb_refresh1=60 - viafb_SAMM_ON=1 - - viafb_mode: - 640x480 (default) - 720x480 - 800x600 - 1024x768 - ...... - - viafb_bpp: - 8, 16, 32 (default:32) - - viafb_refresh: - 60, 75, 85, 100, 120 (default:60) - - viafb_lcd_dsp_method: - 0 : expansion (default) - 1 : centering - - viafb_lcd_mode: - 0 : LCD panel with LSB data format input (default) - 1 : LCD panel with MSB data format input - - viafb_lcd_panel_id: - 0 : Resolution: 640x480, Channel: single, Dithering: Enable - 1 : Resolution: 800x600, Channel: single, Dithering: Enable - 2 : Resolution: 1024x768, Channel: single, Dithering: Enable (default) - 3 : Resolution: 1280x768, Channel: single, Dithering: Enable - 4 : Resolution: 1280x1024, Channel: dual, Dithering: Enable - 5 : Resolution: 1400x1050, Channel: dual, Dithering: Enable - 6 : Resolution: 1600x1200, Channel: dual, Dithering: Enable - - 8 : Resolution: 800x480, Channel: single, Dithering: Enable - 9 : Resolution: 1024x768, Channel: dual, Dithering: Enable - 10: Resolution: 1024x768, Channel: single, Dithering: Disable - 11: Resolution: 1024x768, Channel: dual, Dithering: Disable - 12: Resolution: 1280x768, Channel: single, Dithering: Disable - 13: Resolution: 1280x1024, Channel: dual, Dithering: Disable - 14: Resolution: 1400x1050, Channel: dual, Dithering: Disable - 15: Resolution: 1600x1200, Channel: dual, Dithering: Disable - 16: Resolution: 1366x768, Channel: single, Dithering: Disable - 17: Resolution: 1024x600, Channel: single, Dithering: Enable - 18: Resolution: 1280x768, Channel: dual, Dithering: Enable - 19: Resolution: 1280x800, Channel: single, Dithering: Enable - - viafb_accel: - 0 : No 2D Hardware Acceleration - 1 : 2D Hardware Acceleration (default) - - viafb_SAMM_ON: - 0 : viafb_SAMM_ON disable (default) - 1 : viafb_SAMM_ON enable - - viafb_mode1: (secondary display device) - 640x480 (default) - 720x480 - 800x600 - 1024x768 - ... ... - - viafb_bpp1: (secondary display device) - 8, 16, 32 (default:32) - - viafb_refresh1: (secondary display device) - 60, 75, 85, 100, 120 (default:60) - - viafb_active_dev: - This option is used to specify active devices.(CRT, DVI, CRT+LCD...) - DVI stands for DVI or HDMI, E.g., If you want to enable HDMI, - set viafb_active_dev=DVI. In SAMM case, the previous of - viafb_active_dev is primary device, and the following is - secondary device. - - For example: - To enable one device, such as DVI only, we can use: - modprobe viafb viafb_active_dev=DVI - To enable two devices, such as CRT+DVI: - modprobe viafb viafb_active_dev=CRT+DVI; - - For DuoView case, we can use: - modprobe viafb viafb_active_dev=CRT+DVI - OR - modprobe viafb viafb_active_dev=DVI+CRT... - - For SAMM case: - If CRT is primary and DVI is secondary, we should use: - modprobe viafb viafb_active_dev=CRT+DVI viafb_SAMM_ON=1... - If DVI is primary and CRT is secondary, we should use: - modprobe viafb viafb_active_dev=DVI+CRT viafb_SAMM_ON=1... - - viafb_display_hardware_layout: - This option is used to specify display hardware layout for CX700 chip. - 1 : LCD only - 2 : DVI only - 3 : LCD+DVI (default) - 4 : LCD1+LCD2 (internal + internal) - 16: LCD1+ExternalLCD2 (internal + external) - - viafb_second_size: - This option is used to set second device memory size(MB) in SAMM case. - The minimal size is 16. - - viafb_platform_epia_dvi: - This option is used to enable DVI on EPIA - M - 0 : No DVI on EPIA - M (default) - 1 : DVI on EPIA - M - - viafb_bus_width: - When using 24 - Bit Bus Width Digital Interface, - this option should be set. - 12: 12-Bit LVDS or 12-Bit TMDS (default) - 24: 24-Bit LVDS or 24-Bit TMDS - - viafb_device_lcd_dualedge: - When using Dual Edge Panel, this option should be set. - 0 : No Dual Edge Panel (default) - 1 : Dual Edge Panel - - viafb_video_dev: - This option is used to specify video output devices(CRT, DVI, LCD) for - duoview case. - For example: - To output video on DVI, we should use: - modprobe viafb viafb_video_dev=DVI... - - viafb_lcd_port: - This option is used to specify LCD output port, - available values are "DVP0" "DVP1" "DFP_HIGHLOW" "DFP_HIGH" "DFP_LOW". - for external LCD + external DVI on CX700(External LCD is on DVP0), - we should use: - modprobe viafb viafb_lcd_port=DVP0... - -Notes: - 1. CRT may not display properly for DuoView CRT & DVI display at - the "640x480" PAL mode with DVI overscan enabled. - 2. SAMM stands for single adapter multi monitors. It is different from - multi-head since SAMM support multi monitor at driver layers, thus fbcon - layer doesn't even know about it; SAMM's second screen doesn't have a - device node file, thus a user mode application can't access it directly. - When SAMM is enabled, viafb_mode and viafb_mode1, viafb_bpp and - viafb_bpp1, viafb_refresh and viafb_refresh1 can be different. - 3. When console is depending on viafbinfo1, dynamically change resolution - and bpp, need to call VIAFB specified ioctl interface VIAFB_SET_DEVICE - instead of calling common ioctl function FBIOPUT_VSCREENINFO since - viafb doesn't support multi-head well, or it will cause screen crush. - 4. VX800 2D accelerator hasn't been supported in this driver yet. When - using driver on VX800, the driver will disable the acceleration - function as default. - - -[Configure viafb with "fbset" tool] ------------------------------------ - "fbset" is an inbox utility of Linux. - 1. Inquire current viafb information, type, - # fbset -i - - 2. Set various resolutions and viafb_refresh rates, - # fbset - - example, - # fbset "1024x768-75" - or - # fbset -g 1024 768 1024 768 32 - Check the file "/etc/fb.modes" to find display modes available. - - 3. Set the color depth, - # fbset -depth - - example, - # fbset -depth 16 - -[Bootup with viafb]: --------------------- - Add the following line to your grub.conf: - append = "video=viafb:viafb_mode=1024x768,viafb_bpp=32,viafb_refresh=85" - diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index f5f812daf9f4..3d2d0c29f027 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -287,19 +287,11 @@ Who: Glauber Costa --------------------------- -What: remove HID compat support -When: 2.6.29 -Why: needed only as a temporary solution until distros fix themselves up -Who: Jiri Slaby - ---------------------------- - -What: print_fn_descriptor_symbol() -When: October 2009 -Why: The %pF vsprintf format provides the same functionality in a - simpler way. print_fn_descriptor_symbol() is deprecated but - still present to give out-of-tree modules time to change. -Who: Bjorn Helgaas +What: old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE) +When: 2.6.28 +Why: This driver still uses the old interface and has been replaced + by CONFIG_SERIAL_MCF. +Who: Sebastian Siewior --------------------------- diff --git a/trunk/Documentation/filesystems/autofs4-mount-control.txt b/trunk/Documentation/filesystems/autofs4-mount-control.txt deleted file mode 100644 index c6341745df37..000000000000 --- a/trunk/Documentation/filesystems/autofs4-mount-control.txt +++ /dev/null @@ -1,393 +0,0 @@ - -Miscellaneous Device control operations for the autofs4 kernel module -==================================================================== - -The problem -=========== - -There is a problem with active restarts in autofs (that is to say -restarting autofs when there are busy mounts). - -During normal operation autofs uses a file descriptor opened on the -directory that is being managed in order to be able to issue control -operations. Using a file descriptor gives ioctl operations access to -autofs specific information stored in the super block. The operations -are things such as setting an autofs mount catatonic, setting the -expire timeout and requesting expire checks. As is explained below, -certain types of autofs triggered mounts can end up covering an autofs -mount itself which prevents us being able to use open(2) to obtain a -file descriptor for these operations if we don't already have one open. - -Currently autofs uses "umount -l" (lazy umount) to clear active mounts -at restart. While using lazy umount works for most cases, anything that -needs to walk back up the mount tree to construct a path, such as -getcwd(2) and the proc file system /proc//cwd, no longer works -because the point from which the path is constructed has been detached -from the mount tree. - -The actual problem with autofs is that it can't reconnect to existing -mounts. Immediately one thinks of just adding the ability to remount -autofs file systems would solve it, but alas, that can't work. This is -because autofs direct mounts and the implementation of "on demand mount -and expire" of nested mount trees have the file system mounted directly -on top of the mount trigger directory dentry. - -For example, there are two types of automount maps, direct (in the kernel -module source you will see a third type called an offset, which is just -a direct mount in disguise) and indirect. - -Here is a master map with direct and indirect map entries: - -/- /etc/auto.direct -/test /etc/auto.indirect - -and the corresponding map files: - -/etc/auto.direct: - -/automount/dparse/g6 budgie:/autofs/export1 -/automount/dparse/g1 shark:/autofs/export1 -and so on. - -/etc/auto.indirect: - -g1 shark:/autofs/export1 -g6 budgie:/autofs/export1 -and so on. - -For the above indirect map an autofs file system is mounted on /test and -mounts are triggered for each sub-directory key by the inode lookup -operation. So we see a mount of shark:/autofs/export1 on /test/g1, for -example. - -The way that direct mounts are handled is by making an autofs mount on -each full path, such as /automount/dparse/g1, and using it as a mount -trigger. So when we walk on the path we mount shark:/autofs/export1 "on -top of this mount point". Since these are always directories we can -use the follow_link inode operation to trigger the mount. - -But, each entry in direct and indirect maps can have offsets (making -them multi-mount map entries). - -For example, an indirect mount map entry could also be: - -g1 \ - / shark:/autofs/export5/testing/test \ - /s1 shark:/autofs/export/testing/test/s1 \ - /s2 shark:/autofs/export5/testing/test/s2 \ - /s1/ss1 shark:/autofs/export1 \ - /s2/ss2 shark:/autofs/export2 - -and a similarly a direct mount map entry could also be: - -/automount/dparse/g1 \ - / shark:/autofs/export5/testing/test \ - /s1 shark:/autofs/export/testing/test/s1 \ - /s2 shark:/autofs/export5/testing/test/s2 \ - /s1/ss1 shark:/autofs/export2 \ - /s2/ss2 shark:/autofs/export2 - -One of the issues with version 4 of autofs was that, when mounting an -entry with a large number of offsets, possibly with nesting, we needed -to mount and umount all of the offsets as a single unit. Not really a -problem, except for people with a large number of offsets in map entries. -This mechanism is used for the well known "hosts" map and we have seen -cases (in 2.4) where the available number of mounts are exhausted or -where the number of privileged ports available is exhausted. - -In version 5 we mount only as we go down the tree of offsets and -similarly for expiring them which resolves the above problem. There is -somewhat more detail to the implementation but it isn't needed for the -sake of the problem explanation. The one important detail is that these -offsets are implemented using the same mechanism as the direct mounts -above and so the mount points can be covered by a mount. - -The current autofs implementation uses an ioctl file descriptor opened -on the mount point for control operations. The references held by the -descriptor are accounted for in checks made to determine if a mount is -in use and is also used to access autofs file system information held -in the mount super block. So the use of a file handle needs to be -retained. - - -The Solution -============ - -To be able to restart autofs leaving existing direct, indirect and -offset mounts in place we need to be able to obtain a file handle -for these potentially covered autofs mount points. Rather than just -implement an isolated operation it was decided to re-implement the -existing ioctl interface and add new operations to provide this -functionality. - -In addition, to be able to reconstruct a mount tree that has busy mounts, -the uid and gid of the last user that triggered the mount needs to be -available because these can be used as macro substitution variables in -autofs maps. They are recorded at mount request time and an operation -has been added to retrieve them. - -Since we're re-implementing the control interface, a couple of other -problems with the existing interface have been addressed. First, when -a mount or expire operation completes a status is returned to the -kernel by either a "send ready" or a "send fail" operation. The -"send fail" operation of the ioctl interface could only ever send -ENOENT so the re-implementation allows user space to send an actual -status. Another expensive operation in user space, for those using -very large maps, is discovering if a mount is present. Usually this -involves scanning /proc/mounts and since it needs to be done quite -often it can introduce significant overhead when there are many entries -in the mount table. An operation to lookup the mount status of a mount -point dentry (covered or not) has also been added. - -Current kernel development policy recommends avoiding the use of the -ioctl mechanism in favor of systems such as Netlink. An implementation -using this system was attempted to evaluate its suitability and it was -found to be inadequate, in this case. The Generic Netlink system was -used for this as raw Netlink would lead to a significant increase in -complexity. There's no question that the Generic Netlink system is an -elegant solution for common case ioctl functions but it's not a complete -replacement probably because it's primary purpose in life is to be a -message bus implementation rather than specifically an ioctl replacement. -While it would be possible to work around this there is one concern -that lead to the decision to not use it. This is that the autofs -expire in the daemon has become far to complex because umount -candidates are enumerated, almost for no other reason than to "count" -the number of times to call the expire ioctl. This involves scanning -the mount table which has proved to be a big overhead for users with -large maps. The best way to improve this is try and get back to the -way the expire was done long ago. That is, when an expire request is -issued for a mount (file handle) we should continually call back to -the daemon until we can't umount any more mounts, then return the -appropriate status to the daemon. At the moment we just expire one -mount at a time. A Generic Netlink implementation would exclude this -possibility for future development due to the requirements of the -message bus architecture. - - -autofs4 Miscellaneous Device mount control interface -==================================================== - -The control interface is opening a device node, typically /dev/autofs. - -All the ioctls use a common structure to pass the needed parameter -information and return operation results: - -struct autofs_dev_ioctl { - __u32 ver_major; - __u32 ver_minor; - __u32 size; /* total size of data passed in - * including this struct */ - __s32 ioctlfd; /* automount command fd */ - - __u32 arg1; /* Command parameters */ - __u32 arg2; - - char path[0]; -}; - -The ioctlfd field is a mount point file descriptor of an autofs mount -point. It is returned by the open call and is used by all calls except -the check for whether a given path is a mount point, where it may -optionally be used to check a specific mount corresponding to a given -mount point file descriptor, and when requesting the uid and gid of the -last successful mount on a directory within the autofs file system. - -The fields arg1 and arg2 are used to communicate parameters and results of -calls made as described below. - -The path field is used to pass a path where it is needed and the size field -is used account for the increased structure length when translating the -structure sent from user space. - -This structure can be initialized before setting specific fields by using -the void function call init_autofs_dev_ioctl(struct autofs_dev_ioctl *). - -All of the ioctls perform a copy of this structure from user space to -kernel space and return -EINVAL if the size parameter is smaller than -the structure size itself, -ENOMEM if the kernel memory allocation fails -or -EFAULT if the copy itself fails. Other checks include a version check -of the compiled in user space version against the module version and a -mismatch results in a -EINVAL return. If the size field is greater than -the structure size then a path is assumed to be present and is checked to -ensure it begins with a "/" and is NULL terminated, otherwise -EINVAL is -returned. Following these checks, for all ioctl commands except -AUTOFS_DEV_IOCTL_VERSION_CMD, AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and -AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD the ioctlfd is validated and if it is -not a valid descriptor or doesn't correspond to an autofs mount point -an error of -EBADF, -ENOTTY or -EINVAL (not an autofs descriptor) is -returned. - - -The ioctls -========== - -An example of an implementation which uses this interface can be seen -in autofs version 5.0.4 and later in file lib/dev-ioctl-lib.c of the -distribution tar available for download from kernel.org in directory -/pub/linux/daemons/autofs/v5. - -The device node ioctl operations implemented by this interface are: - - -AUTOFS_DEV_IOCTL_VERSION ------------------------- - -Get the major and minor version of the autofs4 device ioctl kernel module -implementation. It requires an initialized struct autofs_dev_ioctl as an -input parameter and sets the version information in the passed in structure. -It returns 0 on success or the error -EINVAL if a version mismatch is -detected. - - -AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD ------------------------------------------------------------------- - -Get the major and minor version of the autofs4 protocol version understood -by loaded module. This call requires an initialized struct autofs_dev_ioctl -with the ioctlfd field set to a valid autofs mount point descriptor -and sets the requested version number in structure field arg1. These -commands return 0 on success or one of the negative error codes if -validation fails. - - -AUTOFS_DEV_IOCTL_OPENMOUNT and AUTOFS_DEV_IOCTL_CLOSEMOUNT ----------------------------------------------------------- - -Obtain and release a file descriptor for an autofs managed mount point -path. The open call requires an initialized struct autofs_dev_ioctl with -the the path field set and the size field adjusted appropriately as well -as the arg1 field set to the device number of the autofs mount. The -device number can be obtained from the mount options shown in -/proc/mounts. The close call requires an initialized struct -autofs_dev_ioct with the ioctlfd field set to the descriptor obtained -from the open call. The release of the file descriptor can also be done -with close(2) so any open descriptors will also be closed at process exit. -The close call is included in the implemented operations largely for -completeness and to provide for a consistent user space implementation. - - -AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCTL_FAIL_CMD --------------------------------------------------------- - -Return mount and expire result status from user space to the kernel. -Both of these calls require an initialized struct autofs_dev_ioctl -with the ioctlfd field set to the descriptor obtained from the open -call and the arg1 field set to the wait queue token number, received -by user space in the foregoing mount or expire request. The arg2 field -is set to the status to be returned. For the ready call this is always -0 and for the fail call it is set to the errno of the operation. - - -AUTOFS_DEV_IOCTL_SETPIPEFD_CMD ------------------------------- - -Set the pipe file descriptor used for kernel communication to the daemon. -Normally this is set at mount time using an option but when reconnecting -to a existing mount we need to use this to tell the autofs mount about -the new kernel pipe descriptor. In order to protect mounts against -incorrectly setting the pipe descriptor we also require that the autofs -mount be catatonic (see next call). - -The call requires an initialized struct autofs_dev_ioctl with the -ioctlfd field set to the descriptor obtained from the open call and -the arg1 field set to descriptor of the pipe. On success the call -also sets the process group id used to identify the controlling process -(eg. the owning automount(8) daemon) to the process group of the caller. - - -AUTOFS_DEV_IOCTL_CATATONIC_CMD ------------------------------- - -Make the autofs mount point catatonic. The autofs mount will no longer -issue mount requests, the kernel communication pipe descriptor is released -and any remaining waits in the queue released. - -The call requires an initialized struct autofs_dev_ioctl with the -ioctlfd field set to the descriptor obtained from the open call. - - -AUTOFS_DEV_IOCTL_TIMEOUT_CMD ----------------------------- - -Set the expire timeout for mounts withing an autofs mount point. - -The call requires an initialized struct autofs_dev_ioctl with the -ioctlfd field set to the descriptor obtained from the open call. - - -AUTOFS_DEV_IOCTL_REQUESTER_CMD ------------------------------- - -Return the uid and gid of the last process to successfully trigger a the -mount on the given path dentry. - -The call requires an initialized struct autofs_dev_ioctl with the path -field set to the mount point in question and the size field adjusted -appropriately as well as the arg1 field set to the device number of the -containing autofs mount. Upon return the struct field arg1 contains the -uid and arg2 the gid. - -When reconstructing an autofs mount tree with active mounts we need to -re-connect to mounts that may have used the original process uid and -gid (or string variations of them) for mount lookups within the map entry. -This call provides the ability to obtain this uid and gid so they may be -used by user space for the mount map lookups. - - -AUTOFS_DEV_IOCTL_EXPIRE_CMD ---------------------------- - -Issue an expire request to the kernel for an autofs mount. Typically -this ioctl is called until no further expire candidates are found. - -The call requires an initialized struct autofs_dev_ioctl with the -ioctlfd field set to the descriptor obtained from the open call. In -addition an immediate expire, independent of the mount timeout, can be -requested by setting the arg1 field to 1. If no expire candidates can -be found the ioctl returns -1 with errno set to EAGAIN. - -This call causes the kernel module to check the mount corresponding -to the given ioctlfd for mounts that can be expired, issues an expire -request back to the daemon and waits for completion. - -AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD ------------------------------- - -Checks if an autofs mount point is in use. - -The call requires an initialized struct autofs_dev_ioctl with the -ioctlfd field set to the descriptor obtained from the open call and -it returns the result in the arg1 field, 1 for busy and 0 otherwise. - - -AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD ---------------------------------- - -Check if the given path is a mountpoint. - -The call requires an initialized struct autofs_dev_ioctl. There are two -possible variations. Both use the path field set to the path of the mount -point to check and the size field adjusted appropriately. One uses the -ioctlfd field to identify a specific mount point to check while the other -variation uses the path and optionaly arg1 set to an autofs mount type. -The call returns 1 if this is a mount point and sets arg1 to the device -number of the mount and field arg2 to the relevant super block magic -number (described below) or 0 if it isn't a mountpoint. In both cases -the the device number (as returned by new_encode_dev()) is returned -in field arg1. - -If supplied with a file descriptor we're looking for a specific mount, -not necessarily at the top of the mounted stack. In this case the path -the descriptor corresponds to is considered a mountpoint if it is itself -a mountpoint or contains a mount, such as a multi-mount without a root -mount. In this case we return 1 if the descriptor corresponds to a mount -point and and also returns the super magic of the covering mount if there -is one or 0 if it isn't a mountpoint. - -If a path is supplied (and the ioctlfd field is set to -1) then the path -is looked up and is checked to see if it is the root of a mount. If a -type is also given we are looking for a particular autofs mount and if -a match isn't found a fail is returned. If the the located path is the -root of a mount 1 is returned along with the super magic of the mount -or 0 otherwise. - diff --git a/trunk/Documentation/filesystems/ext3.txt b/trunk/Documentation/filesystems/ext3.txt index 295f26cd895a..b45f3c1b8b43 100644 --- a/trunk/Documentation/filesystems/ext3.txt +++ b/trunk/Documentation/filesystems/ext3.txt @@ -193,5 +193,6 @@ kernel source: programs: http://e2fsprogs.sourceforge.net/ http://ext2resize.sourceforge.net -useful links: http://www-106.ibm.com/developerworks/linux/library/l-fs7/ +useful links: http://www.zip.com.au/~akpm/linux/ext3/ext3-usage.html + http://www-106.ibm.com/developerworks/linux/library/l-fs7/ http://www-106.ibm.com/developerworks/linux/library/l-fs8/ diff --git a/trunk/Documentation/filesystems/nfsroot.txt b/trunk/Documentation/filesystems/nfsroot.txt index 68baddf3c3e0..31b329172343 100644 --- a/trunk/Documentation/filesystems/nfsroot.txt +++ b/trunk/Documentation/filesystems/nfsroot.txt @@ -169,7 +169,7 @@ They depend on various facilities being available: 3.1) Booting from a floppy using syslinux When building kernels, an easy way to create a boot floppy that uses - syslinux is to use the zdisk or bzdisk make targets which use zimage + syslinux is to use the zdisk or bzdisk make targets which use and bzimage images respectively. Both targets accept the FDARGS parameter which can be used to set the kernel command line. diff --git a/trunk/Documentation/filesystems/ocfs2.txt b/trunk/Documentation/filesystems/ocfs2.txt index 4340cc825796..c318a8bbb1ef 100644 --- a/trunk/Documentation/filesystems/ocfs2.txt +++ b/trunk/Documentation/filesystems/ocfs2.txt @@ -76,9 +76,3 @@ localalloc=8(*) Allows custom localalloc size in MB. If the value is too large, the fs will silently revert it to the default. Localalloc is not enabled for local mounts. localflocks This disables cluster aware flock. -inode64 Indicates that Ocfs2 is allowed to create inodes at - any location in the filesystem, including those which - will result in inode numbers occupying more than 32 - bits of significance. -user_xattr (*) Enables Extended User Attributes. -nouser_xattr Disables Extended User Attributes. diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index c032bf39e8b9..d831d24d2a6c 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -1321,18 +1321,6 @@ debugging information is displayed on console. NMI switch that most IA32 servers have fires unknown NMI up, for example. If a system hangs up, try pressing the NMI switch. -panic_on_unrecovered_nmi ------------------------- - -The default Linux behaviour on an NMI of either memory or unknown is to continue -operation. For many environments such as scientific computing it is preferable -that the box is taken out and the error dealt with than an uncorrected -parity/ECC error get propogated. - -A small number of systems do generate NMI's for bizarre random reasons such as -power management so the default is off. That sysctl works like the existing -panic controls already in that directory. - nmi_watchdog ------------ @@ -1343,6 +1331,13 @@ determine whether or not they are still functioning properly. Because the NMI watchdog shares registers with oprofile, by disabling the NMI watchdog, oprofile may have more registers to utilize. +maps_protect +------------ + +Enables/Disables the protection of the per-process proc entries "maps" and +"smaps". When enabled, the contents of these files are visible only to +readers that are allowed to ptrace() the given process. + msgmni ------ diff --git a/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt index 62fe9b1e0890..7be232b44ee4 100644 --- a/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt +++ b/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt @@ -263,7 +263,7 @@ User Mode Linux, like so: sleep(999999999); } EOF - gcc -static hello.c -o init + gcc -static hello2.c -o init echo init | cpio -o -H newc | gzip > test.cpio.gz # Testing external initramfs using the initrd loading mechanism. qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt index b1b988701247..18022e249c53 100644 --- a/trunk/Documentation/gpio.txt +++ b/trunk/Documentation/gpio.txt @@ -240,10 +240,6 @@ signal, or (b) something wrongly believes it's safe to remove drivers needed to manage a signal that's in active use. That is, requesting a GPIO can serve as a kind of lock. -Some platforms may also use knowledge about what GPIOs are active for -power management, such as by powering down unused chip sectors and, more -easily, gating off unused clocks. - These two calls are optional because not not all current Linux platforms offer such functionality in their GPIO support; a valid implementation could return success for all gpio_request() calls. Unlike the other calls, @@ -268,7 +264,7 @@ map between them using calls like: /* map GPIO numbers to IRQ numbers */ int gpio_to_irq(unsigned gpio); - /* map IRQ numbers to GPIO numbers (avoid using this) */ + /* map IRQ numbers to GPIO numbers */ int irq_to_gpio(unsigned irq); Those return either the corresponding number in the other namespace, or @@ -288,8 +284,7 @@ system wakeup capabilities. Non-error values returned from irq_to_gpio() would most commonly be used with gpio_get_value(), for example to initialize or update driver state -when the IRQ is edge-triggered. Note that some platforms don't support -this reverse mapping, so you should avoid using it. +when the IRQ is edge-triggered. Emulating Open Drain Signals diff --git a/trunk/Documentation/timers/hpet.txt b/trunk/Documentation/hpet.txt similarity index 81% rename from trunk/Documentation/timers/hpet.txt rename to trunk/Documentation/hpet.txt index e7c09abcfab4..6ad52d9dad6c 100644 --- a/trunk/Documentation/timers/hpet.txt +++ b/trunk/Documentation/hpet.txt @@ -1,32 +1,21 @@ High Precision Event Timer Driver for Linux -The High Precision Event Timer (HPET) hardware follows a specification -by Intel and Microsoft which can be found at - - http://www.intel.com/technology/architecture/hpetspec.htm - -Each HPET has one fixed-rate counter (at 10+ MHz, hence "High Precision") -and up to 32 comparators. Normally three or more comparators are provided, -each of which can generate oneshot interupts and at least one of which has -additional hardware to support periodic interrupts. The comparators are -also called "timers", which can be misleading since usually timers are -independent of each other ... these share a counter, complicating resets. - -HPET devices can support two interrupt routing modes. In one mode, the -comparators are additional interrupt sources with no particular system -role. Many x86 BIOS writers don't route HPET interrupts at all, which -prevents use of that mode. They support the other "legacy replacement" -mode where the first two comparators block interrupts from 8254 timers -and from the RTC. +The High Precision Event Timer (HPET) hardware is the future replacement +for the 8254 and Real Time Clock (RTC) periodic timer functionality. +Each HPET can have up to 32 timers. It is possible to configure the +first two timers as legacy replacements for 8254 and RTC periodic timers. +A specification done by Intel and Microsoft can be found at +. The driver supports detection of HPET driver allocation and initialization of the HPET before the driver module_init routine is called. This enables platform code which uses timer 0 or 1 as the main timer to intercept HPET initialization. An example of this initialization can be found in -arch/x86/kernel/hpet.c. +arch/i386/kernel/time_hpet.c. -The driver provides a userspace API which resembles the API found in the -RTC driver framework. An example user space program is provided below. +The driver provides two APIs which are very similar to the API found in +the rtc.c driver. There is a user space API and a kernel space API. +An example user space program is provided below. #include #include @@ -297,3 +286,15 @@ out: return; } + +The kernel API has three interfaces exported from the driver: + + hpet_register(struct hpet_task *tp, int periodic) + hpet_unregister(struct hpet_task *tp) + hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg) + +The kernel module using this interface fills in the ht_func and ht_data +members of the hpet_task structure before calling hpet_register. +hpet_control simply vectors to the hpet_ioctl routine and has the same +commands and respective arguments as the user API. hpet_unregister +is used to terminate usage of the HPET timer reserved by hpet_register. diff --git a/trunk/Documentation/i2c/busses/i2c-viapro b/trunk/Documentation/i2c/busses/i2c-viapro index 22efedf60c87..1405fb69984c 100644 --- a/trunk/Documentation/i2c/busses/i2c-viapro +++ b/trunk/Documentation/i2c/busses/i2c-viapro @@ -16,9 +16,6 @@ Supported adapters: * VIA Technologies, Inc. CX700 Datasheet: available on request and under NDA from VIA - * VIA Technologies, Inc. VX800/VX820 - Datasheet: available on http://linux.via.com.tw - Authors: Kyösti Mälkki , Mark D. Studebaker , @@ -52,7 +49,6 @@ Your lspci -n listing must show one of these : device 1106:3372 (VT8237S) device 1106:3287 (VT8251) device 1106:8324 (CX700) - device 1106:8353 (VX800/VX820) If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. @@ -61,5 +57,5 @@ Except for the oldest chips (VT82C596A/B, VT82C686A and most probably VT8231), this driver supports I2C block transactions. Such transactions are mainly useful to read from and write to EEPROMs. -The CX700/VX800/VX820 additionally appears to support SMBus PEC, although -this driver doesn't implement it yet. +The CX700 additionally appears to support SMBus PEC, although this driver +doesn't implement it yet. diff --git a/trunk/Documentation/i2c/dev-interface b/trunk/Documentation/i2c/dev-interface index 3e742ba25536..9dd79123ddd9 100644 --- a/trunk/Documentation/i2c/dev-interface +++ b/trunk/Documentation/i2c/dev-interface @@ -4,10 +4,6 @@ the /dev interface. You need to load module i2c-dev for this. Each registered i2c adapter gets a number, counting from 0. You can examine /sys/class/i2c-dev/ to see what number corresponds to which adapter. -Alternatively, you can run "i2cdetect -l" to obtain a formated list of all -i2c adapters present on your system at a given time. i2cdetect is part of -the i2c-tools package. - I2C device files are character device files with major device number 89 and a minor device number corresponding to the number assigned as explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., @@ -21,34 +17,30 @@ So let's say you want to access an i2c adapter from a C program. The first thing to do is "#include ". Please note that there are two files named "i2c-dev.h" out there, one is distributed with the Linux kernel and is meant to be included from kernel -driver code, the other one is distributed with i2c-tools and is +driver code, the other one is distributed with lm_sensors and is meant to be included from user-space programs. You obviously want the second one here. Now, you have to decide which adapter you want to access. You should -inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this. -Adapter numbers are assigned somewhat dynamically, so you can not -assume much about them. They can even change from one boot to the next. +inspect /sys/class/i2c-dev/ to decide this. Adapter numbers are assigned +somewhat dynamically, so you can not even assume /dev/i2c-0 is the +first adapter. Next thing, open the device file, as follows: - int file; int adapter_nr = 2; /* probably dynamically determined */ char filename[20]; - snprintf(filename, 19, "/dev/i2c-%d", adapter_nr); - file = open(filename, O_RDWR); - if (file < 0) { + sprintf(filename,"/dev/i2c-%d",adapter_nr); + if ((file = open(filename,O_RDWR)) < 0) { /* ERROR HANDLING; you can check errno to see what went wrong */ exit(1); } When you have opened the device, you must specify with what device address you want to communicate: - int addr = 0x40; /* The I2C address */ - - if (ioctl(file, I2C_SLAVE, addr) < 0) { + if (ioctl(file,I2C_SLAVE,addr) < 0) { /* ERROR HANDLING; you can check errno to see what went wrong */ exit(1); } @@ -56,41 +48,31 @@ address you want to communicate: Well, you are all set up now. You can now use SMBus commands or plain I2C to communicate with your device. SMBus commands are preferred if the device supports them. Both are illustrated below. - __u8 register = 0x10; /* Device register to access */ __s32 res; char buf[10]; - /* Using SMBus commands */ - res = i2c_smbus_read_word_data(file, register); + res = i2c_smbus_read_word_data(file,register); if (res < 0) { /* ERROR HANDLING: i2c transaction failed */ } else { /* res contains the read word */ } - /* Using I2C Write, equivalent of - i2c_smbus_write_word_data(file, register, 0x6543) */ + i2c_smbus_write_word_data(file,register,0x6543) */ buf[0] = register; buf[1] = 0x43; buf[2] = 0x65; - if (write(file, buf, 3) ! =3) { + if ( write(file,buf,3) != 3) { /* ERROR HANDLING: i2c transaction failed */ } - /* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */ - if (read(file, buf, 1) != 1) { + if (read(file,buf,1) != 1) { /* ERROR HANDLING: i2c transaction failed */ } else { /* buf[0] contains the read byte */ } -Note that only a subset of the I2C and SMBus protocols can be achieved by -the means of read() and write() calls. In particular, so-called combined -transactions (mixing read and write messages in the same transaction) -aren't supported. For this reason, this interface is almost never used by -user-space programs. - IMPORTANT: because of the use of inline functions, you *have* to use '-O' or some variation when you compile your program! @@ -98,29 +80,31 @@ IMPORTANT: because of the use of inline functions, you *have* to use Full interface description ========================== -The following IOCTLs are defined: +The following IOCTLs are defined and fully supported +(see also i2c-dev.h): -ioctl(file, I2C_SLAVE, long addr) +ioctl(file,I2C_SLAVE,long addr) Change slave address. The address is passed in the 7 lower bits of the argument (except for 10 bit addresses, passed in the 10 lower bits in this case). -ioctl(file, I2C_TENBIT, long select) +ioctl(file,I2C_TENBIT,long select) Selects ten bit addresses if select not equals 0, selects normal 7 bit addresses if select equals 0. Default 0. This request is only valid if the adapter has I2C_FUNC_10BIT_ADDR. -ioctl(file, I2C_PEC, long select) +ioctl(file,I2C_PEC,long select) Selects SMBus PEC (packet error checking) generation and verification if select not equals 0, disables if select equals 0. Default 0. Used only for SMBus transactions. This request only has an effect if the the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just doesn't have any effect. -ioctl(file, I2C_FUNCS, unsigned long *funcs) +ioctl(file,I2C_FUNCS,unsigned long *funcs) Gets the adapter functionality and puts it in *funcs. -ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset) +ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset) + Do combined read/write transaction without stop in between. Only valid if the adapter has I2C_FUNC_I2C. The argument is a pointer to a @@ -136,9 +120,10 @@ ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset) The slave address and whether to use ten bit address mode has to be set in each message, overriding the values set with the above ioctl's. -ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args) - Not meant to be called directly; instead, use the access functions - below. + +Other values are NOT supported at this moment, except for I2C_SMBUS, +which you should never directly call; instead, use the access functions +below. You can do plain i2c transactions by using read(2) and write(2) calls. You do not need to pass the address byte; instead, set it through @@ -163,52 +148,7 @@ what happened. The 'write' transactions return 0 on success; the returns the number of values read. The block buffers need not be longer than 32 bytes. -The above functions are all inline functions, that resolve to calls to -the i2c_smbus_access function, that on its turn calls a specific ioctl +The above functions are all macros, that resolve to calls to the +i2c_smbus_access function, that on its turn calls a specific ioctl with the data in a specific format. Read the source code if you want to know what happens behind the screens. - - -Implementation details -====================== - -For the interested, here's the code flow which happens inside the kernel -when you use the /dev interface to I2C: - -1* Your program opens /dev/i2c-N and calls ioctl() on it, as described in -section "C example" above. - -2* These open() and ioctl() calls are handled by the i2c-dev kernel -driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(), -respectively. You can think of i2c-dev as a generic I2C chip driver -that can be programmed from user-space. - -3* Some ioctl() calls are for administrative tasks and are handled by -i2c-dev directly. Examples include I2C_SLAVE (set the address of the -device you want to access) and I2C_PEC (enable or disable SMBus error -checking on future transactions.) - -4* Other ioctl() calls are converted to in-kernel function calls by -i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter -functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which -performs an SMBus transaction using i2c-core.c:i2c_smbus_xfer(). - -The i2c-dev driver is responsible for checking all the parameters that -come from user-space for validity. After this point, there is no -difference between these calls that came from user-space through i2c-dev -and calls that would have been performed by kernel I2C chip drivers -directly. This means that I2C bus drivers don't need to implement -anything special to support access from user-space. - -5* These i2c-core.c/i2c.h functions are wrappers to the actual -implementation of your I2C bus driver. Each adapter must declare -callback functions implementing these standard calls. -i2c.h:i2c_get_functionality() calls i2c_adapter.algo->functionality(), -while i2c-core.c:i2c_smbus_xfer() calls either -adapter.algo->smbus_xfer() if it is implemented, or if not, -i2c-core.c:i2c_smbus_xfer_emulated() which in turn calls -i2c_adapter.algo->master_xfer(). - -After your I2C bus driver has processed these requests, execution runs -up the call chain, with almost no processing done, except by i2c-dev to -package the returned data, if any, in suitable format for the ioctl. diff --git a/trunk/Documentation/i2c/smbus-protocol b/trunk/Documentation/i2c/smbus-protocol index 9df47441f0e7..24bfb65da17d 100644 --- a/trunk/Documentation/i2c/smbus-protocol +++ b/trunk/Documentation/i2c/smbus-protocol @@ -109,8 +109,8 @@ specified through the Comm byte. S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P -SMBus Process Call: i2c_smbus_process_call() -============================================= +SMBus Process Call +================== This command selects a device register (through the Comm byte), sends 16 bits of data to it, and reads 16 bits of data in return. diff --git a/trunk/Documentation/i2c/writing-clients b/trunk/Documentation/i2c/writing-clients index d73ee117a8ca..6b61b3a2e90b 100644 --- a/trunk/Documentation/i2c/writing-clients +++ b/trunk/Documentation/i2c/writing-clients @@ -606,8 +606,6 @@ SMBus communication extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); extern s32 i2c_smbus_write_word_data(struct i2c_client * client, u8 command, u16 value); - extern s32 i2c_smbus_process_call(struct i2c_client *client, - u8 command, u16 value); extern s32 i2c_smbus_read_block_data(struct i2c_client * client, u8 command, u8 *values); extern s32 i2c_smbus_write_block_data(struct i2c_client * client, @@ -623,6 +621,8 @@ These ones were removed from i2c-core because they had no users, but could be added back later if needed: extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value); + extern s32 i2c_smbus_process_call(struct i2c_client * client, + u8 command, u16 value); extern s32 i2c_smbus_block_process_call(struct i2c_client *client, u8 command, u8 length, u8 *values) diff --git a/trunk/Documentation/ia64/kvm.txt b/trunk/Documentation/ia64/kvm.txt index 84f7cb3d5bec..914d07f49268 100644 --- a/trunk/Documentation/ia64/kvm.txt +++ b/trunk/Documentation/ia64/kvm.txt @@ -1,8 +1,7 @@ -Currently, kvm module is in EXPERIMENTAL stage on IA64. This means that -interfaces are not stable enough to use. So, please don't run critical -applications in virtual machine. -We will try our best to improve it in future versions! - +Currently, kvm module in EXPERIMENTAL stage on IA64. This means that +interfaces are not stable enough to use. So, plase had better don't run +critical applications in virtual machine. We will try our best to make it +strong in future versions! Guide: How to boot up guests on kvm/ia64 This guide is to describe how to enable kvm support for IA-64 systems. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index dd28a0d56981..2443f5bb4364 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -796,7 +796,6 @@ and is between 256 and 4096 characters. It is defined in the file Defaults to the default architecture's huge page size if not specified. - i8042.debug [HW] Toggle i8042 debug mode i8042.direct [HW] Put keyboard port into non-translated mode i8042.dumbkbd [HW] Pretend that controller can only read data from keyboard and cannot control its state @@ -1714,11 +1713,6 @@ and is between 256 and 4096 characters. It is defined in the file autoconfiguration. Ranges are in pairs (memory base and size). - dynamic_printk - Enables pr_debug()/dev_dbg() calls if - CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also - be switched on/off via /dynamic_printk/modules - print-fatal-signals= [KNL] debug: print fatal signals print-fatal-signals=1: print segfault info to diff --git a/trunk/Documentation/kobject.txt b/trunk/Documentation/kobject.txt index f5d2aad65a67..51a8021ee532 100644 --- a/trunk/Documentation/kobject.txt +++ b/trunk/Documentation/kobject.txt @@ -118,10 +118,6 @@ the name of the kobject, call kobject_rename(): int kobject_rename(struct kobject *kobj, const char *new_name); -Note kobject_rename does perform any locking or have a solid notion of -what names are valid so the provide must provide their own sanity checking -and serialization. - There is a function called kobject_set_name() but that is legacy cruft and is being removed. If your code needs to call this function, it is incorrect and needs to be fixed. diff --git a/trunk/Documentation/laptops/disk-shock-protection.txt b/trunk/Documentation/laptops/disk-shock-protection.txt deleted file mode 100644 index 0e6ba2663834..000000000000 --- a/trunk/Documentation/laptops/disk-shock-protection.txt +++ /dev/null @@ -1,149 +0,0 @@ -Hard disk shock protection -========================== - -Author: Elias Oltmanns -Last modified: 2008-10-03 - - -0. Contents ------------ - -1. Intro -2. The interface -3. References -4. CREDITS - - -1. Intro --------- - -ATA/ATAPI-7 specifies the IDLE IMMEDIATE command with unload feature. -Issuing this command should cause the drive to switch to idle mode and -unload disk heads. This feature is being used in modern laptops in -conjunction with accelerometers and appropriate software to implement -a shock protection facility. The idea is to stop all I/O operations on -the internal hard drive and park its heads on the ramp when critical -situations are anticipated. The desire to have such a feature -available on GNU/Linux systems has been the original motivation to -implement a generic disk head parking interface in the Linux kernel. -Please note, however, that other components have to be set up on your -system in order to get disk shock protection working (see -section 3. References below for pointers to more information about -that). - - -2. The interface ----------------- - -For each ATA device, the kernel exports the file -block/*/device/unload_heads in sysfs (here assumed to be mounted under -/sys). Access to /sys/block/*/device/unload_heads is denied with --EOPNOTSUPP if the device does not support the unload feature. -Otherwise, writing an integer value to this file will take the heads -of the respective drive off the platter and block all I/O operations -for the specified number of milliseconds. When the timeout expires and -no further disk head park request has been issued in the meantime, -normal operation will be resumed. The maximal value accepted for a -timeout is 30000 milliseconds. Exceeding this limit will return --EOVERFLOW, but heads will be parked anyway and the timeout will be -set to 30 seconds. However, you can always change a timeout to any -value between 0 and 30000 by issuing a subsequent head park request -before the timeout of the previous one has expired. In particular, the -total timeout can exceed 30 seconds and, more importantly, you can -cancel a previously set timeout and resume normal operation -immediately by specifying a timeout of 0. Values below -2 are rejected -with -EINVAL (see below for the special meaning of -1 and -2). If the -timeout specified for a recent head park request has not yet expired, -reading from /sys/block/*/device/unload_heads will report the number -of milliseconds remaining until normal operation will be resumed; -otherwise, reading the unload_heads attribute will return 0. - -For example, do the following in order to park the heads of drive -/dev/sda and stop all I/O operations for five seconds: - -# echo 5000 > /sys/block/sda/device/unload_heads - -A simple - -# cat /sys/block/sda/device/unload_heads - -will show you how many milliseconds are left before normal operation -will be resumed. - -A word of caution: The fact that the interface operates on a basis of -milliseconds may raise expectations that cannot be satisfied in -reality. In fact, the ATA specs clearly state that the time for an -unload operation to complete is vendor specific. The hint in ATA-7 -that this will typically be within 500 milliseconds apparently has -been dropped in ATA-8. - -There is a technical detail of this implementation that may cause some -confusion and should be discussed here. When a head park request has -been issued to a device successfully, all I/O operations on the -controller port this device is attached to will be deferred. That is -to say, any other device that may be connected to the same port will -be affected too. The only exception is that a subsequent head unload -request to that other device will be executed immediately. Further -operations on that port will be deferred until the timeout specified -for either device on the port has expired. As far as PATA (old style -IDE) configurations are concerned, there can only be two devices -attached to any single port. In SATA world we have port multipliers -which means that a user-issued head parking request to one device may -actually result in stopping I/O to a whole bunch of devices. However, -since this feature is supposed to be used on laptops and does not seem -to be very useful in any other environment, there will be mostly one -device per port. Even if the CD/DVD writer happens to be connected to -the same port as the hard drive, it generally *should* recover just -fine from the occasional buffer under-run incurred by a head park -request to the HD. Actually, when you are using an ide driver rather -than its libata counterpart (i.e. your disk is called /dev/hda -instead of /dev/sda), then parking the heads of one drive (drive X) -will generally not affect the mode of operation of another drive -(drive Y) on the same port as described above. It is only when a port -reset is required to recover from an exception on drive Y that further -I/O operations on that drive (and the reset itself) will be delayed -until drive X is no longer in the parked state. - -Finally, there are some hard drives that only comply with an earlier -version of the ATA standard than ATA-7, but do support the unload -feature nonetheless. Unfortunately, there is no safe way Linux can -detect these devices, so you won't be able to write to the -unload_heads attribute. If you know that your device really does -support the unload feature (for instance, because the vendor of your -laptop or the hard drive itself told you so), then you can tell the -kernel to enable the usage of this feature for that drive by writing -the special value -1 to the unload_heads attribute: - -# echo -1 > /sys/block/sda/device/unload_heads - -will enable the feature for /dev/sda, and giving -2 instead of -1 will -disable it again. - - -3. References -------------- - -There are several laptops from different vendors featuring shock -protection capabilities. As manufacturers have refused to support open -source development of the required software components so far, Linux -support for shock protection varies considerably between different -hardware implementations. Ideally, this section should contain a list -of pointers at different projects aiming at an implementation of shock -protection on different systems. Unfortunately, I only know of a -single project which, although still considered experimental, is fit -for use. Please feel free to add projects that have been the victims -of my ignorance. - -- http://www.thinkwiki.org/wiki/HDAPS - See this page for information about Linux support of the hard disk - active protection system as implemented in IBM/Lenovo Thinkpads. - - -4. CREDITS ----------- - -This implementation of disk head parking has been inspired by a patch -originally published by Jon Escombe . My efforts -to develop an implementation of this feature that is fit to be merged -into mainline have been aided by various kernel developers, in -particular by Tejun Heo and Bartlomiej Zolnierkiewicz. diff --git a/trunk/Documentation/networking/cs89x0.txt b/trunk/Documentation/networking/cs89x0.txt index c725d33b316f..6387d3decf85 100644 --- a/trunk/Documentation/networking/cs89x0.txt +++ b/trunk/Documentation/networking/cs89x0.txt @@ -3,7 +3,7 @@ NOTE ---- This document was contributed by Cirrus Logic for kernel 2.2.5. This version -has been updated for 2.3.48 by Andrew Morton. +has been updated for 2.3.48 by Andrew Morton Cirrus make a copy of this driver available at their website, as described below. In general, you should use the driver version which @@ -690,7 +690,7 @@ latest drivers and technical publications. 6.4 Current maintainer In February 2000 the maintenance of this driver was assumed by Andrew -Morton. +Morton 6.5 Kernel module parameters diff --git a/trunk/Documentation/networking/phonet.txt b/trunk/Documentation/networking/phonet.txt index 6a07e45d4a93..0e6e592f4f55 100644 --- a/trunk/Documentation/networking/phonet.txt +++ b/trunk/Documentation/networking/phonet.txt @@ -146,8 +146,8 @@ WARNING: When polling a connected pipe socket for writability, there is an intrinsic race condition whereby writability might be lost between the polling and the writing system calls. In this case, the socket will -block until write becomes possible again, unless non-blocking mode -is enabled. +block until write because possible again, unless non-blocking mode +becomes enabled. The pipe protocol provides two socket options at the SOL_PNPIPE level: diff --git a/trunk/Documentation/networking/vortex.txt b/trunk/Documentation/networking/vortex.txt index bd70976b8160..6356d3faed36 100644 --- a/trunk/Documentation/networking/vortex.txt +++ b/trunk/Documentation/networking/vortex.txt @@ -1,5 +1,5 @@ Documentation/networking/vortex.txt -Andrew Morton +Andrew Morton 30 April 2000 @@ -11,7 +11,7 @@ The driver was written by Donald Becker Don is no longer the prime maintainer of this version of the driver. Please report problems to one or more of: - Andrew Morton + Andrew Morton Netdev mailing list Linux kernel mailing list @@ -305,6 +305,11 @@ Donald's wake-on-LAN page: ftp://ftp.3com.com/pub/nic/3c90x/3c90xx2.exe +Driver updates and a detailed changelog for the modifications which +were made for the 2.3/2,4 series kernel is available at + + http://www.zip.com.au/~akpm/linux/#3c59x-bc + Autonegotiation notes --------------------- diff --git a/trunk/Documentation/pcmcia/driver-changes.txt b/trunk/Documentation/pcmcia/driver-changes.txt index 059934363caf..96f155e68750 100644 --- a/trunk/Documentation/pcmcia/driver-changes.txt +++ b/trunk/Documentation/pcmcia/driver-changes.txt @@ -1,11 +1,5 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: -* New configuration loop helper (as of 2.6.28) - By calling pcmcia_loop_config(), a driver can iterate over all available - configuration options. During a driver's probe() phase, one doesn't need - to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and - pcmcia_parse_tuple directly in most if not all cases. - * New release helper (as of 2.6.17) Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's necessary now is calling pcmcia_disable_device. As there is no valid diff --git a/trunk/Documentation/power/regulator/machine.txt b/trunk/Documentation/power/regulator/machine.txt index ce3487d99abe..c9a35665cf70 100644 --- a/trunk/Documentation/power/regulator/machine.txt +++ b/trunk/Documentation/power/regulator/machine.txt @@ -2,8 +2,17 @@ Regulator Machine Driver Interface =================================== The regulator machine driver interface is intended for board/machine specific -initialisation code to configure the regulator subsystem. +initialisation code to configure the regulator subsystem. Typical things that +machine drivers would do are :- + 1. Regulator -> Device mapping. + 2. Regulator supply configuration. + 3. Power Domain constraint setting. + + + +1. Regulator -> device mapping +============================== Consider the following machine :- Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] @@ -12,82 +21,81 @@ Consider the following machine :- The drivers for consumers A & B must be mapped to the correct regulator in order to control their power supply. This mapping can be achieved in machine -initialisation code by creating a struct regulator_consumer_supply for -each regulator. - -struct regulator_consumer_supply { - struct device *dev; /* consumer */ - const char *supply; /* consumer supply - e.g. "vcc" */ -}; +initialisation code by calling :- -e.g. for the machine above +int regulator_set_device_supply(const char *regulator, struct device *dev, + const char *supply); -static struct regulator_consumer_supply regulator1_consumers[] = { -{ - .dev = &platform_consumerB_device.dev, - .supply = "Vcc", -},}; +and is shown with the following code :- -static struct regulator_consumer_supply regulator2_consumers[] = { -{ - .dev = &platform_consumerA_device.dev, - .supply = "Vcc", -},}; +regulator_set_device_supply("Regulator-1", devB, "Vcc"); +regulator_set_device_supply("Regulator-2", devA, "Vcc"); This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2 to the 'Vcc' supply for Consumer A. -Constraints can now be registered by defining a struct regulator_init_data -for each regulator power domain. This structure also maps the consumers -to their supply regulator :- - -static struct regulator_init_data regulator1_data = { - .constraints = { - .min_uV = 3300000, - .max_uV = 3300000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - }, - .num_consumer_supplies = ARRAY_SIZE(regulator1_consumers), - .consumer_supplies = regulator1_consumers, -}; + +2. Regulator supply configuration. +================================== +Consider the following machine (again) :- + + Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] + | + +-> [Consumer B @ 3.3V] Regulator-1 supplies power to Regulator-2. This relationship must be registered with the core so that Regulator-1 is also enabled when Consumer A enables it's -supply (Regulator-2). The supply regulator is set by the supply_regulator_dev -field below:- - -static struct regulator_init_data regulator2_data = { - .supply_regulator_dev = &platform_regulator1_device.dev, - .constraints = { - .min_uV = 1800000, - .max_uV = 2000000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - }, - .num_consumer_supplies = ARRAY_SIZE(regulator2_consumers), - .consumer_supplies = regulator2_consumers, +supply (Regulator-2). + +This relationship can be register with the core via :- + +int regulator_set_supply(const char *regulator, const char *regulator_supply); + +In this example we would use the following code :- + +regulator_set_supply("Regulator-2", "Regulator-1"); + +Relationships can be queried by calling :- + +const char *regulator_get_supply(const char *regulator); + + +3. Power Domain constraint setting. +=================================== +Each power domain within a system has physical constraints on voltage and +current. This must be defined in software so that the power domain is always +operated within specifications. + +Consider the following machine (again) :- + + Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] + | + +-> [Consumer B @ 3.3V] + +This gives us two regulators and two power domains: + + Domain 1: Regulator-2, Consumer B. + Domain 2: Consumer A. + +Constraints can be registered by calling :- + +int regulator_set_platform_constraints(const char *regulator, + struct regulation_constraints *constraints); + +The example is defined as follows :- + +struct regulation_constraints domain_1 = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, }; -Finally the regulator devices must be registered in the usual manner. - -static struct platform_device regulator_devices[] = { -{ - .name = "regulator", - .id = DCDC_1, - .dev = { - .platform_data = ®ulator1_data, - }, -}, -{ - .name = "regulator", - .id = DCDC_2, - .dev = { - .platform_data = ®ulator2_data, - }, -}, +struct regulation_constraints domain_2 = { + .min_uV = 1800000, + .max_uV = 2000000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = REGULATOR_MODE_NORMAL, }; -/* register regulator 1 device */ -platform_device_register(&wm8350_regulator_devices[0]); -/* register regulator 2 device */ -platform_device_register(&wm8350_regulator_devices[1]); +regulator_set_platform_constraints("Regulator-1", &domain_1); +regulator_set_platform_constraints("Regulator-2", &domain_2); diff --git a/trunk/Documentation/power/regulator/regulator.txt b/trunk/Documentation/power/regulator/regulator.txt index 4200accb9bba..a69050143592 100644 --- a/trunk/Documentation/power/regulator/regulator.txt +++ b/trunk/Documentation/power/regulator/regulator.txt @@ -10,11 +10,11 @@ Registration Drivers can register a regulator by calling :- -struct regulator_dev *regulator_register(struct device *dev, - struct regulator_desc *regulator_desc); +struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, + void *reg_data); -This will register the regulators capabilities and operations to the regulator -core. +This will register the regulators capabilities and operations the regulator +core. The core does not touch reg_data (private to regulator driver). Regulators can be unregistered by calling :- diff --git a/trunk/Documentation/power/s2ram.txt b/trunk/Documentation/power/s2ram.txt index 2ebdc6091ce1..b05f512130ea 100644 --- a/trunk/Documentation/power/s2ram.txt +++ b/trunk/Documentation/power/s2ram.txt @@ -54,21 +54,3 @@ used to run with "radeonfb" (it's an ATI Radeon mobility). It turns out that "radeonfb" simply cannot resume that device - it tries to set the PLL's, and it just _hangs_. Using the regular VGA console and letting X resume it instead works fine. - -NOTE -==== -pm_trace uses the system's Real Time Clock (RTC) to save the magic number. -Reason for this is that the RTC is the only reliably available piece of -hardware during resume operations where a value can be set that will -survive a reboot. - -Consequence is that after a resume (even if it is successful) your system -clock will have a value corresponding to the magic mumber instead of the -correct date/time! It is therefore advisable to use a program like ntp-date -or rdate to reset the correct date/time from an external time source when -using this trace option. - -As the clock keeps ticking it is also essential that the reboot is done -quickly after the resume failure. The trace option does not use the seconds -or the low order bits of the minutes of the RTC, but a too long delay will -corrupt the magic value. diff --git a/trunk/Documentation/powerpc/00-INDEX b/trunk/Documentation/powerpc/00-INDEX index e3960b8c8689..29d839ce7327 100644 --- a/trunk/Documentation/powerpc/00-INDEX +++ b/trunk/Documentation/powerpc/00-INDEX @@ -18,6 +18,10 @@ mpc52xx.txt - Linux 2.6.x on MPC52xx family mpc52xx-device-tree-bindings.txt - MPC5200 Device Tree Bindings +ppc_htab.txt + - info about the Linux/PPC /proc/ppc_htab entry +smp.txt + - use and state info about Linux/PPC on MP machines sound.txt - info on sound support under Linux/PPC zImage_layout.txt diff --git a/trunk/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt b/trunk/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt deleted file mode 100644 index 35a465362408..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt +++ /dev/null @@ -1,40 +0,0 @@ -* Freescale 83xx and 512x PCI bridges - -Freescale 83xx and 512x SOCs include the same pci bridge core. - -83xx/512x specific notes: -- reg: should contain two address length tuples - The first is for the internal pci bridge registers - The second is for the pci config space access registers - -Example (MPC8313ERDB) - pci0: pci@e0008500 { - cell-index = <1>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x0E -mini PCI */ - 0x7000 0x0 0x0 0x1 &ipic 18 0x8 - 0x7000 0x0 0x0 0x2 &ipic 18 0x8 - 0x7000 0x0 0x0 0x3 &ipic 18 0x8 - 0x7000 0x0 0x0 0x4 &ipic 18 0x8 - - /* IDSEL 0x0F - PCI slot */ - 0x7800 0x0 0x0 0x1 &ipic 17 0x8 - 0x7800 0x0 0x0 0x2 &ipic 18 0x8 - 0x7800 0x0 0x0 0x3 &ipic 17 0x8 - 0x7800 0x0 0x0 0x4 &ipic 18 0x8>; - interrupt-parent = <&ipic>; - interrupts = <66 0x8>; - bus-range = <0x0 0x0>; - ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 - 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 - 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; - clock-frequency = <66666666>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ - compatible = "fsl,mpc8349-pci"; - device_type = "pci"; - }; diff --git a/trunk/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt b/trunk/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt deleted file mode 100644 index d015dcec4011..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt +++ /dev/null @@ -1,40 +0,0 @@ -GPIO controllers on MPC8xxx SoCs - -This is for the non-QE/CPM/GUTs GPIO controllers as found on -8349, 8572, 8610 and compatible. - -Every GPIO controller node must have #gpio-cells property defined, -this information will be used to translate gpio-specifiers. - -Required properties: -- compatible : "fsl,-gpio" followed by "fsl,mpc8349-gpio" for - 83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx. -- #gpio-cells : Should be two. The first cell is the pin number and the - second cell is used to specify optional parameters (currently unused). - - interrupts : Interrupt mapping for GPIO IRQ (currently unused). - - interrupt-parent : Phandle for the interrupt controller that - services interrupts for this device. -- gpio-controller : Marks the port as GPIO controller. - -Example of gpio-controller nodes for a MPC8347 SoC: - - gpio1: gpio-controller@c00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio"; - reg = <0xc00 0x100>; - interrupts = <74 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - gpio2: gpio-controller@d00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio"; - reg = <0xd00 0x100>; - interrupts = <75 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - -See booting-without-of.txt for details of how to specify GPIO -information for devices. diff --git a/trunk/Documentation/powerpc/dts-bindings/fsl/dma.txt b/trunk/Documentation/powerpc/dts-bindings/fsl/dma.txt index cc453110fc46..86826df00e64 100644 --- a/trunk/Documentation/powerpc/dts-bindings/fsl/dma.txt +++ b/trunk/Documentation/powerpc/dts-bindings/fsl/dma.txt @@ -20,7 +20,7 @@ Required properties: - compatible : compatible list, contains 2 entries, first is "fsl,CHIP-dma-channel", where CHIP is the processor (mpc8349, mpc8350, etc.) and the second is - "fsl,elo-dma-channel". However, see note below. + "fsl,elo-dma-channel" - reg : - cell-index : dma channel index starts at 0. @@ -82,7 +82,7 @@ Required properties: - compatible : compatible list, contains 2 entries, first is "fsl,CHIP-dma-channel", where CHIP is the processor (mpc8540, mpc8560, etc.) and the second is - "fsl,eloplus-dma-channel". However, see note below. + "fsl,eloplus-dma-channel" - cell-index : dma channel index starts at 0. - reg : - interrupts : @@ -125,12 +125,3 @@ Example: interrupts = <17 2>; }; }; - -Note on DMA channel compatible properties: The compatible property must say -"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA -driver (fsldma). Any DMA channel used by fsldma cannot be used by another -DMA driver, such as the SSI sound drivers for the MPC8610. Therefore, any DMA -channel that should be used for another driver should not use -"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel". For the SSI drivers, for -example, the compatible property should be "fsl,ssi-dma-channel". See ssi.txt -for more information. diff --git a/trunk/Documentation/powerpc/dts-bindings/fsl/ssi.txt b/trunk/Documentation/powerpc/dts-bindings/fsl/ssi.txt index a2d963998a65..d100555d488a 100644 --- a/trunk/Documentation/powerpc/dts-bindings/fsl/ssi.txt +++ b/trunk/Documentation/powerpc/dts-bindings/fsl/ssi.txt @@ -24,12 +24,6 @@ Required properties: "rj-master" - r.j., SSI is clock master "ac97-slave" - AC97 mode, SSI is clock slave "ac97-master" - AC97 mode, SSI is clock master -- fsl,playback-dma: phandle to a node for the DMA channel to use for - playback of audio. This is typically dictated by SOC - design. See the notes below. -- fsl,capture-dma: phandle to a node for the DMA channel to use for - capture (recording) of audio. This is typically dictated - by SOC design. See the notes below. Optional properties: - codec-handle : phandle to a 'codec' node that defines an audio @@ -42,20 +36,3 @@ Child 'codec' node required properties: Child 'codec' node optional properties: - clock-frequency : The frequency of the input clock, which typically comes from an on-board dedicated oscillator. - -Notes on fsl,playback-dma and fsl,capture-dma: - -On SOCs that have an SSI, specific DMA channels are hard-wired for playback -and capture. On the MPC8610, for example, SSI1 must use DMA channel 0 for -playback and DMA channel 1 for capture. SSI2 must use DMA channel 2 for -playback and DMA channel 3 for capture. The developer can choose which -DMA controller to use, but the channels themselves are hard-wired. The -purpose of these two properties is to represent this hardware design. - -The device tree nodes for the DMA channels that are referenced by -"fsl,playback-dma" and "fsl,capture-dma" must be marked as compatible with -"fsl,ssi-dma-channel". The SOC-specific compatible string (e.g. -"fsl,mpc8610-dma-channel") can remain. If these nodes are left as -"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel", then the generic Elo DMA -drivers (fsldma) will attempt to use them, and it will conflict with the -sound drivers. diff --git a/trunk/Documentation/powerpc/ppc_htab.txt b/trunk/Documentation/powerpc/ppc_htab.txt new file mode 100644 index 000000000000..8b8c7df29fa9 --- /dev/null +++ b/trunk/Documentation/powerpc/ppc_htab.txt @@ -0,0 +1,118 @@ + Information about /proc/ppc_htab +===================================================================== + +This document and the related code was written by me (Cort Dougan), please +email me (cort@fsmlabs.com) if you have questions, comments or corrections. + +Last Change: 2.16.98 + +This entry in the proc directory is readable by all users but only +writable by root. + +The ppc_htab interface is a user level way of accessing the +performance monitoring registers as well as providing information +about the PTE hash table. + +1. Reading + + Reading this file will give you information about the memory management + hash table that serves as an extended tlb for page translation on the + powerpc. It will also give you information about performance measurement + specific to the cpu that you are using. + + Explanation of the 604 Performance Monitoring Fields: + MMCR0 - the current value of the MMCR0 register + PMC1 + PMC2 - the value of the performance counters and a + description of what events they are counting + which are based on MMCR0 bit settings. + Explanation of the PTE Hash Table fields: + + Size - hash table size in Kb. + Buckets - number of buckets in the table. + Address - the virtual kernel address of the hash table base. + Entries - the number of ptes that can be stored in the hash table. + User/Kernel - how many pte's are in use by the kernel or user at that time. + Overflows - How many of the entries are in their secondary hash location. + Percent full - ratio of free pte entries to in use entries. + Reloads - Count of how many hash table misses have occurred + that were fixed with a reload from the linux tables. + Should always be 0 on 603 based machines. + Non-error Misses - Count of how many hash table misses have occurred + that were completed with the creation of a pte in the linux + tables with a call to do_page_fault(). + Error Misses - Number of misses due to errors such as bad address + and permission violations. This includes kernel access of + bad user addresses that are fixed up by the trap handler. + + Note that calculation of the data displayed from /proc/ppc_htab takes + a long time and spends a great deal of time in the kernel. It would + be quite hard on performance to read this file constantly. In time + there may be a counter in the kernel that allows successive reads from + this file only after a given amount of time has passed to reduce the + possibility of a user slowing the system by reading this file. + +2. Writing + + Writing to the ppc_htab allows you to change the characteristics of + the powerpc PTE hash table and setup performance monitoring. + + Resizing the PTE hash table is not enabled right now due to many + complications with moving the hash table, rehashing the entries + and many many SMP issues that would have to be dealt with. + + Write options to ppc_htab: + + - To set the size of the hash table to 64Kb: + + echo 'size 64' > /proc/ppc_htab + + The size must be a multiple of 64 and must be greater than or equal to + 64. + + - To turn off performance monitoring: + + echo 'off' > /proc/ppc_htab + + - To reset the counters without changing what they're counting: + + echo 'reset' > /proc/ppc_htab + + Note that counting will continue after the reset if it is enabled. + + - To count only events in user mode or only in kernel mode: + + echo 'user' > /proc/ppc_htab + ...or... + echo 'kernel' > /proc/ppc_htab + + Note that these two options are exclusive of one another and the + lack of either of these options counts user and kernel. + Using 'reset' and 'off' reset these flags. + + - The 604 has 2 performance counters which can each count events from + a specific set of events. These sets are disjoint so it is not + possible to count _any_ combination of 2 events. One event can + be counted by PMC1 and one by PMC2. + + To start counting a particular event use: + + echo 'event' > /proc/ppc_htab + + and choose from these events: + + PMC1 + ---- + 'ic miss' - instruction cache misses + 'dtlb' - data tlb misses (not hash table misses) + + PMC2 + ---- + 'dc miss' - data cache misses + 'itlb' - instruction tlb misses (not hash table misses) + 'load miss time' - cycles to complete a load miss + +3. Bugs + + The PMC1 and PMC2 counters can overflow and give no indication of that + in /proc/ppc_htab. diff --git a/trunk/Documentation/powerpc/smp.txt b/trunk/Documentation/powerpc/smp.txt new file mode 100644 index 000000000000..5b581b849ff7 --- /dev/null +++ b/trunk/Documentation/powerpc/smp.txt @@ -0,0 +1,34 @@ + Information about Linux/PPC SMP mode +===================================================================== + +This document and the related code was written by me +(Cort Dougan, cort@fsmlabs.com) please email me if you have questions, +comments or corrections. + +Last Change: 3.31.99 + +If you want to help by writing code or testing different hardware please +email me! + +1. State of Supported Hardware + + PowerSurge Architecture - tested on UMAX s900, Apple 9600 + The second processor on this machine boots up just fine and + enters its idle loop. Hopefully a completely working SMP kernel + on this machine will be done shortly. + + The code makes the assumption of only two processors. The changes + necessary to work with any number would not be overly difficult but + I don't have any machines with >2 processors so it's not high on my + list of priorities. If anyone else would like do to the work email + me and I can point out the places that need changed. If you have >2 + processors and don't want to add support yourself let me know and I + can take a look into it. + + BeBox + BeBox support hasn't been added to the 2.1.X kernels from 2.0.X + but work is being done and SMP support for BeBox is in the works. + + CHRP + CHRP SMP works and is fairly solid. It's been tested on the IBM F50 + with 4 processors for quite some time now. diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid b/trunk/Documentation/scsi/ChangeLog.megaraid index eaa4801f2ce6..37796fe45bd0 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid +++ b/trunk/Documentation/scsi/ChangeLog.megaraid @@ -409,7 +409,7 @@ i. Function reordering so that inline functions are defined before they megaraid_mbox_prepare_pthru, megaraid_mbox_prepare_epthru, megaraid_busywait_mbox - - Andrew Morton, 08.19.2004 + - Andrew Morton , 08.19.2004 linux-scsi mailing list "Something else to clean up after inclusion: every instance of an @@ -471,13 +471,13 @@ vi. Add support for 64-bit applications. Current drivers assume only vii. Move the function declarations for the management module from megaraid_mm.h to megaraid_mm.c - - Andrew Morton, 08.19.2004 + - Andrew Morton , 08.19.2004 linux-scsi mailing list viii. Change default values for MEGARAID_NEWGEN, MEGARAID_MM, and MEGARAID_MAILBOX to 'n' in Kconfig.megaraid - - Andrew Morton, 08.19.2004 + - Andrew Morton , 08.19.2004 linux-scsi mailing list ix. replace udelay with msleep diff --git a/trunk/Documentation/spi/pxa2xx b/trunk/Documentation/spi/pxa2xx index 6bb916d57c95..bbe8dee681a5 100644 --- a/trunk/Documentation/spi/pxa2xx +++ b/trunk/Documentation/spi/pxa2xx @@ -96,7 +96,7 @@ Each slave device attached to the PXA must provide slave specific configuration information via the structure "pxa2xx_spi_chip" found in "arch/arm/mach-pxa/include/mach/pxa2xx_spi.h". The pxa2xx_spi master controller driver will uses the configuration whenever the driver communicates with the slave -device. All fields are optional. +device. struct pxa2xx_spi_chip { u8 tx_threshold; @@ -112,17 +112,14 @@ used to configure the SSP hardware fifo. These fields are critical to the performance of pxa2xx_spi driver and misconfiguration will result in rx fifo overruns (especially in PIO mode transfers). Good default values are - .tx_threshold = 8, - .rx_threshold = 8, - -The range is 1 to 16 where zero indicates "use default". + .tx_threshold = 12, + .rx_threshold = 4, The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA engine and is related the "spi_device.bits_per_word" field. Read and understand the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers to determine the correct value. An SSP configured for byte-wide transfers would -use a value of 8. The driver will determine a reasonable default if -dma_burst_size == 0. +use a value of 8. The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle trailing bytes in the SSP receiver fifo. The correct value for this field is @@ -140,13 +137,7 @@ function for asserting/deasserting a slave device chip select. If the field is NULL, the pxa2xx_spi master controller driver assumes that the SSP port is configured to use SSPFRM instead. -NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the -chipselect is dropped after each spi_transfer. Most devices need chip select -asserted around the complete message. Use SSPFRM as a GPIO (through cs_control) -to accomodate these chips. - - -NSSP SLAVE SAMPLE +NSSP SALVE SAMPLE ----------------- The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the "spi_board_info.controller_data" field. Below is a sample configuration using @@ -215,21 +206,18 @@ static void __init streetracer_init(void) DMA and PIO I/O Support ----------------------- -The pxa2xx_spi driver supports both DMA and interrupt driven PIO message -transfers. The driver defaults to PIO mode and DMA transfers must be enabled -by setting the "enable_dma" flag in the "pxa2xx_spi_master" structure. The DMA -mode supports both coherent and stream based DMA mappings. +The pxa2xx_spi driver support both DMA and interrupt driven PIO message +transfers. The driver defaults to PIO mode and DMA transfers must enabled by +setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and +ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero. The DMA +mode support both coherent and stream based DMA mappings. The following logic is used to determine the type of I/O to be used on a per "spi_transfer" basis: -if !enable_dma then +if !enable_dma or dma_burst_size == 0 then always use PIO transfers -if spi_message.len > 8191 then - print "rate limited" warning - use PIO transfers - if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then use coherent DMA mode diff --git a/trunk/Documentation/timers/00-INDEX b/trunk/Documentation/timers/00-INDEX deleted file mode 100644 index 397dc35e1323..000000000000 --- a/trunk/Documentation/timers/00-INDEX +++ /dev/null @@ -1,10 +0,0 @@ -00-INDEX - - this file -highres.txt - - High resolution timers and dynamic ticks design notes -hpet.txt - - High Precision Event Timer Driver for Linux -hrtimers.txt - - subsystem for high-resolution kernel timers -timer_stats.txt - - timer usage statistics diff --git a/trunk/Documentation/video4linux/CARDLIST.bttv b/trunk/Documentation/video4linux/CARDLIST.bttv index 60ba66836038..f32efb6fb12c 100644 --- a/trunk/Documentation/video4linux/CARDLIST.bttv +++ b/trunk/Documentation/video4linux/CARDLIST.bttv @@ -150,4 +150,3 @@ 149 -> Typhoon TV-Tuner PCI (50684) 150 -> Geovision GV-600 [008a:763c] 151 -> Kozumi KTV-01C -152 -> Encore ENL TV-FM-2 [1000:1801] diff --git a/trunk/Documentation/video4linux/CARDLIST.cx23885 b/trunk/Documentation/video4linux/CARDLIST.cx23885 index 64823ccacd69..f0e613ba55b8 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx23885 +++ b/trunk/Documentation/video4linux/CARDLIST.cx23885 @@ -9,5 +9,3 @@ 8 -> Hauppauge WinTV-HVR1700 [0070:8101] 9 -> Hauppauge WinTV-HVR1400 [0070:8010] 10 -> DViCO FusionHDTV7 Dual Express [18ac:d618] - 11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78] - 12 -> Leadtek Winfast PxDVR3200 H [107d:6681] diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index a5227e308f4a..7cf5685d3645 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -66,11 +66,3 @@ 65 -> DViCO FusionHDTV 7 Gold [18ac:d610] 66 -> Prolink Pixelview MPEG 8000GT [1554:4935] 67 -> Kworld PlusTV HD PCI 120 (ATSC 120) [17de:08c1] - 68 -> Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid [0070:6900,0070:6904,0070:6902] - 69 -> Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 [0070:6905,0070:6906] - 70 -> TeVii S460 DVB-S/S2 [d460:9022] - 71 -> Omicom SS4 DVB-S/S2 PCI [A044:2011] - 72 -> TBS 8920 DVB-S/S2 [8920:8888] - 73 -> TeVii S420 DVB-S [d420:9022] - 74 -> Prolink Pixelview Global Extreme [1554:4976] - 75 -> PROF 7300 DVB-S/S2 [B033:3033] diff --git a/trunk/Documentation/video4linux/CARDLIST.em28xx b/trunk/Documentation/video4linux/CARDLIST.em28xx index 187cc48d0924..53449cb99b17 100644 --- a/trunk/Documentation/video4linux/CARDLIST.em28xx +++ b/trunk/Documentation/video4linux/CARDLIST.em28xx @@ -1,5 +1,5 @@ 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] - 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] + 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] @@ -12,7 +12,7 @@ 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 -> Kworld PVR TV 2800 RF (em2820/em2840) 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] - 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) [eb1a:2821] + 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f] 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134 index dc67eef38ff9..39868af9cf9f 100644 --- a/trunk/Documentation/video4linux/CARDLIST.saa7134 +++ b/trunk/Documentation/video4linux/CARDLIST.saa7134 @@ -76,7 +76,7 @@ 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044] 76 -> SKNet MonsterTV Mobile [1131:4ee9] 77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e] - 78 -> ASUSTeK P7131 Dual [1043:4862] + 78 -> ASUSTeK P7131 Dual [1043:4862,1043:4857] 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) 80 -> ASUS Digimatrix TV [1043:0210] 81 -> Philips Tiger reference design [1131:2018] @@ -145,9 +145,3 @@ 144 -> Beholder BeholdTV M6 Extra [5ace:6193] 145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636] 146 -> ASUSTeK P7131 Analog -147 -> Asus Tiger 3in1 [1043:4878] -148 -> Encore ENLTV-FM v5.3 [1a7f:2008] -149 -> Avermedia PCI pure analog (M135A) [1461:f11d] -150 -> Zogis Real Angel 220 -151 -> ADS Tech Instant HDTV [1421:0380] -152 -> Asus Tiger Rev:1.00 [1043:4857] diff --git a/trunk/Documentation/video4linux/CARDLIST.tuner b/trunk/Documentation/video4linux/CARDLIST.tuner index 30bbdda68d03..0e2394695bb8 100644 --- a/trunk/Documentation/video4linux/CARDLIST.tuner +++ b/trunk/Documentation/video4linux/CARDLIST.tuner @@ -74,4 +74,3 @@ tuner=72 - Thomson FE6600 tuner=73 - Samsung TCPG 6121P30A tuner=75 - Philips TEA5761 FM Radio tuner=76 - Xceive 5000 tuner -tuner=77 - TCL tuner MF02GIP-5N-E diff --git a/trunk/Documentation/video4linux/gspca.txt b/trunk/Documentation/video4linux/gspca.txt index 004818fab040..9a3e4d797fa8 100644 --- a/trunk/Documentation/video4linux/gspca.txt +++ b/trunk/Documentation/video4linux/gspca.txt @@ -7,7 +7,6 @@ The modules are: xxxx vend:prod ---- spca501 0000:0000 MystFromOri Unknow Camera -m5602 0402:5602 ALi Video Camera Controller spca501 040a:0002 Kodak DVC-325 spca500 040a:0300 Kodak EZ200 zc3xx 041e:041e Creative WebCam Live! @@ -43,7 +42,6 @@ zc3xx 0458:7007 Genius VideoCam V2 zc3xx 0458:700c Genius VideoCam V3 zc3xx 0458:700f Genius VideoCam Web V2 sonixj 0458:7025 Genius Eye 311Q -sonixj 0458:702e Genius Slim 310 NB sonixj 045e:00f5 MicroSoft VX3000 sonixj 045e:00f7 MicroSoft VX1000 ov519 045e:028c Micro$oft xbox cam @@ -83,7 +81,7 @@ spca561 046d:092b Labtec Webcam Plus spca561 046d:092c Logitech QC chat Elch2 spca561 046d:092d Logitech QC Elch2 spca561 046d:092e Logitech QC Elch2 -spca561 046d:092f Logitech QuickCam Express Plus +spca561 046d:092f Logitech QC Elch2 sunplus 046d:0960 Logitech ClickSmart 420 sunplus 0471:0322 Philips DMVC1300K zc3xx 0471:0325 Philips SPC 200 NC @@ -98,29 +96,6 @@ sunplus 04a5:3003 Benq DC 1300 sunplus 04a5:3008 Benq DC 1500 sunplus 04a5:300a Benq DC 3410 spca500 04a5:300c Benq DC 1016 -finepix 04cb:0104 Fujifilm FinePix 4800 -finepix 04cb:0109 Fujifilm FinePix A202 -finepix 04cb:010b Fujifilm FinePix A203 -finepix 04cb:010f Fujifilm FinePix A204 -finepix 04cb:0111 Fujifilm FinePix A205 -finepix 04cb:0113 Fujifilm FinePix A210 -finepix 04cb:0115 Fujifilm FinePix A303 -finepix 04cb:0117 Fujifilm FinePix A310 -finepix 04cb:0119 Fujifilm FinePix F401 -finepix 04cb:011b Fujifilm FinePix F402 -finepix 04cb:011d Fujifilm FinePix F410 -finepix 04cb:0121 Fujifilm FinePix F601 -finepix 04cb:0123 Fujifilm FinePix F700 -finepix 04cb:0125 Fujifilm FinePix M603 -finepix 04cb:0127 Fujifilm FinePix S300 -finepix 04cb:0129 Fujifilm FinePix S304 -finepix 04cb:012b Fujifilm FinePix S500 -finepix 04cb:012d Fujifilm FinePix S602 -finepix 04cb:012f Fujifilm FinePix S700 -finepix 04cb:0131 Fujifilm FinePix unknown model -finepix 04cb:013b Fujifilm FinePix unknown model -finepix 04cb:013d Fujifilm FinePix unknown model -finepix 04cb:013f Fujifilm FinePix F420 sunplus 04f1:1001 JVC GC A50 spca561 04fc:0561 Flexcam 100 sunplus 04fc:500c Sunplus CA500C @@ -206,7 +181,6 @@ pac207 093a:2468 PAC207 pac207 093a:2470 Genius GF112 pac207 093a:2471 Genius VideoCam ge111 pac207 093a:2472 Genius VideoCam ge110 -pac207 093a:2476 Genius e-Messenger 112 pac7311 093a:2600 PAC7311 Typhoon pac7311 093a:2601 Philips SPC 610 NC pac7311 093a:2603 PAC7312 diff --git a/trunk/Documentation/video4linux/m5602.txt b/trunk/Documentation/video4linux/m5602.txt deleted file mode 100644 index 4450ab13f37b..000000000000 --- a/trunk/Documentation/video4linux/m5602.txt +++ /dev/null @@ -1,12 +0,0 @@ -This document describes the ALi m5602 bridge connected -to the following supported sensors: -OmniVision OV9650, -Samsung s5k83a, -Samsung s5k4aa, -Micron mt9m111, -Pixel plus PO1030 - -This driver mimics the windows drivers, which have a braindead implementation sending bayer-encoded frames at VGA resolution. -In a perfect world we should be able to reprogram the m5602 and the connected sensor in hardware instead, supporting a range of resolutions and pixelformats - -Anyway, have fun and please report any bugs to m560x-driver-devel@lists.sourceforge.net diff --git a/trunk/Documentation/video4linux/soc-camera.txt b/trunk/Documentation/video4linux/soc-camera.txt deleted file mode 100644 index 178ef3c5e579..000000000000 --- a/trunk/Documentation/video4linux/soc-camera.txt +++ /dev/null @@ -1,120 +0,0 @@ - Soc-Camera Subsystem - ==================== - -Terminology ------------ - -The following terms are used in this document: - - camera / camera device / camera sensor - a video-camera sensor chip, capable - of connecting to a variety of systems and interfaces, typically uses i2c for - control and configuration, and a parallel or a serial bus for data. - - camera host - an interface, to which a camera is connected. Typically a - specialised interface, present on many SoCs, e.g., PXA27x and PXA3xx, SuperH, - AVR32, i.MX27, i.MX31. - - camera host bus - a connection between a camera host and a camera. Can be - parallel or serial, consists of data and control lines, e.g., clock, vertical - and horizontal synchronization signals. - -Purpose of the soc-camera subsystem ------------------------------------ - -The soc-camera subsystem provides a unified API between camera host drivers and -camera sensor drivers. It implements a V4L2 interface to the user, currently -only the mmap method is supported. - -This subsystem has been written to connect drivers for System-on-Chip (SoC) -video capture interfaces with drivers for CMOS camera sensor chips to enable -the reuse of sensor drivers with various hosts. The subsystem has been designed -to support multiple camera host interfaces and multiple cameras per interface, -although most applications have only one camera sensor. - -Existing drivers ----------------- - -As of 2.6.27-rc4 there are two host drivers in the mainline: pxa_camera.c for -PXA27x SoCs and sh_mobile_ceu_camera.c for SuperH SoCs, and four sensor drivers: -mt9m001.c, mt9m111.c, mt9v022.c and a generic soc_camera_platform.c driver. This -list is not supposed to be updated, look for more examples in your tree. - -Camera host API ---------------- - -A host camera driver is registered using the - -soc_camera_host_register(struct soc_camera_host *); - -function. The host object can be initialized as follows: - -static struct soc_camera_host pxa_soc_camera_host = { - .drv_name = PXA_CAM_DRV_NAME, - .ops = &pxa_soc_camera_host_ops, -}; - -All camera host methods are passed in a struct soc_camera_host_ops: - -static struct soc_camera_host_ops pxa_soc_camera_host_ops = { - .owner = THIS_MODULE, - .add = pxa_camera_add_device, - .remove = pxa_camera_remove_device, - .suspend = pxa_camera_suspend, - .resume = pxa_camera_resume, - .set_fmt_cap = pxa_camera_set_fmt_cap, - .try_fmt_cap = pxa_camera_try_fmt_cap, - .init_videobuf = pxa_camera_init_videobuf, - .reqbufs = pxa_camera_reqbufs, - .poll = pxa_camera_poll, - .querycap = pxa_camera_querycap, - .try_bus_param = pxa_camera_try_bus_param, - .set_bus_param = pxa_camera_set_bus_param, -}; - -.add and .remove methods are called when a sensor is attached to or detached -from the host, apart from performing host-internal tasks they shall also call -sensor driver's .init and .release methods respectively. .suspend and .resume -methods implement host's power-management functionality and its their -responsibility to call respective sensor's methods. .try_bus_param and -.set_bus_param are used to negotiate physical connection parameters between the -host and the sensor. .init_videobuf is called by soc-camera core when a -video-device is opened, further video-buffer management is implemented completely -by the specific camera host driver. The rest of the methods are called from -respective V4L2 operations. - -Camera API ----------- - -Sensor drivers can use struct soc_camera_link, typically provided by the -platform, and used to specify to which camera host bus the sensor is connected, -and arbitrarily provide platform .power and .reset methods for the camera. -soc_camera_device_register() and soc_camera_device_unregister() functions are -used to add a sensor driver to or remove one from the system. The registration -function takes a pointer to struct soc_camera_device as the only parameter. -This struct can be initialized as follows: - - /* link to driver operations */ - icd->ops = &mt9m001_ops; - /* link to the underlying physical (e.g., i2c) device */ - icd->control = &client->dev; - /* window geometry */ - icd->x_min = 20; - icd->y_min = 12; - icd->x_current = 20; - icd->y_current = 12; - icd->width_min = 48; - icd->width_max = 1280; - icd->height_min = 32; - icd->height_max = 1024; - icd->y_skip_top = 1; - /* camera bus ID, typically obtained from platform data */ - icd->iface = icl->bus_id; - -struct soc_camera_ops provides .probe and .remove methods, which are called by -the soc-camera core, when a camera is matched against or removed from a camera -host bus, .init, .release, .suspend, and .resume are called from the camera host -driver as discussed above. Other members of this struct provide respective V4L2 -functionality. - -struct soc_camera_device also links to an array of struct soc_camera_data_format, -listing pixel formats, supported by the camera. - --- -Author: Guennadi Liakhovetski diff --git a/trunk/Documentation/w1/00-INDEX b/trunk/Documentation/w1/00-INDEX index cb49802745dc..5270cf4cb109 100644 --- a/trunk/Documentation/w1/00-INDEX +++ b/trunk/Documentation/w1/00-INDEX @@ -1,7 +1,5 @@ 00-INDEX - This file -slaves/ - - Drivers that provide support for specific family codes. masters/ - Individual chips providing 1-wire busses. w1.generic diff --git a/trunk/Documentation/w1/masters/ds2490 b/trunk/Documentation/w1/masters/ds2490 index 28176def3d6f..239f9ae01843 100644 --- a/trunk/Documentation/w1/masters/ds2490 +++ b/trunk/Documentation/w1/masters/ds2490 @@ -16,55 +16,3 @@ which allows to build USB <-> W1 bridges. DS9490(R) is a USB <-> W1 bus master device which has 0x81 family ID integrated chip and DS2490 low-level operational chip. - -Notes and limitations. -- The weak pullup current is a minimum of 0.9mA and maximum of 6.0mA. -- The 5V strong pullup is supported with a minimum of 5.9mA and a - maximum of 30.4 mA. (From DS2490.pdf) -- While the ds2490 supports a hardware search the code doesn't take - advantage of it (in tested case it only returned first device). -- The hardware will detect when devices are attached to the bus on the - next bus (reset?) operation, however only a message is printed as - the core w1 code doesn't make use of the information. Connecting - one device tends to give multiple new device notifications. -- The number of USB bus transactions could be reduced if w1_reset_send - was added to the API. The name is just a suggestion. It would take - a write buffer and a read buffer (along with sizes) as arguments. - The ds2490 block I/O command supports reset, write buffer, read - buffer, and strong pullup all in one command, instead of the current - 1 reset bus, 2 write the match rom command and slave rom id, 3 block - write and read data. The write buffer needs to have the match rom - command and slave rom id prepended to the front of the requested - write buffer, both of which are known to the driver. -- The hardware supports normal, flexible, and overdrive bus - communication speeds, but only the normal is supported. -- The registered w1_bus_master functions don't define error - conditions. If a bus search is in progress and the ds2490 is - removed it can produce a good amount of error output before the bus - search finishes. -- The hardware supports detecting some error conditions, such as - short, alarming presence on reset, and no presence on reset, but the - driver doesn't query those values. -- The ds2490 specification doesn't cover short bulk in reads in - detail, but my observation is if fewer bytes are requested than are - available, the bulk read will return an error and the hardware will - clear the entire bulk in buffer. It would be possible to read the - maximum buffer size to not run into this error condition, only extra - bytes in the buffer is a logic error in the driver. The code should - should match reads and writes as well as data sizes. Reads and - writes are serialized and the status verifies that the chip is idle - (and data is available) before the read is executed, so it should - not happen. -- Running x86_64 2.6.24 UHCI under qemu 0.9.0 under x86_64 2.6.22-rc6 - with a OHCI controller, ds2490 running in the guest would operate - normally the first time the module was loaded after qemu attached - the ds2490 hardware, but if the module was unloaded, then reloaded - most of the time one of the bulk out or in, and usually the bulk in - would fail. qemu sets a 50ms timeout and the bulk in would timeout - even when the status shows data available. A bulk out write would - show a successful completion, but the ds2490 status register would - show 0 bytes written. Detaching qemu from the ds2490 hardware and - reattaching would clear the problem. usbmon output in the guest and - host did not explain the problem. My guess is a bug in either qemu - or the host OS and more likely the host OS. --- 03-06-2008 David Fries diff --git a/trunk/Documentation/w1/slaves/00-INDEX b/trunk/Documentation/w1/slaves/00-INDEX deleted file mode 100644 index f8101d6b07b7..000000000000 --- a/trunk/Documentation/w1/slaves/00-INDEX +++ /dev/null @@ -1,4 +0,0 @@ -00-INDEX - - This file -w1_therm - - The Maxim/Dallas Semiconductor ds18*20 temperature sensor. diff --git a/trunk/Documentation/w1/slaves/w1_therm b/trunk/Documentation/w1/slaves/w1_therm deleted file mode 100644 index 0403aaaba878..000000000000 --- a/trunk/Documentation/w1/slaves/w1_therm +++ /dev/null @@ -1,41 +0,0 @@ -Kernel driver w1_therm -==================== - -Supported chips: - * Maxim ds18*20 based temperature sensors. - -Author: Evgeniy Polyakov - - -Description ------------ - -w1_therm provides basic temperature conversion for ds18*20 devices. -supported family codes: -W1_THERM_DS18S20 0x10 -W1_THERM_DS1822 0x22 -W1_THERM_DS18B20 0x28 - -Support is provided through the sysfs w1_slave file. Each open and -read sequence will initiate a temperature conversion then provide two -lines of ASCII output. The first line contains the nine hex bytes -read along with a calculated crc value and YES or NO if it matched. -If the crc matched the returned values are retained. The second line -displays the retained values along with a temperature in millidegrees -Centigrade after t=. - -Parasite powered devices are limited to one slave performing a -temperature conversion at a time. If none of the devices are parasite -powered it would be possible to convert all the devices at the same -time and then go back to read individual sensors. That isn't -currently supported. The driver also doesn't support reduced -precision (which would also reduce the conversion time). - -The module parameter strong_pullup can be set to 0 to disable the -strong pullup or 1 to enable. If enabled the 5V strong pullup will be -enabled when the conversion is taking place provided the master driver -must support the strong pullup (or it falls back to a pullup -resistor). The DS18b20 temperature sensor specification lists a -maximum current draw of 1.5mA and that a 5k pullup resistor is not -sufficient. The strong pullup is designed to provide the additional -current required. diff --git a/trunk/Documentation/w1/w1.generic b/trunk/Documentation/w1/w1.generic index e3333eec4320..4c6509dd4789 100644 --- a/trunk/Documentation/w1/w1.generic +++ b/trunk/Documentation/w1/w1.generic @@ -79,13 +79,10 @@ w1 master sysfs interface - a directory for a found device. The format is family-serial bus - (standard) symlink to the w1 bus driver - (standard) symlink to the w1 driver -w1_master_add - Manually register a slave device w1_master_attempts - the number of times a search was attempted w1_master_max_slave_count - the maximum slaves that may be attached to a master w1_master_name - the name of the device (w1_bus_masterX) -w1_master_pullup - 5V strong pullup 0 enabled, 1 disabled -w1_master_remove - Manually remove a slave device w1_master_search - the number of searches left to do, -1=continual (default) w1_master_slave_count - the number of slaves found @@ -93,13 +90,7 @@ w1_master_slaves - the names of the slaves, one per line w1_master_timeout - the delay in seconds between searches If you have a w1 bus that never changes (you don't add or remove devices), -you can set the module parameter search_count to a small positive number -for an initially small number of bus searches. Alternatively it could be -set to zero, then manually add the slave device serial numbers by -w1_master_add device file. The w1_master_add and w1_master_remove files -generally only make sense when searching is disabled, as a search will -redetect manually removed devices that are present and timeout manually -added devices that aren't on the bus. +you can set w1_master_search to a positive value to disable searches. w1 slave sysfs interface diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 57975bda9201..6ba3ee822838 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -72,8 +72,8 @@ M: Mail patches to L: Mailing list that is relevant to this area W: Web-page with status/info T: SCM tree type and location. Type is one of: git, hg, quilt. -F: Applicable files and/or directories S: Status, one of the following: +F: Applicable files and/or directories Supported: Someone is actually paid to look after this. Maintained: Someone actually looks after it. @@ -1629,11 +1629,6 @@ P: Christopher Hoover M: ch@murgatroid.com, ch@hpl.hp.com S: Maintained -EPSON S1D13XXX FRAMEBUFFER DRIVER -P: Kristoffer Ericson -M: kristoffer.ericson@gmail.com -S: Maintained - ETHEREXPRESS-16 NETWORK DRIVER P: Philip Blundell M: philb@gnu.org @@ -2802,6 +2797,15 @@ L: linux-mtd@lists.infradead.org T: git git://git.infradead.org/mtd-2.6.git S: Maintained +MEI MN10300/AM33 PORT +P: David Howells +M: dhowells@redhat.com +P: Koichi Yasutake +M: yasutake.koichi@jp.panasonic.com +L: linux-am33-list@redhat.com (moderated for non-subscribers) +W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/ +S: Maintained + MICROTEK X6 SCANNER P: Oliver Neukum M: oliver@neukum.name @@ -3166,15 +3170,6 @@ M: olof@lixom.net L: i2c@lm-sensors.org S: Maintained -PANASONIC MN10300/AM33 PORT -P: David Howells -M: dhowells@redhat.com -P: Koichi Yasutake -M: yasutake.koichi@jp.panasonic.com -L: linux-am33-list@redhat.com (moderated for non-subscribers) -W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/ -S: Maintained - PARALLEL PORT SUPPORT L: linux-parport@lists.infradead.org (subscribers-only) S: Orphan @@ -4094,7 +4089,7 @@ W: http://tpmdd.sourceforge.net P: Marcel Selhorst M: tpm@selhorst.net W: http://www.prosec.rub.de/tpm/ -L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) +L: tpmdd-devel@lists.sourceforge.net S: Maintained TRIVIAL PATCHES @@ -4485,13 +4480,6 @@ W: http://kernel.org/~kzak/util-linux-ng/ T: git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git S: Maintained -UVESAFB DRIVER -P: Michal Januszewski -M: spock@gentoo.org -L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) -W: http://dev.gentoo.org/~spock/projects/uvesafb/ -S: Maintained - VFAT/FAT/MSDOS FILESYSTEM P: OGAWA Hirofumi M: hirofumi@mail.parknet.co.jp @@ -4509,14 +4497,6 @@ M: khali@linux-fr.org L: i2c@lm-sensors.org S: Maintained -VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER -P: Joseph Chan -M: JosephChan@via.com.tw -P: Scott Fang -M: ScottFang@viatech.com.cn -L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) -S: Maintained - VIA VELOCITY NETWORK DRIVER P: Francois Romieu M: romieu@fr.zoreil.com @@ -4540,11 +4520,10 @@ S: Maintained VOLTAGE AND CURRENT REGULATOR FRAMEWORK P: Liam Girdwood -M: lrg@slimlogic.co.uk +M: lg@opensource.wolfsonmicro.com P: Mark Brown M: broonie@opensource.wolfsonmicro.com W: http://opensource.wolfsonmicro.com/node/15 -W: http://www.slimlogic.co.uk/?page_id=5 T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git S: Supported @@ -4618,7 +4597,7 @@ WM97XX TOUCHSCREEN DRIVERS P: Mark Brown M: broonie@opensource.wolfsonmicro.com P: Liam Girdwood -M: lrg@slimlogic.co.uk +M: liam.girdwood@wolfsonmicro.com L: linux-input@vger.kernel.org T: git git://opensource.wolfsonmicro.com/linux-2.6-touch W: http://opensource.wolfsonmicro.com/node/7 diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index e6ab550bceb3..364c6dadde0a 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -13,22 +13,8 @@ config OPROFILE If unsure, say N. -config OPROFILE_IBS - bool "OProfile AMD IBS support (EXPERIMENTAL)" - default n - depends on OPROFILE && SMP && X86 - help - Instruction-Based Sampling (IBS) is a new profiling - technique that provides rich, precise program performance - information. IBS is introduced by AMD Family10h processors - (AMD Opteron Quad-Core processor “Barcelonaâ€) to overcome - the limitations of conventional performance counter - sampling. - - If unsure, say N. - config HAVE_OPROFILE - bool + def_bool n config KPROBES bool "Kprobes" @@ -42,7 +28,7 @@ config KPROBES If in doubt, say "N". config HAVE_EFFICIENT_UNALIGNED_ACCESS - bool + def_bool n help Some architectures are unable to perform unaligned accesses without the use of get_unaligned/put_unaligned. Others are @@ -65,13 +51,13 @@ config KRETPROBES depends on KPROBES && HAVE_KRETPROBES config HAVE_IOREMAP_PROT - bool + def_bool n config HAVE_KPROBES - bool + def_bool n config HAVE_KRETPROBES - bool + def_bool n # # An arch should select this if it provides all these things: @@ -89,16 +75,16 @@ config HAVE_KRETPROBES # signal delivery calls tracehook_signal_handler() # config HAVE_ARCH_TRACEHOOK - bool + def_bool n config HAVE_DMA_ATTRS - bool + def_bool n config USE_GENERIC_SMP_HELPERS - bool + def_bool n config HAVE_CLK - bool + def_bool n help The calls support software clock gating and thus are a key power management tool on many systems. diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index a0f642b6a4b9..1bec55d63ef6 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -5,7 +5,6 @@ config ALPHA bool default y - select HAVE_AOUT select HAVE_IDE select HAVE_OPROFILE help @@ -69,6 +68,9 @@ config AUTO_IRQ_AFFINITY depends on SMP default y +config ARCH_SUPPORTS_AOUT + def_bool y + source "init/Kconfig" @@ -222,7 +224,8 @@ config ALPHA_MIATA bool "Miata" help The Digital PersonalWorkStation (PWS 433a, 433au, 500a, 500au, 600a, - or 600au). + or 600au). There is an Installation HOWTO for this hardware at + . config ALPHA_MIKASA bool "Mikasa" diff --git a/trunk/arch/alpha/include/asm/a.out.h b/trunk/arch/alpha/include/asm/a.out.h index acdc681231cb..02ce8473870a 100644 --- a/trunk/arch/alpha/include/asm/a.out.h +++ b/trunk/arch/alpha/include/asm/a.out.h @@ -95,7 +95,7 @@ struct exec Worse, we have to notice the start address before swapping to use /sbin/loader, which of course is _not_ a TASO application. */ #define SET_AOUT_PERSONALITY(BFPM, EX) \ - set_personality (((BFPM->taso || EX.ah.entry < 0x100000000L \ + set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \ ? ADDR_LIMIT_32BIT : 0) | PER_OSF4)) #endif /* __KERNEL__ */ diff --git a/trunk/arch/alpha/include/asm/elf.h b/trunk/arch/alpha/include/asm/elf.h index 5c75c1b2352a..fc1002ea1e0c 100644 --- a/trunk/arch/alpha/include/asm/elf.h +++ b/trunk/arch/alpha/include/asm/elf.h @@ -144,9 +144,9 @@ extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task); : amask (AMASK_CIX) ? "ev6" : "ev67"); \ }) -#define SET_PERSONALITY(EX) \ +#define SET_PERSONALITY(EX, IBCS2) \ set_personality(((EX).e_flags & EF_ALPHA_32BIT) \ - ? PER_LINUX_32BIT : PER_LINUX) + ? PER_LINUX_32BIT : (IBCS2) ? PER_SVR4 : PER_LINUX) extern int alpha_l1i_cacheshape; extern int alpha_l1d_cacheshape; diff --git a/trunk/arch/alpha/include/asm/statfs.h b/trunk/arch/alpha/include/asm/statfs.h index de35cd438a10..ad15830baefe 100644 --- a/trunk/arch/alpha/include/asm/statfs.h +++ b/trunk/arch/alpha/include/asm/statfs.h @@ -1,10 +1,6 @@ #ifndef _ALPHA_STATFS_H #define _ALPHA_STATFS_H -/* Alpha is the only 64-bit platform with 32-bit statfs. And doesn't - even seem to implement statfs64 */ -#define __statfs_word __u32 - #include #endif diff --git a/trunk/arch/alpha/kernel/pci_iommu.c b/trunk/arch/alpha/kernel/pci_iommu.c index b9094da05d7a..2179c602032a 100644 --- a/trunk/arch/alpha/kernel/pci_iommu.c +++ b/trunk/arch/alpha/kernel/pci_iommu.c @@ -41,6 +41,13 @@ mk_iommu_pte(unsigned long paddr) return (paddr >> (PAGE_SHIFT-1)) | 1; } +static inline long +calc_npages(long bytes) +{ + return (bytes + PAGE_SIZE - 1) >> PAGE_SHIFT; +} + + /* Return the minimum of MAX or the first power of two larger than main memory. */ @@ -280,7 +287,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, if (!arena || arena->dma_base + arena->size - 1 > max_dma) arena = hose->sg_isa; - npages = iommu_num_pages(paddr, size, PAGE_SIZE); + npages = calc_npages((paddr & ~PAGE_MASK) + size); /* Force allocation to 64KB boundary for ISA bridges. */ if (pdev && pdev == isa_bridge) @@ -380,7 +387,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, BUG(); } - npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); + npages = calc_npages((dma_addr & ~PAGE_MASK) + size); spin_lock_irqsave(&arena->lock, flags); @@ -573,7 +580,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, contiguous. */ paddr &= ~PAGE_MASK; - npages = iommu_num_pages(paddr, size, PAGE_SIZE); + npages = calc_npages(paddr + size); dma_ofs = iommu_arena_alloc(dev, arena, npages, 0); if (dma_ofs < 0) { /* If we attempted a direct map above but failed, die. */ @@ -609,7 +616,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, sg++; } - npages = iommu_num_pages(paddr, size, PAGE_SIZE); + npages = calc_npages((paddr & ~PAGE_MASK) + size); paddr &= PAGE_MASK; for (i = 0; i < npages; ++i, paddr += PAGE_SIZE) @@ -768,7 +775,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, DBGA(" (%ld) sg [%lx,%lx]\n", sg - end + nents, addr, size); - npages = iommu_num_pages(addr, size, PAGE_SIZE); + npages = calc_npages((addr & ~PAGE_MASK) + size); ofs = (addr - arena->dma_base) >> PAGE_SHIFT; iommu_arena_free(arena, ofs, npages); diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index e657c45d91d2..06b6fdab639f 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 4853f9df37bd..efeed65b4a66 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration" config ARM bool default y - select HAVE_AOUT select HAVE_IDE select RTC_LIB select SYS_SUPPORTS_APM_EMULATION @@ -141,6 +140,9 @@ config GENERIC_CALIBRATE_DELAY bool default y +config ARCH_SUPPORTS_AOUT + def_bool y + config ARCH_MAY_HAVE_PC_FDC bool diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 7d5121260fda..e2274bc0b544 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -118,10 +118,9 @@ endif machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx machine-$(CONFIG_ARCH_OMAP1) := omap1 machine-$(CONFIG_ARCH_OMAP2) := omap2 - machine-$(CONFIG_ARCH_OMAP3) := omap2 plat-$(CONFIG_ARCH_OMAP) := omap machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 - plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c + plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_IMX) := imx diff --git a/trunk/arch/arm/configs/omap3_beagle_defconfig b/trunk/arch/arm/configs/omap3_beagle_defconfig deleted file mode 100644 index e042d27eae16..000000000000 --- a/trunk/arch/arm/configs/omap3_beagle_defconfig +++ /dev/null @@ -1,1321 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc8 -# Wed Oct 1 17:14:22 2008 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_MMU=y -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_HARDIRQS=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_SUPPORTS_AOUT=y -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set -# CONFIG_HAVE_IOREMAP_PROT is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -# CONFIG_USE_GENERIC_SMP_HELPERS is not set -CONFIG_HAVE_CLK=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_ARCH_OMAP=y -# CONFIG_ARCH_MSM7X00A is not set - -# -# TI OMAP Implementations -# -CONFIG_ARCH_OMAP_OTG=y -# CONFIG_ARCH_OMAP1 is not set -# CONFIG_ARCH_OMAP2 is not set -CONFIG_ARCH_OMAP3=y - -# -# OMAP Feature Selections -# -# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set -# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set -# CONFIG_OMAP_RESET_CLOCKS is not set -# CONFIG_OMAP_MUX is not set -# CONFIG_OMAP_MCBSP is not set -# CONFIG_OMAP_MPU_TIMER is not set -CONFIG_OMAP_32K_TIMER=y -CONFIG_OMAP_32K_TIMER_HZ=128 -CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_LL_DEBUG_UART1 is not set -# CONFIG_OMAP_LL_DEBUG_UART2 is not set -CONFIG_OMAP_LL_DEBUG_UART3=y -CONFIG_ARCH_OMAP34XX=y -CONFIG_ARCH_OMAP3430=y - -# -# OMAP Board Type -# -CONFIG_MACH_OMAP3_BEAGLE=y - -# -# Boot options -# - -# -# Power management -# - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_V7=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_IFAR=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_HAS_TLS_REG=y -# CONFIG_OUTER_CACHE is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PREEMPT is not set -CONFIG_HZ=128 -CONFIG_AEABI=y -CONFIG_OABI_COMPAT=y -CONFIG_ARCH_FLATMEM_HAS_HOLES=y -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_LEDS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8" -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set - -# -# CPU Power Management -# -# CONFIG_CPU_FREQ is not set -# CONFIG_CPU_IDLE is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y -CONFIG_VFPv3=y -# CONFIG_NEON is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_MISC=y - -# -# Power management options -# -# CONFIG_PM is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_ALAUDA is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_NET_ETHERNET is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -CONFIG_I2C_OMAP=y -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_AT24 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_ISP1301_OMAP is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -# CONFIG_HID_SUPPORT is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=y - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_MUSB_HDRC=y -CONFIG_USB_MUSB_SOC=y - -# -# OMAP 343x high speed USB support -# -CONFIG_USB_MUSB_HOST=y -# CONFIG_USB_MUSB_PERIPHERAL is not set -# CONFIG_USB_MUSB_OTG is not set -# CONFIG_USB_GADGET_MUSB_HDRC is not set -CONFIG_USB_MUSB_HDRC_HCD=y -# CONFIG_MUSB_PIO_ONLY is not set -CONFIG_USB_INVENTRA_DMA=y -# CONFIG_USB_TI_CPPI_DMA is not set -# CONFIG_USB_MUSB_DEBUG is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set -# CONFIG_USB_GADGET_ATMEL_USBA is not set -# CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA25X is not set -CONFIG_USB_GADGET_M66592=y -CONFIG_USB_M66592=y -# CONFIG_USB_GADGET_PXA27X is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_PRINTER is not set -# CONFIG_USB_CDC_COMPOSITE is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set - -# -# MMC/SD Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_OMAP is not set -# CONFIG_MEMSTICK is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_NEW_LEDS is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set - -# -# Voltage and Current regulators -# -# CONFIG_REGULATOR is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_QUOTA=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -CONFIG_FRAME_POINTER=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_HAVE_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_LL is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_GENERIC_FIND_NEXT_BIT is not set -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/arm/configs/omap_ldp_defconfig b/trunk/arch/arm/configs/omap_ldp_defconfig deleted file mode 100644 index 948a212fb1cc..000000000000 --- a/trunk/arch/arm/configs/omap_ldp_defconfig +++ /dev/null @@ -1,1044 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc5 -# Fri Oct 10 11:49:41 2008 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_MMU=y -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_HARDIRQS=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_SUPPORTS_AOUT=y -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set -# CONFIG_HAVE_IOREMAP_PROT is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -# CONFIG_USE_GENERIC_SMP_HELPERS is not set -CONFIG_HAVE_CLK=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_ARCH_OMAP=y -# CONFIG_ARCH_MSM7X00A is not set - -# -# TI OMAP Implementations -# -CONFIG_ARCH_OMAP_OTG=y -# CONFIG_ARCH_OMAP1 is not set -# CONFIG_ARCH_OMAP2 is not set -CONFIG_ARCH_OMAP3=y - -# -# OMAP Feature Selections -# -# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set -# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set -# CONFIG_OMAP_RESET_CLOCKS is not set -CONFIG_OMAP_MUX=y -CONFIG_OMAP_MUX_DEBUG=y -CONFIG_OMAP_MUX_WARNINGS=y -CONFIG_OMAP_MCBSP=y -# CONFIG_OMAP_MPU_TIMER is not set -CONFIG_OMAP_32K_TIMER=y -CONFIG_OMAP_32K_TIMER_HZ=128 -CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_LL_DEBUG_UART1 is not set -# CONFIG_OMAP_LL_DEBUG_UART2 is not set -CONFIG_OMAP_LL_DEBUG_UART3=y -CONFIG_OMAP_SERIAL_WAKE=y -CONFIG_ARCH_OMAP34XX=y -CONFIG_ARCH_OMAP3430=y - -# -# OMAP Board Type -# -# CONFIG_MACH_OMAP3_BEAGLE is not set -CONFIG_MACH_OMAP_LDP=y -# CONFIG_MACH_OVERO is not set - -# -# Boot options -# - -# -# Power management -# - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_V7=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_IFAR=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_HAS_TLS_REG=y -# CONFIG_OUTER_CACHE is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_PREEMPT is not set -CONFIG_HZ=128 -CONFIG_AEABI=y -CONFIG_OABI_COMPAT=y -CONFIG_ARCH_FLATMEM_HAS_HOLES=y -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_LEDS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8" -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y -CONFIG_VFPv3=y -# CONFIG_NEON is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_MISC=y - -# -# Power management options -# -# CONFIG_PM is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_NET is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -CONFIG_I2C_OMAP=y -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_AT24 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_ISP1301_OMAP is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_BITBANG is not set -CONFIG_SPI_OMAP24XX=y - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -CONFIG_W1=y - -# -# 1-wire Bus Masters -# -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS1WM is not set -# CONFIG_W1_MASTER_GPIO is not set - -# -# 1-wire Slaves -# -# CONFIG_W1_SLAVE_THERM is not set -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2760 is not set -CONFIG_POWER_SUPPLY=y -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_BATTERY_DS2760 is not set -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_SOUND=y -CONFIG_SND=y -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -CONFIG_SND_ARM=y -CONFIG_SND_SPI=y -# CONFIG_SND_SOC is not set -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -# CONFIG_USB_SUPPORT is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set - -# -# MMC/SD Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_OMAP is not set -# CONFIG_MMC_SPI is not set -# CONFIG_NEW_LEDS is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set - -# -# Voltage and Current regulators -# -# CONFIG_REGULATOR is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_QUOTA=y -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -CONFIG_FRAME_POINTER=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_HAVE_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_GENERIC_FIND_NEXT_BIT is not set -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC_T10DIF=y -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/arm/configs/overo_defconfig b/trunk/arch/arm/configs/overo_defconfig deleted file mode 100644 index 49200967a153..000000000000 --- a/trunk/arch/arm/configs/overo_defconfig +++ /dev/null @@ -1,1885 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc8 -# Fri Oct 3 11:50:34 2008 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_MMU=y -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_HARDIRQS=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_SUPPORTS_AOUT=y -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_OPROFILE_ARMV7=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -# CONFIG_ELF_CORE is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set -# CONFIG_HAVE_IOREMAP_PROT is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -# CONFIG_USE_GENERIC_SMP_HELPERS is not set -CONFIG_HAVE_CLK=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -CONFIG_LSF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_ARCH_OMAP=y -# CONFIG_ARCH_MSM7X00A is not set - -# -# TI OMAP Implementations -# -CONFIG_ARCH_OMAP_OTG=y -# CONFIG_ARCH_OMAP1 is not set -# CONFIG_ARCH_OMAP2 is not set -CONFIG_ARCH_OMAP3=y - -# -# OMAP Feature Selections -# -# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set -# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set -# CONFIG_OMAP_RESET_CLOCKS is not set -# CONFIG_OMAP_MUX is not set -CONFIG_OMAP_MCBSP=y -# CONFIG_OMAP_MPU_TIMER is not set -CONFIG_OMAP_32K_TIMER=y -CONFIG_OMAP_32K_TIMER_HZ=128 -CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_LL_DEBUG_UART1 is not set -# CONFIG_OMAP_LL_DEBUG_UART2 is not set -CONFIG_OMAP_LL_DEBUG_UART3=y -CONFIG_ARCH_OMAP34XX=y -CONFIG_ARCH_OMAP3430=y - -# -# OMAP Board Type -# -# CONFIG_MACH_OMAP3_BEAGLE is not set -CONFIG_MACH_OVERO=y - -# -# Boot options -# - -# -# Power management -# - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_V7=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_IFAR=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_HAS_TLS_REG=y -# CONFIG_OUTER_CACHE is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PREEMPT is not set -CONFIG_HZ=128 -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_ARCH_FLATMEM_HAS_HOLES=y -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_LEDS=y -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE=" debug " -# CONFIG_XIP_KERNEL is not set -CONFIG_KEXEC=y -CONFIG_ATAGS_PROC=y - -# -# CPU Power Management -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -# CONFIG_CPU_FREQ_DEBUG is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_STAT_DETAILS=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -# CONFIG_CPU_IDLE is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_NEON=y - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_MISC=y - -# -# Power management options -# -# CONFIG_PM is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m -CONFIG_IPV6_NDISC_NODETYPE=y -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y -# CONFIG_BT_HCIBTUSB is not set -# CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -# CONFIG_BT_HCIUART_LL is not set -CONFIG_BT_HCIBCM203X=y -CONFIG_BT_HCIBPA10X=y -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -CONFIG_CFG80211=y -CONFIG_NL80211=y -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -CONFIG_MAC80211=y - -# -# Rate control algorithm selection -# -CONFIG_MAC80211_RC_PID=y -CONFIG_MAC80211_RC_DEFAULT_PID=y -CONFIG_MAC80211_RC_DEFAULT="pid" -# CONFIG_MAC80211_MESH is not set -CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_IEEE80211=y -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=y -CONFIG_IEEE80211_CRYPT_CCMP=y -CONFIG_IEEE80211_CRYPT_TKIP=y -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_ALAUDA is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=m -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_BLK_DEV_XIP is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -CONFIG_EEPROM_93CX6=m -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_RAID5_RESHAPE=y -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -CONFIG_DM_DELAY=m -# CONFIG_DM_UEVENT is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m -# CONFIG_VETH is not set -# CONFIG_NET_ETHERNET is not set -CONFIG_MII=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -CONFIG_LIBERTAS=y -CONFIG_LIBERTAS_USB=y -CONFIG_LIBERTAS_SDIO=y -CONFIG_LIBERTAS_DEBUG=y -CONFIG_USB_ZD1201=m -# CONFIG_USB_NET_RNDIS_WLAN is not set -CONFIG_RTL8187=m -# CONFIG_MAC80211_HWSIM is not set -CONFIG_P54_COMMON=m -CONFIG_P54_USB=m -# CONFIG_IWLWIFI_LEDS is not set -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -# CONFIG_ZD1211RW is not set -# CONFIG_RT2X00 is not set - -# -# USB Network Adapters -# -CONFIG_USB_CATC=m -CONFIG_USB_KAWETH=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_USBNET=y -CONFIG_USB_NET_AX8817X=y -CONFIG_USB_NET_CDCETHER=y -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_NET1080=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_NET_RNDIS_HOST=m -CONFIG_USB_NET_CDC_SUBSET=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_BELKIN=y -CONFIG_USB_ARMLINUX=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_ZAURUS=m -# CONFIG_WAN is not set -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -# CONFIG_PPPOL2TP is not set -# CONFIG_SLIP is not set -CONFIG_SLHC=m -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_GPIO is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -CONFIG_I2C_OMAP=y -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_AT24 is not set -CONFIG_SENSORS_EEPROM=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_ISP1301_OMAP is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_BITBANG is not set -CONFIG_SPI_OMAP24XX=y - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -CONFIG_DEBUG_GPIO=y -CONFIG_GPIO_SYSFS=y - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_W1 is not set -CONFIG_POWER_SUPPLY=m -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_BATTERY_DS2760 is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADCXX is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_COMMON=m -CONFIG_VIDEO_ALLOW_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -CONFIG_DVB_CORE=m -CONFIG_VIDEO_MEDIA=m - -# -# Multimedia drivers -# -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_TUNER=m -# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_VIDEO_V4L2=m -CONFIG_VIDEO_V4L1=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_VIDEO_TUNER=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_CX25840=m -CONFIG_VIDEO_CX2341X=m -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_TUNER_3036 is not set -# CONFIG_VIDEO_AU0828 is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -# CONFIG_USB_GSPCA is not set -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_PVRUSB2_DVB=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -# CONFIG_VIDEO_EM28XX is not set -CONFIG_VIDEO_USBVISION=m -CONFIG_VIDEO_USBVIDEO=m -CONFIG_USB_VICAM=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_QUICKCAM_MESSENGER=m -# CONFIG_USB_ET61X251 is not set -CONFIG_VIDEO_OVCAMCHIP=m -CONFIG_USB_W9968CF=m -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -# CONFIG_USB_ZC0301 is not set -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -CONFIG_USB_ZR364XX=m -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_S2255 is not set -# CONFIG_SOC_CAMERA is not set -# CONFIG_VIDEO_SH_MOBILE_CEU is not set -CONFIG_RADIO_ADAPTERS=y -# CONFIG_USB_DSBR is not set -# CONFIG_USB_SI470X is not set -CONFIG_DVB_CAPTURE_DRIVERS=y -# CONFIG_TTPCI_EEPROM is not set - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -# CONFIG_DVB_USB_DW2102 is not set -# CONFIG_DVB_USB_ANYSEE is not set -CONFIG_DVB_TTUSB_BUDGET=m -CONFIG_DVB_TTUSB_DEC=m -CONFIG_DVB_CINERGYT2=m -# CONFIG_DVB_CINERGYT2_TUNING is not set -# CONFIG_DVB_SIANO_SMS1XXX is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -# CONFIG_DVB_B2C2_FLEXCOP is not set - -# -# Supported DVB Frontends -# - -# -# Customise DVB Frontends -# -# CONFIG_DVB_FE_CUSTOMISE is not set - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24110=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -# CONFIG_DVB_DRX397XD is not set -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_TDA10048=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -# CONFIG_DVB_OR51211 is not set -# CONFIG_DVB_OR51132 is not set -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_S5H1411=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_LNBP21=m -# CONFIG_DVB_ISL6405 is not set -CONFIG_DVB_ISL6421=m -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -CONFIG_DISPLAY_SUPPORT=y - -# -# Display hardware drivers -# - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=y -CONFIG_SND_RAWMIDI=y -CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_PCM_OSS_PLUGINS=y -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -CONFIG_SND_VERBOSE_PRINTK=y -CONFIG_SND_DEBUG=y -# CONFIG_SND_DEBUG_VERBOSE is not set -# CONFIG_SND_PCM_XRUN_DEBUG is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -CONFIG_SND_ARM=y -CONFIG_SND_SPI=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=y -CONFIG_SND_USB_CAIAQ=m -CONFIG_SND_USB_CAIAQ_INPUT=y -CONFIG_SND_SOC=y -CONFIG_SND_OMAP_SOC=y -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -CONFIG_HID_DEBUG=y -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y -CONFIG_USB_DEBUG=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=y - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_MUSB_HDRC=y -CONFIG_USB_MUSB_SOC=y - -# -# OMAP 343x high speed USB support -# -CONFIG_USB_MUSB_HOST=y -# CONFIG_USB_MUSB_PERIPHERAL is not set -# CONFIG_USB_MUSB_OTG is not set -CONFIG_USB_MUSB_HDRC_HCD=y -CONFIG_MUSB_PIO_ONLY=y -# CONFIG_USB_MUSB_DEBUG is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_WDM=y - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_EZUSB is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_CH341 is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MOTOROLA is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_DEBUG is not set - -# -# USB Miscellaneous drivers -# -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_RIO500 is not set -CONFIG_USB_LEGOTOWER=m -CONFIG_USB_LCD=m -# CONFIG_USB_BERRY_CHARGE is not set -CONFIG_USB_LED=m -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_GADGET is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_UNSAFE_RESUME=y - -# -# MMC/SD Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_BOUNCE=y -CONFIG_SDIO_UART=y -# CONFIG_MMC_TEST is not set - -# -# MMC/SD Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_OMAP is not set -# CONFIG_MMC_SPI is not set -# CONFIG_MEMSTICK is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -# CONFIG_LEDS_PCA955X is not set - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set - -# -# Voltage and Current regulators -# -# CONFIG_REGULATOR is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_DEBUG is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_QUOTA=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_SUMMARY=y -CONFIG_JFFS2_FS_XATTR=y -CONFIG_JFFS2_FS_POSIX_ACL=y -CONFIG_JFFS2_FS_SECURITY=y -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_LZO=y -CONFIG_JFFS2_RTIME=y -CONFIG_JFFS2_RUBIN=y -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -# CONFIG_JFFS2_CMODE_FAVOURLZO is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -CONFIG_FRAME_POINTER=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_HAVE_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_LL is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=m -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_CRYPTD=m -# CONFIG_CRYPTO_AUTHENC is not set -CONFIG_CRYPTO_TEST=m - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=m -CONFIG_CRYPTO_XCBC=m - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=y -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_WP512=m - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_KHAZAD=m -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_GENERIC_FIND_NEXT_BIT is not set -CONFIG_CRC_CCITT=y -CONFIG_CRC16=m -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -CONFIG_CRC7=y -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/arm/include/asm/elf.h b/trunk/arch/arm/include/asm/elf.h index a58378c343b9..5be016980c19 100644 --- a/trunk/arch/arm/include/asm/elf.h +++ b/trunk/arch/arm/include/asm/elf.h @@ -107,6 +107,6 @@ extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int); #define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0 extern void elf_set_personality(const struct elf32_hdr *); -#define SET_PERSONALITY(ex) elf_set_personality(&(ex)) +#define SET_PERSONALITY(ex, ibcs2) elf_set_personality(&(ex)) #endif diff --git a/trunk/arch/arm/include/asm/statfs.h b/trunk/arch/arm/include/asm/statfs.h index 079447c05ba7..a02e6a8c3d70 100644 --- a/trunk/arch/arm/include/asm/statfs.h +++ b/trunk/arch/arm/include/asm/statfs.h @@ -1,12 +1,42 @@ #ifndef _ASMARM_STATFS_H #define _ASMARM_STATFS_H +#ifndef __KERNEL_STRICT_NAMES +# include +typedef __kernel_fsid_t fsid_t; +#endif + +struct statfs { + __u32 f_type; + __u32 f_bsize; + __u32 f_blocks; + __u32 f_bfree; + __u32 f_bavail; + __u32 f_files; + __u32 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +}; + /* * With EABI there is 4 bytes of padding added to this structure. * Let's pack it so the padding goes away to simplify dual ABI support. * Note that user space does NOT have to pack this structure. */ -#define ARCH_PACK_STATFS64 __attribute__((packed,aligned(4))) +struct statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +} __attribute__ ((packed,aligned(4))); -#include #endif diff --git a/trunk/arch/arm/kernel/dma.c b/trunk/arch/arm/kernel/dma.c index d006085ed7e7..ba99a2035523 100644 --- a/trunk/arch/arm/kernel/dma.c +++ b/trunk/arch/arm/kernel/dma.c @@ -25,6 +25,23 @@ EXPORT_SYMBOL(dma_spin_lock); static dma_t dma_chan[MAX_DMA_CHANNELS]; +/* + * Get dma list for /proc/dma + */ +int get_dma_list(char *buf) +{ + dma_t *dma; + char *p = buf; + int i; + + for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++) + if (dma->lock) + p += sprintf(p, "%2d: %14s %s\n", i, + dma->d_ops->type, dma->device_id); + + return p - buf; +} + /* * Request DMA channel * diff --git a/trunk/arch/arm/mach-integrator/cpu.c b/trunk/arch/arm/mach-integrator/cpu.c index 44d4c2e8207b..e4f72d202cc0 100644 --- a/trunk/arch/arm/mach-integrator/cpu.c +++ b/trunk/arch/arm/mach-integrator/cpu.c @@ -184,6 +184,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy) { /* set default policy and cpuinfo */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.max_freq = 160000; policy->cpuinfo.min_freq = 12000; policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */ diff --git a/trunk/arch/arm/mach-omap1/board-h3.c b/trunk/arch/arm/mach-omap1/board-h3.c index adfcd7b51393..2ced6d9984d2 100644 --- a/trunk/arch/arm/mach-omap1/board-h3.c +++ b/trunk/arch/arm/mach-omap1/board-h3.c @@ -476,10 +476,6 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = { I2C_BOARD_INFO("tps65013", 0x48), /* .irq = OMAP_GPIO_IRQ(??), */ }, - { - I2C_BOARD_INFO("isp1301_omap", 0x2d), - .irq = OMAP_GPIO_IRQ(14), - }, }; static struct omap_gpio_switch h3_gpio_switches[] __initdata = { diff --git a/trunk/arch/arm/mach-omap1/clock.c b/trunk/arch/arm/mach-omap1/clock.c index 5fba20731710..478c2c9a22cb 100644 --- a/trunk/arch/arm/mach-omap1/clock.c +++ b/trunk/arch/arm/mach-omap1/clock.c @@ -201,7 +201,7 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) return -EINVAL; parent = clk->parent; - if (unlikely(parent == NULL)) + if (unlikely(parent == 0)) return -EIO; realrate = parent->rate; @@ -499,7 +499,7 @@ static int omap1_clk_enable_generic(struct clk *clk) if (clk->flags & ALWAYS_ENABLED) return 0; - if (unlikely(clk->enable_reg == NULL)) { + if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); return -EINVAL; @@ -535,7 +535,7 @@ static void omap1_clk_disable_generic(struct clk *clk) __u16 regval16; __u32 regval32; - if (clk->enable_reg == NULL) + if (clk->enable_reg == 0) return; if (clk->flags & ENABLE_REG_32BIT) { @@ -577,7 +577,7 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) return clk->parent->rate / (1 << dsor_exp); } - if (clk->round_rate != NULL) + if(clk->round_rate != 0) return clk->round_rate(clk, rate); return clk->rate; @@ -625,7 +625,7 @@ static void __init omap1_clk_disable_unused(struct clk *clk) /* Clocks in the DSP domain need api_ck. Just assume bootloader * has not enabled any DSP clocks */ - if (clk->enable_reg == DSP_IDLECT2) { + if ((u32)clk->enable_reg == DSP_IDLECT2) { printk(KERN_INFO "Skipping reset check for DSP domain " "clock \"%s\"\n", clk->name); return; diff --git a/trunk/arch/arm/mach-omap1/clock.h b/trunk/arch/arm/mach-omap1/clock.h index 5635b511ab6f..6eadf72828d8 100644 --- a/trunk/arch/arm/mach-omap1/clock.h +++ b/trunk/arch/arm/mach-omap1/clock.h @@ -324,7 +324,7 @@ static struct clk dspper_ck = { .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL | VIRTUAL_IO_ADDRESS, - .enable_reg = DSP_IDLECT2, + .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_PERCK, .rate_offset = CKCTL_PERDIV_OFFSET, .recalc = &omap1_ckctl_recalc_dsp_domain, @@ -338,7 +338,7 @@ static struct clk dspxor_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_IO_ADDRESS, - .enable_reg = DSP_IDLECT2, + .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_XORPCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable_dsp_domain, @@ -350,7 +350,7 @@ static struct clk dsptim_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_IO_ADDRESS, - .enable_reg = DSP_IDLECT2, + .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_DSPTIMCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable_dsp_domain, diff --git a/trunk/arch/arm/mach-omap1/devices.c b/trunk/arch/arm/mach-omap1/devices.c index e382b438c64e..99982d3380c9 100644 --- a/trunk/arch/arm/mach-omap1/devices.c +++ b/trunk/arch/arm/mach-omap1/devices.c @@ -101,7 +101,7 @@ static inline void omap_init_mbox(void) { } #if defined(CONFIG_OMAP_STI) -#define OMAP1_STI_BASE 0xfffea000 +#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000) #define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400) static struct resource sti_resources[] = { diff --git a/trunk/arch/arm/mach-omap1/mcbsp.c b/trunk/arch/arm/mach-omap1/mcbsp.c index 7de7c6915584..2baeaeb0c900 100644 --- a/trunk/arch/arm/mach-omap1/mcbsp.c +++ b/trunk/arch/arm/mach-omap1/mcbsp.c @@ -103,6 +103,30 @@ static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) { } #endif +static int omap1_mcbsp_check(unsigned int id) +{ + /* REVISIT: Check correctly for number of registered McBSPs */ + if (cpu_is_omap730()) { + if (id > OMAP_MAX_MCBSP_COUNT - 2) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", + id + 1); + return -ENODEV; + } + return 0; + } + + if (cpu_is_omap15xx() || cpu_is_omap16xx()) { + if (id > OMAP_MAX_MCBSP_COUNT - 1) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", + id + 1); + return -ENODEV; + } + return 0; + } + + return -ENODEV; +} + static void omap1_mcbsp_request(unsigned int id) { /* @@ -127,6 +151,7 @@ static void omap1_mcbsp_free(unsigned int id) } static struct omap_mcbsp_ops omap1_mcbsp_ops = { + .check = omap1_mcbsp_check, .request = omap1_mcbsp_request, .free = omap1_mcbsp_free, }; @@ -135,6 +160,7 @@ static struct omap_mcbsp_ops omap1_mcbsp_ops = { static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = { { .phys_base = OMAP730_MCBSP1_BASE, + .virt_base = io_p2v(OMAP730_MCBSP1_BASE), .dma_rx_sync = OMAP_DMA_MCBSP1_RX, .dma_tx_sync = OMAP_DMA_MCBSP1_TX, .rx_irq = INT_730_McBSP1RX, @@ -143,6 +169,7 @@ static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = { }, { .phys_base = OMAP730_MCBSP2_BASE, + .virt_base = io_p2v(OMAP730_MCBSP2_BASE), .dma_rx_sync = OMAP_DMA_MCBSP3_RX, .dma_tx_sync = OMAP_DMA_MCBSP3_TX, .rx_irq = INT_730_McBSP2RX, @@ -160,6 +187,7 @@ static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = { static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { { .phys_base = OMAP1510_MCBSP1_BASE, + .virt_base = OMAP1510_MCBSP1_BASE, .dma_rx_sync = OMAP_DMA_MCBSP1_RX, .dma_tx_sync = OMAP_DMA_MCBSP1_TX, .rx_irq = INT_McBSP1RX, @@ -169,6 +197,7 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { }, { .phys_base = OMAP1510_MCBSP2_BASE, + .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), .dma_rx_sync = OMAP_DMA_MCBSP2_RX, .dma_tx_sync = OMAP_DMA_MCBSP2_TX, .rx_irq = INT_1510_SPI_RX, @@ -177,6 +206,7 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { }, { .phys_base = OMAP1510_MCBSP3_BASE, + .virt_base = OMAP1510_MCBSP3_BASE, .dma_rx_sync = OMAP_DMA_MCBSP3_RX, .dma_tx_sync = OMAP_DMA_MCBSP3_TX, .rx_irq = INT_McBSP3RX, @@ -195,6 +225,7 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { { .phys_base = OMAP1610_MCBSP1_BASE, + .virt_base = OMAP1610_MCBSP1_BASE, .dma_rx_sync = OMAP_DMA_MCBSP1_RX, .dma_tx_sync = OMAP_DMA_MCBSP1_TX, .rx_irq = INT_McBSP1RX, @@ -204,6 +235,7 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { }, { .phys_base = OMAP1610_MCBSP2_BASE, + .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), .dma_rx_sync = OMAP_DMA_MCBSP2_RX, .dma_tx_sync = OMAP_DMA_MCBSP2_TX, .rx_irq = INT_1610_McBSP2_RX, @@ -212,6 +244,7 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { }, { .phys_base = OMAP1610_MCBSP3_BASE, + .virt_base = OMAP1610_MCBSP3_BASE, .dma_rx_sync = OMAP_DMA_MCBSP3_RX, .dma_tx_sync = OMAP_DMA_MCBSP3_TX, .rx_irq = INT_McBSP3RX, @@ -237,18 +270,6 @@ int __init omap1_mcbsp_init(void) } } - if (cpu_is_omap730()) - omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ; - if (cpu_is_omap15xx()) - omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ; - if (cpu_is_omap16xx()) - omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ; - - mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), - GFP_KERNEL); - if (!mcbsp_ptr) - return -ENOMEM; - if (cpu_is_omap730()) omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata, OMAP730_MCBSP_PDATA_SZ); diff --git a/trunk/arch/arm/mach-omap1/serial.c b/trunk/arch/arm/mach-omap1/serial.c index 528691d5cb51..aefc967fc003 100644 --- a/trunk/arch/arm/mach-omap1/serial.c +++ b/trunk/arch/arm/mach-omap1/serial.c @@ -67,8 +67,8 @@ static void __init omap_serial_reset(struct plat_serial8250_port *p) static struct plat_serial8250_port serial_platform_data[] = { { - .membase = IO_ADDRESS(OMAP_UART1_BASE), - .mapbase = OMAP_UART1_BASE, + .membase = (char*)IO_ADDRESS(OMAP_UART1_BASE), + .mapbase = (unsigned long)OMAP_UART1_BASE, .irq = INT_UART1, .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, @@ -76,8 +76,8 @@ static struct plat_serial8250_port serial_platform_data[] = { .uartclk = OMAP16XX_BASE_BAUD * 16, }, { - .membase = IO_ADDRESS(OMAP_UART2_BASE), - .mapbase = OMAP_UART2_BASE, + .membase = (char*)IO_ADDRESS(OMAP_UART2_BASE), + .mapbase = (unsigned long)OMAP_UART2_BASE, .irq = INT_UART2, .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, @@ -85,8 +85,8 @@ static struct plat_serial8250_port serial_platform_data[] = { .uartclk = OMAP16XX_BASE_BAUD * 16, }, { - .membase = IO_ADDRESS(OMAP_UART3_BASE), - .mapbase = OMAP_UART3_BASE, + .membase = (char*)IO_ADDRESS(OMAP_UART3_BASE), + .mapbase = (unsigned long)OMAP_UART3_BASE, .irq = INT_UART3, .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index 4832fcc7d04a..7069c9d536f1 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -15,17 +15,8 @@ config ARCH_OMAP2430 bool "OMAP2430 support" depends on ARCH_OMAP24XX -config ARCH_OMAP34XX - bool "OMAP34xx Based System" - depends on ARCH_OMAP3 - -config ARCH_OMAP3430 - bool "OMAP3430 support" - depends on ARCH_OMAP3 && ARCH_OMAP34XX - select ARCH_OMAP_OTG - comment "OMAP Board Type" - depends on ARCH_OMAP2 || ARCH_OMAP3 + depends on ARCH_OMAP2 config MACH_OMAP_GENERIC bool "Generic OMAP board" @@ -44,14 +35,3 @@ config MACH_OMAP_2430SDP bool "OMAP 2430 SDP board" depends on ARCH_OMAP2 && ARCH_OMAP24XX -config MACH_OMAP3_BEAGLE - bool "OMAP3 BEAGLE board" - depends on ARCH_OMAP3 && ARCH_OMAP34XX - -config MACH_OMAP_LDP - bool "OMAP3 LDP board" - depends on ARCH_OMAP3 && ARCH_OMAP34XX - -config MACH_OVERO - bool "Gumstix Overo board" - depends on ARCH_OMAP3 && ARCH_OMAP34XX diff --git a/trunk/arch/arm/mach-omap2/Makefile b/trunk/arch/arm/mach-omap2/Makefile index c69392372c99..93ee990618ef 100644 --- a/trunk/arch/arm/mach-omap2/Makefile +++ b/trunk/arch/arm/mach-omap2/Makefile @@ -4,21 +4,16 @@ # Common support obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ - devices.o serial.o gpmc.o timer-gp.o powerdomain.o \ - clockdomain.o + devices.o serial.o gpmc.o timer-gp.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o # Functions loaded to SRAM obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o -obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o # Power Management -ifeq ($(CONFIG_PM),y) -obj-y += pm.o -obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o -endif +obj-$(CONFIG_PM) += pm.o sleep.o # Clock framework obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o @@ -29,7 +24,4 @@ obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o -obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o -obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o -obj-$(CONFIG_MACH_OVERO) += board-overo.o diff --git a/trunk/arch/arm/mach-omap2/board-h4.c b/trunk/arch/arm/mach-omap2/board-h4.c index 2fef2c845083..d4e3b6fc4705 100644 --- a/trunk/arch/arm/mach-omap2/board-h4.c +++ b/trunk/arch/arm/mach-omap2/board-h4.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -392,13 +391,6 @@ static struct omap_board_config_kernel h4_config[] = { { OMAP_TAG_LCD, &h4_lcd_config }, }; -static struct i2c_board_info __initdata h4_i2c_board_info[] = { - { - I2C_BOARD_INFO("isp1301_omap", 0x2d), - .irq = OMAP_GPIO_IRQ(125), - }, -}; - static void __init omap_h4_init(void) { /* @@ -419,9 +411,6 @@ static void __init omap_h4_init(void) } #endif - i2c_register_board_info(1, h4_i2c_board_info, - ARRAY_SIZE(h4_i2c_board_info)); - platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); omap_board_config = h4_config; omap_board_config_size = ARRAY_SIZE(h4_config); diff --git a/trunk/arch/arm/mach-omap2/board-ldp.c b/trunk/arch/arm/mach-omap2/board-ldp.c deleted file mode 100644 index 1ea59986aa7a..000000000000 --- a/trunk/arch/arm/mach-omap2/board-ldp.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-ldp.c - * - * Copyright (C) 2008 Texas Instruments Inc. - * Nishant Kamat - * - * Modified from mach-omap2/board-3430sdp.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static void __init omap_ldp_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); -} - -static struct omap_uart_config ldp_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -}; - -static struct omap_board_config_kernel ldp_config[] __initdata = { - { OMAP_TAG_UART, &ldp_uart_config }, -}; - -static int __init omap_i2c_init(void) -{ - omap_register_i2c_bus(1, 2600, NULL, 0); - omap_register_i2c_bus(2, 400, NULL, 0); - omap_register_i2c_bus(3, 400, NULL, 0); - return 0; -} - -static void __init omap_ldp_init(void) -{ - omap_i2c_init(); - omap_board_config = ldp_config; - omap_board_config_size = ARRAY_SIZE(ldp_config); - omap_serial_init(); -} - -static void __init omap_ldp_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); -} - -MACHINE_START(OMAP_LDP, "OMAP LDP board") - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_ldp_map_io, - .init_irq = omap_ldp_init_irq, - .init_machine = omap_ldp_init, - .timer = &omap_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-omap2/board-omap3beagle.c b/trunk/arch/arm/mach-omap2/board-omap3beagle.c deleted file mode 100644 index baa79674e9d5..000000000000 --- a/trunk/arch/arm/mach-omap2/board-omap3beagle.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-omap3beagle.c - * - * Copyright (C) 2008 Texas Instruments - * - * Modified from mach-omap2/board-3430sdp.c - * - * Initial code: Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 - -#define NAND_BLOCK_SIZE SZ_128K - -static struct mtd_partition omap3beagle_nand_partitions[] = { - /* All the partition sizes are listed in terms of NAND block size */ - { - .name = "X-Loader", - .offset = 0, - .size = 4 * NAND_BLOCK_SIZE, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "U-Boot", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ - .size = 15 * NAND_BLOCK_SIZE, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "U-Boot Env", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ - .size = 1 * NAND_BLOCK_SIZE, - }, - { - .name = "Kernel", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ - .size = 32 * NAND_BLOCK_SIZE, - }, - { - .name = "File System", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct omap_nand_platform_data omap3beagle_nand_data = { - .options = NAND_BUSWIDTH_16, - .parts = omap3beagle_nand_partitions, - .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions), - .dma_channel = -1, /* disable DMA in OMAP NAND driver */ - .nand_setup = NULL, - .dev_ready = NULL, -}; - -static struct resource omap3beagle_nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device omap3beagle_nand_device = { - .name = "omap2-nand", - .id = -1, - .dev = { - .platform_data = &omap3beagle_nand_data, - }, - .num_resources = 1, - .resource = &omap3beagle_nand_resource, -}; - -static struct omap_uart_config omap3_beagle_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -}; - -static void __init omap3_beagle_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); -} - -static struct platform_device omap3_beagle_lcd_device = { - .name = "omap3beagle_lcd", - .id = -1, -}; - -static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { - .ctrl_name = "internal", -}; - -static struct gpio_led gpio_leds[] = { - { - .name = "beagleboard::usr0", - .default_trigger = "heartbeat", - .gpio = 150, - }, - { - .name = "beagleboard::usr1", - .default_trigger = "mmc0", - .gpio = 149, - }, -}; - -static struct gpio_led_platform_data gpio_led_info = { - .leds = gpio_leds, - .num_leds = ARRAY_SIZE(gpio_leds), -}; - -static struct platform_device leds_gpio = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &gpio_led_info, - }, -}; - -static struct gpio_keys_button gpio_buttons[] = { - { - .code = BTN_EXTRA, - .gpio = 7, - .desc = "user", - .wakeup = 1, - }, -}; - -static struct gpio_keys_platform_data gpio_key_info = { - .buttons = gpio_buttons, - .nbuttons = ARRAY_SIZE(gpio_buttons), -}; - -static struct platform_device keys_gpio = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &gpio_key_info, - }, -}; - -static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { - { OMAP_TAG_UART, &omap3_beagle_uart_config }, - { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, -}; - -static struct platform_device *omap3_beagle_devices[] __initdata = { - &omap3_beagle_lcd_device, - &leds_gpio, - &keys_gpio, -}; - -static void __init omap3beagle_flash_init(void) -{ - u8 cs = 0; - u8 nandcs = GPMC_CS_NUM + 1; - - u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; - - /* find out the chip-select on which NAND exists */ - while (cs < GPMC_CS_NUM) { - u32 ret = 0; - ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - if ((ret & 0xC00) == 0x800) { - printk(KERN_INFO "Found NAND on CS%d\n", cs); - if (nandcs > GPMC_CS_NUM) - nandcs = cs; - } - cs++; - } - - if (nandcs > GPMC_CS_NUM) { - printk(KERN_INFO "NAND: Unable to find configuration " - "in GPMC\n "); - return; - } - - if (nandcs < GPMC_CS_NUM) { - omap3beagle_nand_data.cs = nandcs; - omap3beagle_nand_data.gpmc_cs_baseaddr = (void *) - (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); - omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add); - - printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (platform_device_register(&omap3beagle_nand_device) < 0) - printk(KERN_ERR "Unable to register NAND device\n"); - } -} - -static void __init omap3_beagle_init(void) -{ - platform_add_devices(omap3_beagle_devices, - ARRAY_SIZE(omap3_beagle_devices)); - omap_board_config = omap3_beagle_config; - omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); - omap_serial_init(); - omap3beagle_flash_init(); -} - -static void __init omap3_beagle_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); -} - -MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") - /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap3_beagle_map_io, - .init_irq = omap3_beagle_init_irq, - .init_machine = omap3_beagle_init, - .timer = &omap_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-omap2/board-overo.c b/trunk/arch/arm/mach-omap2/board-overo.c deleted file mode 100644 index e09aa59a399c..000000000000 --- a/trunk/arch/arm/mach-omap2/board-overo.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * board-overo.c (Gumstix Overo) - * - * Initial code: Steve Sakoman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define NAND_BLOCK_SIZE SZ_128K -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 - -static struct mtd_partition overo_nand_partitions[] = { - { - .name = "xloader", - .offset = 0, /* Offset = 0x00000 */ - .size = 4 * NAND_BLOCK_SIZE, - .mask_flags = MTD_WRITEABLE - }, - { - .name = "uboot", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ - .size = 14 * NAND_BLOCK_SIZE, - }, - { - .name = "uboot environment", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x240000 */ - .size = 2 * NAND_BLOCK_SIZE, - }, - { - .name = "linux", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ - .size = 32 * NAND_BLOCK_SIZE, - }, - { - .name = "rootfs", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct omap_nand_platform_data overo_nand_data = { - .parts = overo_nand_partitions, - .nr_parts = ARRAY_SIZE(overo_nand_partitions), - .dma_channel = -1, /* disable DMA in OMAP NAND driver */ -}; - -static struct resource overo_nand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device overo_nand_device = { - .name = "omap2-nand", - .id = -1, - .dev = { - .platform_data = &overo_nand_data, - }, - .num_resources = 1, - .resource = &overo_nand_resource, -}; - - -static void __init overo_flash_init(void) -{ - u8 cs = 0; - u8 nandcs = GPMC_CS_NUM + 1; - - u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; - - /* find out the chip-select on which NAND exists */ - while (cs < GPMC_CS_NUM) { - u32 ret = 0; - ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - if ((ret & 0xC00) == 0x800) { - printk(KERN_INFO "Found NAND on CS%d\n", cs); - if (nandcs > GPMC_CS_NUM) - nandcs = cs; - } - cs++; - } - - if (nandcs > GPMC_CS_NUM) { - printk(KERN_INFO "NAND: Unable to find configuration " - "in GPMC\n "); - return; - } - - if (nandcs < GPMC_CS_NUM) { - overo_nand_data.cs = nandcs; - overo_nand_data.gpmc_cs_baseaddr = (void *) - (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); - overo_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add); - - printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (platform_device_register(&overo_nand_device) < 0) - printk(KERN_ERR "Unable to register NAND device\n"); - } -} -static struct omap_uart_config overo_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -}; - -static int __init overo_i2c_init(void) -{ - /* i2c2 pins are used for gpio */ - omap_register_i2c_bus(3, 400, NULL, 0); - return 0; -} - -static void __init overo_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); -} - -static struct platform_device overo_lcd_device = { - .name = "overo_lcd", - .id = -1, -}; - -static struct omap_lcd_config overo_lcd_config __initdata = { - .ctrl_name = "internal", -}; - -static struct omap_board_config_kernel overo_config[] __initdata = { - { OMAP_TAG_UART, &overo_uart_config }, - { OMAP_TAG_LCD, &overo_lcd_config }, -}; - -static struct platform_device *overo_devices[] __initdata = { - &overo_lcd_device, -}; - -static void __init overo_init(void) -{ - overo_i2c_init(); - platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); - omap_board_config = overo_config; - omap_board_config_size = ARRAY_SIZE(overo_config); - omap_serial_init(); - overo_flash_init(); - - if ((gpio_request(OVERO_GPIO_W2W_NRESET, - "OVERO_GPIO_W2W_NRESET") == 0) && - (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) { - gpio_export(OVERO_GPIO_W2W_NRESET, 0); - gpio_set_value(OVERO_GPIO_W2W_NRESET, 0); - udelay(10); - gpio_set_value(OVERO_GPIO_W2W_NRESET, 1); - } else { - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_W2W_NRESET\n"); - } - - if ((gpio_request(OVERO_GPIO_BT_XGATE, "OVERO_GPIO_BT_XGATE") == 0) && - (gpio_direction_output(OVERO_GPIO_BT_XGATE, 0) == 0)) - gpio_export(OVERO_GPIO_BT_XGATE, 0); - else - printk(KERN_ERR "could not obtain gpio for OVERO_GPIO_BT_XGATE\n"); - - if ((gpio_request(OVERO_GPIO_BT_NRESET, "OVERO_GPIO_BT_NRESET") == 0) && - (gpio_direction_output(OVERO_GPIO_BT_NRESET, 1) == 0)) { - gpio_export(OVERO_GPIO_BT_NRESET, 0); - gpio_set_value(OVERO_GPIO_BT_NRESET, 0); - mdelay(6); - gpio_set_value(OVERO_GPIO_BT_NRESET, 1); - } else { - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_BT_NRESET\n"); - } - - if ((gpio_request(OVERO_GPIO_USBH_CPEN, "OVERO_GPIO_USBH_CPEN") == 0) && - (gpio_direction_output(OVERO_GPIO_USBH_CPEN, 1) == 0)) - gpio_export(OVERO_GPIO_USBH_CPEN, 0); - else - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_USBH_CPEN\n"); - - if ((gpio_request(OVERO_GPIO_USBH_NRESET, - "OVERO_GPIO_USBH_NRESET") == 0) && - (gpio_direction_output(OVERO_GPIO_USBH_NRESET, 1) == 0)) - gpio_export(OVERO_GPIO_USBH_NRESET, 0); - else - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_USBH_NRESET\n"); -} - -static void __init overo_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); -} - -MACHINE_START(OVERO, "Gumstix Overo") - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = overo_map_io, - .init_irq = overo_init_irq, - .init_machine = overo_init, - .timer = &omap_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-omap2/clock.c b/trunk/arch/arm/mach-omap2/clock.c index ad721e0cbf7a..97cde3d3611d 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -62,35 +61,9 @@ u8 cpu_mask; /*------------------------------------------------------------------------- - * OMAP2/3 specific clock functions + * Omap2 specific clock functions *-------------------------------------------------------------------------*/ -/** - * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk - * @clk: OMAP clock struct ptr to use - * - * Convert a clockdomain name stored in a struct clk 'clk' into a - * clockdomain pointer, and save it into the struct clk. Intended to be - * called during clk_register(). No return value. - */ -void omap2_init_clk_clkdm(struct clk *clk) -{ - struct clockdomain *clkdm; - - if (!clk->clkdm_name) - return; - - clkdm = clkdm_lookup(clk->clkdm_name); - if (clkdm) { - pr_debug("clock: associated clk %s to clkdm %s\n", - clk->name, clk->clkdm_name); - clk->clkdm = clkdm; - } else { - pr_debug("clock: could not associate clk %s to " - "clkdm %s\n", clk->name, clk->clkdm_name); - } -} - /** * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware * @clk: OMAP clock struct ptr to use @@ -277,7 +250,7 @@ int _omap2_clk_enable(struct clk *clk) if (clk->enable) return clk->enable(clk); - if (unlikely(clk->enable_reg == NULL)) { + if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); return 0; /* REVISIT: -EINVAL */ @@ -309,7 +282,7 @@ void _omap2_clk_disable(struct clk *clk) return; } - if (clk->enable_reg == NULL) { + if (clk->enable_reg == 0) { /* * 'Independent' here refers to a clock which is not * controlled by its parent. @@ -334,9 +307,6 @@ void omap2_clk_disable(struct clk *clk) _omap2_clk_disable(clk); if (likely((u32)clk->parent)) omap2_clk_disable(clk->parent); - if (clk->clkdm) - omap2_clkdm_clk_disable(clk->clkdm, clk); - } } @@ -353,19 +323,11 @@ int omap2_clk_enable(struct clk *clk) return ret; } - if (clk->clkdm) - omap2_clkdm_clk_enable(clk->clkdm, clk); - ret = _omap2_clk_enable(clk); - if (unlikely(ret != 0)) { - if (clk->clkdm) - omap2_clkdm_clk_disable(clk->clkdm, clk); - - if (clk->parent) { - omap2_clk_disable(clk->parent); - clk->usecount--; - } + if (unlikely(ret != 0) && clk->parent) { + omap2_clk_disable(clk->parent); + clk->usecount--; } } @@ -514,7 +476,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) /* Given a clock and a rate apply a clock specific rounding function */ long omap2_clk_round_rate(struct clk *clk, unsigned long rate) { - if (clk->round_rate != NULL) + if (clk->round_rate != 0) return clk->round_rate(clk, rate); if (clk->flags & RATE_FIXED) @@ -603,7 +565,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) */ void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask) { - if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL))) + if (unlikely((clk->clksel_reg == 0) || (clk->clksel_mask == 0))) return NULL; *field_mask = clk->clksel_mask; @@ -623,7 +585,7 @@ u32 omap2_clksel_get_divisor(struct clk *clk) void __iomem *div_addr; div_addr = omap2_get_clksel(clk, &field_mask); - if (div_addr == NULL) + if (div_addr == 0) return 0; field_val = __raw_readl(div_addr) & field_mask; @@ -642,7 +604,7 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) return -EINVAL; div_addr = omap2_get_clksel(clk, &field_mask); - if (div_addr == NULL) + if (div_addr == 0) return -EINVAL; field_val = omap2_divisor_to_clksel(clk, new_div); @@ -680,7 +642,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate) return -EINVAL; /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ - if (clk->set_rate != NULL) + if (clk->set_rate != 0) ret = clk->set_rate(clk, rate); if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) @@ -701,7 +663,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr, const struct clksel_rate *clkr; *parent_div = 0; - *src_addr = NULL; + *src_addr = 0; clks = omap2_get_clksel_by_parent(clk, src_clk); if (clks == NULL) @@ -742,7 +704,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) field_val = omap2_clksel_get_src_field(&src_addr, new_parent, &field_mask, clk, &parent_div); - if (src_addr == NULL) + if (src_addr == 0) return -EINVAL; if (clk->usecount > 0) diff --git a/trunk/arch/arm/mach-omap2/clock.h b/trunk/arch/arm/mach-omap2/clock.h index 1fb330e0847d..626e5fa93b6a 100644 --- a/trunk/arch/arm/mach-omap2/clock.h +++ b/trunk/arch/arm/mach-omap2/clock.h @@ -21,7 +21,6 @@ /* The maximum error between a target DPLL rate and the rounded rate in Hz */ #define DEFAULT_DPLL_RATE_TOLERANCE 50000 -int omap2_clk_init(void); int omap2_clk_enable(struct clk *clk); void omap2_clk_disable(struct clk *clk); long omap2_clk_round_rate(struct clk *clk, unsigned long rate); @@ -37,7 +36,6 @@ void omap2_clk_disable_unused(struct clk *clk); #endif void omap2_clksel_recalc(struct clk *clk); -void omap2_init_clk_clkdm(struct clk *clk); void omap2_init_clksel_parent(struct clk *clk); u32 omap2_clksel_get_divisor(struct clk *clk); u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, diff --git a/trunk/arch/arm/mach-omap2/clock24xx.h b/trunk/arch/arm/mach-omap2/clock24xx.h index 242a19d86ccd..be4e25554e05 100644 --- a/trunk/arch/arm/mach-omap2/clock24xx.h +++ b/trunk/arch/arm/mach-omap2/clock24xx.h @@ -626,7 +626,6 @@ static struct clk func_32k_ck = { .rate = 32000, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .recalc = &propagate_rate, }; @@ -635,19 +634,17 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ .name = "osc_ck", .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .enable = &omap2_enable_osc_ck, .disable = &omap2_disable_osc_ck, .recalc = &omap2_osc_clk_recalc, }; -/* Without modem likely 12MHz, with modem likely 13MHz */ +/* With out modem likely 12MHz, with modem likely 13MHz */ static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */ .name = "sys_ck", /* ~ ref_clk also */ .parent = &osc_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .recalc = &omap2_sys_clk_recalc, }; @@ -656,7 +653,6 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */ .rate = 54000000, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .recalc = &propagate_rate, }; @@ -688,7 +684,6 @@ static struct clk dpll_ck = { .dpll_data = &dpll_dd, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "wkup_clkdm", .recalc = &omap2_dpllcore_recalc, .set_rate = &omap2_reprogram_dpllcore, }; @@ -699,7 +694,6 @@ static struct clk apll96_ck = { .rate = 96000000, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT, .enable = &omap2_clk_fixed_enable, @@ -713,7 +707,6 @@ static struct clk apll54_ck = { .rate = 54000000, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT, .enable = &omap2_clk_fixed_enable, @@ -748,7 +741,6 @@ static struct clk func_54m_ck = { .parent = &apll54_ck, /* can also be alt_clk */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .clksel_mask = OMAP24XX_54M_SOURCE, @@ -761,7 +753,6 @@ static struct clk core_ck = { .parent = &dpll_ck, /* can also be 32k */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -788,7 +779,6 @@ static struct clk func_96m_ck = { .parent = &apll96_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .clksel_mask = OMAP2430_96M_SOURCE, @@ -821,7 +811,6 @@ static struct clk func_48m_ck = { .parent = &apll96_ck, /* 96M or Alt */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .clksel_mask = OMAP24XX_48M_SOURCE, @@ -837,7 +826,6 @@ static struct clk func_12m_ck = { .fixed_div = 4, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", .recalc = &omap2_fixed_divisor_recalc, }; @@ -890,7 +878,6 @@ static struct clk sys_clkout_src = { .parent = &func_54m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL, .enable_bit = OMAP24XX_CLKOUT_EN_SHIFT, .init = &omap2_init_clksel_parent, @@ -921,7 +908,6 @@ static struct clk sys_clkout = { .parent = &sys_clkout_src, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", .clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL, .clksel_mask = OMAP24XX_CLKOUT_DIV_MASK, .clksel = sys_clkout_clksel, @@ -935,7 +921,6 @@ static struct clk sys_clkout2_src = { .name = "sys_clkout2_src", .parent = &func_54m_ck, .flags = CLOCK_IN_OMAP242X | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL, .enable_bit = OMAP2420_CLKOUT2_EN_SHIFT, .init = &omap2_init_clksel_parent, @@ -957,7 +942,6 @@ static struct clk sys_clkout2 = { .name = "sys_clkout2", .parent = &sys_clkout2_src, .flags = CLOCK_IN_OMAP242X | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", .clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL, .clksel_mask = OMAP2420_CLKOUT2_DIV_MASK, .clksel = sys_clkout2_clksel, @@ -970,7 +954,6 @@ static struct clk emul_ck = { .name = "emul_ck", .parent = &func_54m_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP24XX_PRCM_CLKEMUL_CTRL, .enable_bit = OMAP24XX_EMULATION_EN_SHIFT, .recalc = &followparent_recalc, @@ -1007,13 +990,12 @@ static struct clk mpu_ck = { /* Control cpu */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED | DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES, - .clkdm_name = "mpu_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL), .clksel_mask = OMAP24XX_CLKSEL_MPU_MASK, .clksel = mpu_clksel, .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, + .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate }; @@ -1049,7 +1031,6 @@ static struct clk dsp_fck = { .parent = &core_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES, - .clkdm_name = "dsp_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), @@ -1073,7 +1054,10 @@ static const struct clksel dsp_irate_ick_clksel[] = { { .parent = NULL } }; -/* This clock does not exist as such in the TRM. */ +/* + * This clock does not exist as such in the TRM, but is added to + * separate source selection from XXX + */ static struct clk dsp_irate_ick = { .name = "dsp_irate_ick", .parent = &dsp_fck, @@ -1105,17 +1089,11 @@ static struct clk iva2_1_ick = { .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, }; -/* - * The IVA1 is an ARM7 core on the 2420 that has nothing to do with - * the C54x, but which is contained in the DSP powerdomain. Does not - * exist on later OMAPs. - */ static struct clk iva1_ifck = { .name = "iva1_ifck", .parent = &core_ck, .flags = CLOCK_IN_OMAP242X | CONFIG_PARTICIPANT | RATE_PROPAGATES | DELAYED_APP, - .clkdm_name = "iva1_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), .enable_bit = OMAP2420_EN_IVA_COP_SHIFT, .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), @@ -1131,7 +1109,6 @@ static struct clk iva1_mpu_int_ifck = { .name = "iva1_mpu_int_ifck", .parent = &iva1_ifck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "iva1_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), .enable_bit = OMAP2420_EN_IVA_MPU_SHIFT, .fixed_div = 2, @@ -1179,7 +1156,6 @@ static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED | DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES, - .clkdm_name = "core_l3_clkdm", .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), .clksel_mask = OMAP24XX_CLKSEL_L3_MASK, .clksel = core_l3_clksel, @@ -1201,13 +1177,11 @@ static const struct clksel usb_l4_ick_clksel[] = { { .parent = NULL }, }; -/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */ static struct clk usb_l4_ick = { /* FS-USB interface clock */ .name = "usb_l4_ick", .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP24XX_EN_USB_SHIFT, .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), @@ -1218,43 +1192,11 @@ static struct clk usb_l4_ick = { /* FS-USB interface clock */ .set_rate = &omap2_clksel_set_rate }; -/* - * L4 clock management domain - * - * This domain contains lots of interface clocks from the L4 interface, some - * functional clocks. Fixed APLL functional source clocks are managed in - * this domain. - */ -static const struct clksel_rate l4_core_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 0 } -}; - -static const struct clksel l4_clksel[] = { - { .parent = &core_l3_ck, .rates = l4_core_l3_rates }, - { .parent = NULL } -}; - -static struct clk l4_ck = { /* used both as an ick and fck */ - .name = "l4_ck", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES, - .clkdm_name = "core_l4_clkdm", - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_L4_MASK, - .clksel = l4_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - /* * SSI is in L3 management domain, its direct parent is core not l3, * many core power domain entities are grouped into the L3 clock * domain. - * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK + * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK * * ssr = core/1/2/3/4/5, sst = 1/2 ssr. */ @@ -1279,7 +1221,6 @@ static struct clk ssi_ssr_sst_fck = { .parent = &core_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP24XX_EN_SSI_SHIFT, .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), @@ -1290,7 +1231,6 @@ static struct clk ssi_ssr_sst_fck = { .set_rate = &omap2_clksel_set_rate }; - /* * GFX clock domain * Clocks: @@ -1314,7 +1254,6 @@ static struct clk gfx_3d_fck = { .name = "gfx_3d_fck", .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "gfx_clkdm", .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_EN_3D_SHIFT, .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), @@ -1329,7 +1268,6 @@ static struct clk gfx_2d_fck = { .name = "gfx_2d_fck", .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "gfx_clkdm", .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_EN_2D_SHIFT, .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), @@ -1344,7 +1282,6 @@ static struct clk gfx_ick = { .name = "gfx_ick", /* From l3 */ .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "gfx_clkdm", .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), .enable_bit = OMAP_EN_GFX_SHIFT, .recalc = &followparent_recalc, @@ -1374,7 +1311,6 @@ static struct clk mdm_ick = { /* used both as a ick and fck */ .name = "mdm_ick", .parent = &core_ck, .flags = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT, - .clkdm_name = "mdm_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN), .enable_bit = OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT, .clksel_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL), @@ -1389,12 +1325,51 @@ static struct clk mdm_osc_ck = { .name = "mdm_osc_ck", .parent = &osc_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "mdm_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN), .enable_bit = OMAP2430_EN_OSC_SHIFT, .recalc = &followparent_recalc, }; +/* + * L4 clock management domain + * + * This domain contains lots of interface clocks from the L4 interface, some + * functional clocks. Fixed APLL functional source clocks are managed in + * this domain. + */ +static const struct clksel_rate l4_core_l3_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel l4_clksel[] = { + { .parent = &core_l3_ck, .rates = l4_core_l3_rates }, + { .parent = NULL } +}; + +static struct clk l4_ck = { /* used both as an ick and fck */ + .name = "l4_ck", + .parent = &core_l3_ck, + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | + ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES, + .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + .clksel_mask = OMAP24XX_CLKSEL_L4_MASK, + .clksel = l4_clksel, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate +}; + +static struct clk ssi_l4_ick = { + .name = "ssi_l4_ick", + .parent = &l4_ck, + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP24XX_EN_SSI_SHIFT, + .recalc = &followparent_recalc, +}; + /* * DSS clock domain * CLOCKs: @@ -1434,7 +1409,6 @@ static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */ .name = "dss_ick", .parent = &l4_ck, /* really both l3 and l4 */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "dss_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_DSS1_SHIFT, .recalc = &followparent_recalc, @@ -1445,7 +1419,6 @@ static struct clk dss1_fck = { .parent = &core_ck, /* Core or sys */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP, - .clkdm_name = "dss_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_DSS1_SHIFT, .init = &omap2_init_clksel_parent, @@ -1478,7 +1451,6 @@ static struct clk dss2_fck = { /* Alt clk used in power management */ .parent = &sys_ck, /* fixed at sys_ck or 48MHz */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP, - .clkdm_name = "dss_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_DSS2_SHIFT, .init = &omap2_init_clksel_parent, @@ -1492,7 +1464,6 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */ .name = "dss_54m_fck", /* 54m tv clk */ .parent = &func_54m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "dss_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_TV_SHIFT, .recalc = &followparent_recalc, @@ -1520,7 +1491,6 @@ static struct clk gpt1_ick = { .name = "gpt1_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_GPT1_SHIFT, .recalc = &followparent_recalc, @@ -1530,7 +1500,6 @@ static struct clk gpt1_fck = { .name = "gpt1_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_EN_GPT1_SHIFT, .init = &omap2_init_clksel_parent, @@ -1546,7 +1515,6 @@ static struct clk gpt2_ick = { .name = "gpt2_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT2_SHIFT, .recalc = &followparent_recalc, @@ -1556,7 +1524,6 @@ static struct clk gpt2_fck = { .name = "gpt2_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT2_SHIFT, .init = &omap2_init_clksel_parent, @@ -1570,7 +1537,6 @@ static struct clk gpt3_ick = { .name = "gpt3_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT3_SHIFT, .recalc = &followparent_recalc, @@ -1580,7 +1546,6 @@ static struct clk gpt3_fck = { .name = "gpt3_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT3_SHIFT, .init = &omap2_init_clksel_parent, @@ -1594,7 +1559,6 @@ static struct clk gpt4_ick = { .name = "gpt4_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT4_SHIFT, .recalc = &followparent_recalc, @@ -1604,7 +1568,6 @@ static struct clk gpt4_fck = { .name = "gpt4_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT4_SHIFT, .init = &omap2_init_clksel_parent, @@ -1618,7 +1581,6 @@ static struct clk gpt5_ick = { .name = "gpt5_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT5_SHIFT, .recalc = &followparent_recalc, @@ -1628,7 +1590,6 @@ static struct clk gpt5_fck = { .name = "gpt5_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT5_SHIFT, .init = &omap2_init_clksel_parent, @@ -1642,7 +1603,6 @@ static struct clk gpt6_ick = { .name = "gpt6_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT6_SHIFT, .recalc = &followparent_recalc, @@ -1652,7 +1612,6 @@ static struct clk gpt6_fck = { .name = "gpt6_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT6_SHIFT, .init = &omap2_init_clksel_parent, @@ -1675,7 +1634,6 @@ static struct clk gpt7_fck = { .name = "gpt7_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT7_SHIFT, .init = &omap2_init_clksel_parent, @@ -1689,7 +1647,6 @@ static struct clk gpt8_ick = { .name = "gpt8_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT8_SHIFT, .recalc = &followparent_recalc, @@ -1699,7 +1656,6 @@ static struct clk gpt8_fck = { .name = "gpt8_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT8_SHIFT, .init = &omap2_init_clksel_parent, @@ -1713,7 +1669,6 @@ static struct clk gpt9_ick = { .name = "gpt9_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT9_SHIFT, .recalc = &followparent_recalc, @@ -1723,7 +1678,6 @@ static struct clk gpt9_fck = { .name = "gpt9_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT9_SHIFT, .init = &omap2_init_clksel_parent, @@ -1737,7 +1691,6 @@ static struct clk gpt10_ick = { .name = "gpt10_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT10_SHIFT, .recalc = &followparent_recalc, @@ -1747,7 +1700,6 @@ static struct clk gpt10_fck = { .name = "gpt10_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT10_SHIFT, .init = &omap2_init_clksel_parent, @@ -1761,7 +1713,6 @@ static struct clk gpt11_ick = { .name = "gpt11_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT11_SHIFT, .recalc = &followparent_recalc, @@ -1771,7 +1722,6 @@ static struct clk gpt11_fck = { .name = "gpt11_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT11_SHIFT, .init = &omap2_init_clksel_parent, @@ -1785,7 +1735,6 @@ static struct clk gpt12_ick = { .name = "gpt12_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT12_SHIFT, .recalc = &followparent_recalc, @@ -1795,7 +1744,6 @@ static struct clk gpt12_fck = { .name = "gpt12_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_GPT12_SHIFT, .init = &omap2_init_clksel_parent, @@ -1810,7 +1758,6 @@ static struct clk mcbsp1_ick = { .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT, .recalc = &followparent_recalc, @@ -1821,7 +1768,6 @@ static struct clk mcbsp1_fck = { .id = 1, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT, .recalc = &followparent_recalc, @@ -1832,7 +1778,6 @@ static struct clk mcbsp2_ick = { .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT, .recalc = &followparent_recalc, @@ -1843,7 +1788,6 @@ static struct clk mcbsp2_fck = { .id = 2, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT, .recalc = &followparent_recalc, @@ -1854,7 +1798,6 @@ static struct clk mcbsp3_ick = { .id = 3, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MCBSP3_SHIFT, .recalc = &followparent_recalc, @@ -1865,7 +1808,6 @@ static struct clk mcbsp3_fck = { .id = 3, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MCBSP3_SHIFT, .recalc = &followparent_recalc, @@ -1876,7 +1818,6 @@ static struct clk mcbsp4_ick = { .id = 4, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MCBSP4_SHIFT, .recalc = &followparent_recalc, @@ -1887,7 +1828,6 @@ static struct clk mcbsp4_fck = { .id = 4, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MCBSP4_SHIFT, .recalc = &followparent_recalc, @@ -1898,7 +1838,6 @@ static struct clk mcbsp5_ick = { .id = 5, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MCBSP5_SHIFT, .recalc = &followparent_recalc, @@ -1909,7 +1848,6 @@ static struct clk mcbsp5_fck = { .id = 5, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MCBSP5_SHIFT, .recalc = &followparent_recalc, @@ -1919,7 +1857,6 @@ static struct clk mcspi1_ick = { .name = "mcspi_ick", .id = 1, .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, @@ -1931,7 +1868,6 @@ static struct clk mcspi1_fck = { .id = 1, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, .recalc = &followparent_recalc, @@ -1942,7 +1878,6 @@ static struct clk mcspi2_ick = { .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, .recalc = &followparent_recalc, @@ -1953,7 +1888,6 @@ static struct clk mcspi2_fck = { .id = 2, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, .recalc = &followparent_recalc, @@ -1964,7 +1898,6 @@ static struct clk mcspi3_ick = { .id = 3, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MCSPI3_SHIFT, .recalc = &followparent_recalc, @@ -1975,7 +1908,6 @@ static struct clk mcspi3_fck = { .id = 3, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MCSPI3_SHIFT, .recalc = &followparent_recalc, @@ -1985,7 +1917,6 @@ static struct clk uart1_ick = { .name = "uart1_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_UART1_SHIFT, .recalc = &followparent_recalc, @@ -1995,7 +1926,6 @@ static struct clk uart1_fck = { .name = "uart1_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_UART1_SHIFT, .recalc = &followparent_recalc, @@ -2005,7 +1935,6 @@ static struct clk uart2_ick = { .name = "uart2_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_UART2_SHIFT, .recalc = &followparent_recalc, @@ -2015,7 +1944,6 @@ static struct clk uart2_fck = { .name = "uart2_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_UART2_SHIFT, .recalc = &followparent_recalc, @@ -2025,7 +1953,6 @@ static struct clk uart3_ick = { .name = "uart3_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP24XX_EN_UART3_SHIFT, .recalc = &followparent_recalc, @@ -2035,7 +1962,6 @@ static struct clk uart3_fck = { .name = "uart3_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP24XX_EN_UART3_SHIFT, .recalc = &followparent_recalc, @@ -2045,7 +1971,6 @@ static struct clk gpios_ick = { .name = "gpios_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, .recalc = &followparent_recalc, @@ -2055,7 +1980,6 @@ static struct clk gpios_fck = { .name = "gpios_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, .recalc = &followparent_recalc, @@ -2065,7 +1989,6 @@ static struct clk mpu_wdt_ick = { .name = "mpu_wdt_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, .recalc = &followparent_recalc, @@ -2075,7 +1998,6 @@ static struct clk mpu_wdt_fck = { .name = "mpu_wdt_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, .recalc = &followparent_recalc, @@ -2084,40 +2006,31 @@ static struct clk mpu_wdt_fck = { static struct clk sync_32k_ick = { .name = "sync_32k_ick", .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT, .recalc = &followparent_recalc, }; - static struct clk wdt1_ick = { .name = "wdt1_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_WDT1_SHIFT, .recalc = &followparent_recalc, }; - static struct clk omapctrl_ick = { .name = "omapctrl_ick", .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT, .recalc = &followparent_recalc, }; - static struct clk icr_ick = { .name = "icr_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP2430_EN_ICR_SHIFT, .recalc = &followparent_recalc, @@ -2127,22 +2040,15 @@ static struct clk cam_ick = { .name = "cam_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_CAM_SHIFT, .recalc = &followparent_recalc, }; -/* - * cam_fck controls both CAM_MCLK and CAM_FCLK. It should probably be - * split into two separate clocks, since the parent clocks are different - * and the clockdomains are also different. - */ static struct clk cam_fck = { .name = "cam_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_CAM_SHIFT, .recalc = &followparent_recalc, @@ -2152,7 +2058,6 @@ static struct clk mailboxes_ick = { .name = "mailboxes_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT, .recalc = &followparent_recalc, @@ -2162,7 +2067,6 @@ static struct clk wdt4_ick = { .name = "wdt4_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_WDT4_SHIFT, .recalc = &followparent_recalc, @@ -2172,7 +2076,6 @@ static struct clk wdt4_fck = { .name = "wdt4_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_WDT4_SHIFT, .recalc = &followparent_recalc, @@ -2182,7 +2085,6 @@ static struct clk wdt3_ick = { .name = "wdt3_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP2420_EN_WDT3_SHIFT, .recalc = &followparent_recalc, @@ -2192,7 +2094,6 @@ static struct clk wdt3_fck = { .name = "wdt3_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP2420_EN_WDT3_SHIFT, .recalc = &followparent_recalc, @@ -2202,7 +2103,6 @@ static struct clk mspro_ick = { .name = "mspro_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, .recalc = &followparent_recalc, @@ -2212,7 +2112,6 @@ static struct clk mspro_fck = { .name = "mspro_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, .recalc = &followparent_recalc, @@ -2222,7 +2121,6 @@ static struct clk mmc_ick = { .name = "mmc_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP2420_EN_MMC_SHIFT, .recalc = &followparent_recalc, @@ -2232,7 +2130,6 @@ static struct clk mmc_fck = { .name = "mmc_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP2420_EN_MMC_SHIFT, .recalc = &followparent_recalc, @@ -2242,7 +2139,6 @@ static struct clk fac_ick = { .name = "fac_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_FAC_SHIFT, .recalc = &followparent_recalc, @@ -2252,7 +2148,6 @@ static struct clk fac_fck = { .name = "fac_fck", .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_FAC_SHIFT, .recalc = &followparent_recalc, @@ -2262,7 +2157,6 @@ static struct clk eac_ick = { .name = "eac_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP2420_EN_EAC_SHIFT, .recalc = &followparent_recalc, @@ -2272,7 +2166,6 @@ static struct clk eac_fck = { .name = "eac_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP2420_EN_EAC_SHIFT, .recalc = &followparent_recalc, @@ -2282,7 +2175,6 @@ static struct clk hdq_ick = { .name = "hdq_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_HDQ_SHIFT, .recalc = &followparent_recalc, @@ -2292,7 +2184,6 @@ static struct clk hdq_fck = { .name = "hdq_fck", .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP24XX_EN_HDQ_SHIFT, .recalc = &followparent_recalc, @@ -2303,7 +2194,6 @@ static struct clk i2c2_ick = { .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP2420_EN_I2C2_SHIFT, .recalc = &followparent_recalc, @@ -2314,7 +2204,6 @@ static struct clk i2c2_fck = { .id = 2, .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP2420_EN_I2C2_SHIFT, .recalc = &followparent_recalc, @@ -2325,7 +2214,6 @@ static struct clk i2chs2_fck = { .id = 2, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_I2CHS2_SHIFT, .recalc = &followparent_recalc, @@ -2336,7 +2224,6 @@ static struct clk i2c1_ick = { .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP2420_EN_I2C1_SHIFT, .recalc = &followparent_recalc, @@ -2347,7 +2234,6 @@ static struct clk i2c1_fck = { .id = 1, .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP2420_EN_I2C1_SHIFT, .recalc = &followparent_recalc, @@ -2358,7 +2244,6 @@ static struct clk i2chs1_fck = { .id = 1, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_I2CHS1_SHIFT, .recalc = &followparent_recalc, @@ -2367,9 +2252,7 @@ static struct clk i2chs1_fck = { static struct clk gpmc_fck = { .name = "gpmc_fck", .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ENABLE_ON_INIT, - .clkdm_name = "core_l3_clkdm", + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT, .recalc = &followparent_recalc, }; @@ -2377,7 +2260,6 @@ static struct clk sdma_fck = { .name = "sdma_fck", .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", .recalc = &followparent_recalc, }; @@ -2385,7 +2267,6 @@ static struct clk sdma_ick = { .name = "sdma_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", .recalc = &followparent_recalc, }; @@ -2393,7 +2274,6 @@ static struct clk vlynq_ick = { .name = "vlynq_ick", .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP2420_EN_VLYNQ_SHIFT, .recalc = &followparent_recalc, @@ -2428,7 +2308,6 @@ static struct clk vlynq_fck = { .name = "vlynq_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | DELAYED_APP, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP2420_EN_VLYNQ_SHIFT, .init = &omap2_init_clksel_parent, @@ -2444,7 +2323,6 @@ static struct clk sdrc_ick = { .name = "sdrc_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X | ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), .enable_bit = OMAP2430_EN_SDRC_SHIFT, .recalc = &followparent_recalc, @@ -2454,7 +2332,6 @@ static struct clk des_ick = { .name = "des_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), .enable_bit = OMAP24XX_EN_DES_SHIFT, .recalc = &followparent_recalc, @@ -2464,7 +2341,6 @@ static struct clk sha_ick = { .name = "sha_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), .enable_bit = OMAP24XX_EN_SHA_SHIFT, .recalc = &followparent_recalc, @@ -2474,7 +2350,6 @@ static struct clk rng_ick = { .name = "rng_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), .enable_bit = OMAP24XX_EN_RNG_SHIFT, .recalc = &followparent_recalc, @@ -2484,7 +2359,6 @@ static struct clk aes_ick = { .name = "aes_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), .enable_bit = OMAP24XX_EN_AES_SHIFT, .recalc = &followparent_recalc, @@ -2494,7 +2368,6 @@ static struct clk pka_ick = { .name = "pka_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), .enable_bit = OMAP24XX_EN_PKA_SHIFT, .recalc = &followparent_recalc, @@ -2504,7 +2377,6 @@ static struct clk usb_fck = { .name = "usb_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP24XX_EN_USB_SHIFT, .recalc = &followparent_recalc, @@ -2514,7 +2386,6 @@ static struct clk usbhs_ick = { .name = "usbhs_ick", .parent = &core_l3_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_USBHS_SHIFT, .recalc = &followparent_recalc, @@ -2525,7 +2396,6 @@ static struct clk mmchs1_ick = { .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, .recalc = &followparent_recalc, @@ -2536,7 +2406,6 @@ static struct clk mmchs1_fck = { .id = 1, .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, .recalc = &followparent_recalc, @@ -2547,7 +2416,6 @@ static struct clk mmchs2_ick = { .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MMCHS2_SHIFT, .recalc = &followparent_recalc, @@ -2567,7 +2435,6 @@ static struct clk gpio5_ick = { .name = "gpio5_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_GPIO5_SHIFT, .recalc = &followparent_recalc, @@ -2577,7 +2444,6 @@ static struct clk gpio5_fck = { .name = "gpio5_fck", .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_GPIO5_SHIFT, .recalc = &followparent_recalc, @@ -2587,7 +2453,6 @@ static struct clk mdm_intc_ick = { .name = "mdm_intc_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP2430_EN_MDM_INTC_SHIFT, .recalc = &followparent_recalc, @@ -2598,7 +2463,6 @@ static struct clk mmchsdb1_fck = { .id = 1, .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MMCHSDB1_SHIFT, .recalc = &followparent_recalc, @@ -2609,7 +2473,6 @@ static struct clk mmchsdb2_fck = { .id = 2, .parent = &func_32k_ck, .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MMCHSDB2_SHIFT, .recalc = &followparent_recalc, @@ -2688,6 +2551,7 @@ static struct clk *onchip_24xx_clks[] __initdata = { &usb_l4_ick, /* L4 domain clocks */ &l4_ck, /* used as both core_l4 and wu_l4 */ + &ssi_l4_ick, /* virtual meta-group clock */ &virt_prcm_set, /* general l4 interface ck, multi-parent functional clk */ diff --git a/trunk/arch/arm/mach-omap2/clock34xx.c b/trunk/arch/arm/mach-omap2/clock34xx.c index 084e11082f80..e5b475f21081 100644 --- a/trunk/arch/arm/mach-omap2/clock34xx.c +++ b/trunk/arch/arm/mach-omap2/clock34xx.c @@ -62,14 +62,11 @@ static void omap3_dpll_recalc(struct clk *clk) static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) { const struct dpll_data *dd; - u32 v; dd = clk->dpll_data; - v = __raw_readl(dd->control_reg); - v &= ~dd->enable_mask; - v |= clken_bits << __ffs(dd->enable_mask); - __raw_writel(v, dd->control_reg); + cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask), + dd->control_reg); } /* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ @@ -85,7 +82,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state) state <<= dd->idlest_bit; idlest_mask = 1 << dd->idlest_bit; - while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) && + while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) && i < MAX_DPLL_WAIT_TRIES) { i++; udelay(1); @@ -288,7 +285,7 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk) dd = clk->dpll_data; - v = __raw_readl(dd->autoidle_reg); + v = cm_read_reg(dd->autoidle_reg); v &= dd->autoidle_mask; v >>= __ffs(dd->autoidle_mask); @@ -307,7 +304,6 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk) static void omap3_dpll_allow_idle(struct clk *clk) { const struct dpll_data *dd; - u32 v; if (!clk || !clk->dpll_data) return; @@ -319,10 +315,9 @@ static void omap3_dpll_allow_idle(struct clk *clk) * by writing 0x5 instead of 0x1. Add some mechanism to * optionally enter this mode. */ - v = __raw_readl(dd->autoidle_reg); - v &= ~dd->autoidle_mask; - v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); - __raw_writel(v, dd->autoidle_reg); + cm_rmw_reg_bits(dd->autoidle_mask, + DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask), + dd->autoidle_reg); } /** @@ -334,17 +329,15 @@ static void omap3_dpll_allow_idle(struct clk *clk) static void omap3_dpll_deny_idle(struct clk *clk) { const struct dpll_data *dd; - u32 v; if (!clk || !clk->dpll_data) return; dd = clk->dpll_data; - v = __raw_readl(dd->autoidle_reg); - v &= ~dd->autoidle_mask; - v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask); - __raw_writel(v, dd->autoidle_reg); + cm_rmw_reg_bits(dd->autoidle_mask, + DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask), + dd->autoidle_reg); } /* Clock control for DPLL outputs */ @@ -489,10 +482,8 @@ int __init omap2_clk_init(void) for (clkp = onchip_34xx_clks; clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks); clkp++) { - if ((*clkp)->flags & cpu_clkflg) { + if ((*clkp)->flags & cpu_clkflg) clk_register(*clkp); - omap2_init_clk_clkdm(*clkp); - } } /* REVISIT: Not yet ready for OMAP3 */ diff --git a/trunk/arch/arm/mach-omap2/clock34xx.h b/trunk/arch/arm/mach-omap2/clock34xx.h index c38a8a09692f..ec664457a11a 100644 --- a/trunk/arch/arm/mach-omap2/clock34xx.h +++ b/trunk/arch/arm/mach-omap2/clock34xx.h @@ -478,7 +478,7 @@ static struct clk dpll3_m2_ck = { }; static const struct clksel core_ck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll3_m2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -495,7 +495,7 @@ static struct clk core_ck = { }; static const struct clksel dpll3_m2x2_ck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll3_x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -541,7 +541,7 @@ static struct clk dpll3_m3x2_ck = { }; static const struct clksel emu_core_alwon_ck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -633,7 +633,7 @@ static struct clk dpll4_m2x2_ck = { }; static const struct clksel omap_96m_alwon_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -659,7 +659,7 @@ static struct clk omap_96m_fck = { }; static const struct clksel cm_96m_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -701,7 +701,7 @@ static struct clk dpll4_m3x2_ck = { }; static const struct clksel virt_omap_54m_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -911,7 +911,7 @@ static struct clk dpll5_m2_ck = { }; static const struct clksel omap_120m_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll5_m2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -919,13 +919,13 @@ static const struct clksel omap_120m_fck_clksel[] = { static struct clk omap_120m_fck = { .name = "omap_120m_fck", .parent = &dpll5_m2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), - .clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK, - .clksel = omap_120m_fck_clksel, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), + .clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK, + .clksel = omap_120m_fck_clksel, .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, + .recalc = &omap2_clksel_recalc, }; /* CM EXTERNAL CLOCK OUTPUTS */ @@ -1034,7 +1034,7 @@ static struct clk dpll1_fck = { * called 'dpll1_fck' */ static const struct clksel mpu_clksel[] = { - { .parent = &dpll1_fck, .rates = dpll_bypass_rates }, + { .parent = &dpll1_fck, .rates = dpll_bypass_rates }, { .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -1048,7 +1048,6 @@ static struct clk mpu_ck = { .clksel = mpu_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "mpu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1076,8 +1075,6 @@ static struct clk arm_fck = { .recalc = &omap2_clksel_recalc, }; -/* XXX What about neon_clkdm ? */ - /* * REVISIT: This clock is never specifically defined in the 3430 TRM, * although it is referenced - so this is a guess @@ -1110,7 +1107,7 @@ static struct clk dpll2_fck = { */ static const struct clksel iva2_clksel[] = { - { .parent = &dpll2_fck, .rates = dpll_bypass_rates }, + { .parent = &dpll2_fck, .rates = dpll_bypass_rates }, { .parent = &dpll2_m2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -1126,7 +1123,6 @@ static struct clk iva2_ck = { .clksel_mask = OMAP3430_ST_IVA2_CLK_MASK, .clksel = iva2_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .clkdm_name = "iva2_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1141,7 +1137,6 @@ static struct clk l3_ick = { .clksel = div2_core_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l3_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1159,7 +1154,6 @@ static struct clk l4_ick = { .clksel = div2_l3_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1189,57 +1183,43 @@ static const struct clksel gfx_l3_clksel[] = { { .parent = NULL } }; -/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */ -static struct clk gfx_l3_ck = { - .name = "gfx_l3_ck", +static struct clk gfx_l3_fck = { + .name = "gfx_l3_fck", .parent = &l3_ick, .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), .enable_bit = OMAP_EN_GFX_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .recalc = &followparent_recalc, -}; - -static struct clk gfx_l3_fck = { - .name = "gfx_l3_fck", - .parent = &gfx_l3_ck, - .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), .clksel_mask = OMAP_CLKSEL_GFX_MASK, .clksel = gfx_l3_clksel, - .flags = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "gfx_3430es1_clkdm", + .flags = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES, .recalc = &omap2_clksel_recalc, }; static struct clk gfx_l3_ick = { .name = "gfx_l3_ick", - .parent = &gfx_l3_ck, - .flags = CLOCK_IN_OMAP3430ES1 | PARENT_CONTROLS_CLOCK, - .clkdm_name = "gfx_3430es1_clkdm", + .parent = &l3_ick, + .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), + .enable_bit = OMAP_EN_GFX_SHIFT, + .flags = CLOCK_IN_OMAP3430ES1, .recalc = &followparent_recalc, }; static struct clk gfx_cg1_ck = { .name = "gfx_cg1_ck", .parent = &gfx_l3_fck, /* REVISIT: correct? */ - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), .enable_bit = OMAP3430ES1_EN_2D_SHIFT, .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "gfx_3430es1_clkdm", .recalc = &followparent_recalc, }; static struct clk gfx_cg2_ck = { .name = "gfx_cg2_ck", .parent = &gfx_l3_fck, /* REVISIT: correct? */ - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), .enable_bit = OMAP3430ES1_EN_3D_SHIFT, .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "gfx_3430es1_clkdm", .recalc = &followparent_recalc, }; @@ -1272,18 +1252,15 @@ static struct clk sgx_fck = { .clksel_mask = OMAP3430ES2_CLKSEL_SGX_MASK, .clksel = sgx_clksel, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "sgx_clkdm", .recalc = &omap2_clksel_recalc, }; static struct clk sgx_ick = { .name = "sgx_ick", .parent = &l3_ick, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN), .enable_bit = OMAP3430ES2_EN_SGX_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "sgx_clkdm", .recalc = &followparent_recalc, }; @@ -1292,11 +1269,9 @@ static struct clk sgx_ick = { static struct clk d2d_26m_fck = { .name = "d2d_26m_fck", .parent = &sys_ck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430ES1_EN_D2D_SHIFT, .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "d2d_clkdm", .recalc = &followparent_recalc, }; @@ -1316,7 +1291,6 @@ static struct clk gpt10_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT10_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1330,7 +1304,6 @@ static struct clk gpt11_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT11_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1368,7 +1341,6 @@ static struct clk core_96m_fck = { .parent = &omap_96m_fck, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1379,7 +1351,6 @@ static struct clk mmchs3_fck = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1390,7 +1361,6 @@ static struct clk mmchs2_fck = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MMC2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1400,7 +1370,6 @@ static struct clk mspro_fck = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MSPRO_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1411,7 +1380,6 @@ static struct clk mmchs1_fck = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MMC1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1422,18 +1390,16 @@ static struct clk i2c3_fck = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_I2C3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; static struct clk i2c2_fck = { .name = "i2c_fck", - .id = 2, + .id = 2, .parent = &core_96m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_I2C2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1444,7 +1410,6 @@ static struct clk i2c1_fck = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_I2C1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1478,7 +1443,6 @@ static struct clk mcbsp5_fck = { .clksel_mask = OMAP2_MCBSP5_CLKS_MASK, .clksel = mcbsp_15_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1492,7 +1456,6 @@ static struct clk mcbsp1_fck = { .clksel_mask = OMAP2_MCBSP1_CLKS_MASK, .clksel = mcbsp_15_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1503,7 +1466,6 @@ static struct clk core_48m_fck = { .parent = &omap_48m_fck, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1581,7 +1543,6 @@ static struct clk core_12m_fck = { .parent = &omap_12m_fck, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1620,7 +1581,6 @@ static struct clk ssi_ssr_fck = { .clksel_mask = OMAP3430_CLKSEL_SSI_MASK, .clksel = ssi_ssr_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -1636,17 +1596,11 @@ static struct clk ssi_sst_fck = { /* CORE_L3_ICK based clocks */ -/* - * XXX must add clk_enable/clk_disable for these if standard code won't - * handle it - */ static struct clk core_l3_ick = { .name = "core_l3_ick", .parent = &l3_ick, - .init = &omap2_init_clk_clkdm, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l3_clkdm", .recalc = &followparent_recalc, }; @@ -1656,7 +1610,6 @@ static struct clk hsotgusb_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l3_clkdm", .recalc = &followparent_recalc, }; @@ -1666,7 +1619,6 @@ static struct clk sdrc_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SDRC_SHIFT, .flags = CLOCK_IN_OMAP343X | ENABLE_ON_INIT, - .clkdm_name = "core_l3_clkdm", .recalc = &followparent_recalc, }; @@ -1675,7 +1627,6 @@ static struct clk gpmc_fck = { .parent = &core_l3_ick, .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK | ENABLE_ON_INIT, - .clkdm_name = "core_l3_clkdm", .recalc = &followparent_recalc, }; @@ -1703,10 +1654,8 @@ static struct clk pka_ick = { static struct clk core_l4_ick = { .name = "core_l4_ick", .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1716,7 +1665,6 @@ static struct clk usbtll_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1727,7 +1675,6 @@ static struct clk mmchs3_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1738,7 +1685,6 @@ static struct clk icr_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_ICR_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1748,7 +1694,6 @@ static struct clk aes2_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_AES2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1758,7 +1703,6 @@ static struct clk sha12_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SHA12_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1768,7 +1712,6 @@ static struct clk des2_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_DES2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1779,7 +1722,6 @@ static struct clk mmchs2_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MMC2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1790,7 +1732,6 @@ static struct clk mmchs1_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MMC1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1800,7 +1741,6 @@ static struct clk mspro_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MSPRO_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1810,7 +1750,6 @@ static struct clk hdq_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_HDQ_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1821,7 +1760,6 @@ static struct clk mcspi4_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI4_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1832,7 +1770,6 @@ static struct clk mcspi3_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1843,7 +1780,6 @@ static struct clk mcspi2_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1854,7 +1790,6 @@ static struct clk mcspi1_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1865,7 +1800,6 @@ static struct clk i2c3_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_I2C3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1876,7 +1810,6 @@ static struct clk i2c2_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_I2C2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1887,7 +1820,6 @@ static struct clk i2c1_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_I2C1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1897,7 +1829,6 @@ static struct clk uart2_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_UART2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1907,7 +1838,6 @@ static struct clk uart1_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_UART1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1917,7 +1847,6 @@ static struct clk gpt11_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_GPT11_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1927,7 +1856,6 @@ static struct clk gpt10_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_GPT10_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1938,7 +1866,6 @@ static struct clk mcbsp5_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1949,7 +1876,6 @@ static struct clk mcbsp1_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1959,7 +1885,6 @@ static struct clk fac_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430ES1_EN_FAC_SHIFT, .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1969,7 +1894,6 @@ static struct clk mailboxes_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MAILBOXES_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1989,7 +1913,6 @@ static struct clk ssi_l4_ick = { .parent = &l4_ick, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1999,7 +1922,6 @@ static struct clk ssi_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SSI_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -2074,7 +1996,7 @@ static struct clk des1_ick = { /* DSS */ static const struct clksel dss1_alwon_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -2089,40 +2011,33 @@ static struct clk dss1_alwon_fck = { .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, .clksel = dss1_alwon_fck_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", .recalc = &omap2_clksel_recalc, }; static struct clk dss_tv_fck = { .name = "dss_tv_fck", .parent = &omap_54m_fck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_TV_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", .recalc = &followparent_recalc, }; static struct clk dss_96m_fck = { .name = "dss_96m_fck", .parent = &omap_96m_fck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_TV_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", .recalc = &followparent_recalc, }; static struct clk dss2_alwon_fck = { .name = "dss2_alwon_fck", .parent = &sys_ck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_DSS2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", .recalc = &followparent_recalc, }; @@ -2130,18 +2045,16 @@ static struct clk dss_ick = { /* Handles both L3 and L4 clocks */ .name = "dss_ick", .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", .recalc = &followparent_recalc, }; /* CAM */ static const struct clksel cam_mclk_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, + { .parent = &sys_ck, .rates = dpll_bypass_rates }, { .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates }, { .parent = NULL } }; @@ -2156,19 +2069,24 @@ static struct clk cam_mclk = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_CAM_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "cam_clkdm", .recalc = &omap2_clksel_recalc, }; -static struct clk cam_ick = { - /* Handles both L3 and L4 clocks */ - .name = "cam_ick", +static struct clk cam_l3_ick = { + .name = "cam_l3_ick", + .parent = &l3_ick, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_CAM_SHIFT, + .flags = CLOCK_IN_OMAP343X, + .recalc = &followparent_recalc, +}; + +static struct clk cam_l4_ick = { + .name = "cam_l4_ick", .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_CAM_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "cam_clkdm", .recalc = &followparent_recalc, }; @@ -2177,45 +2095,45 @@ static struct clk cam_ick = { static struct clk usbhost_120m_fck = { .name = "usbhost_120m_fck", .parent = &omap_120m_fck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", .recalc = &followparent_recalc, }; static struct clk usbhost_48m_fck = { .name = "usbhost_48m_fck", .parent = &omap_48m_fck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", .recalc = &followparent_recalc, }; -static struct clk usbhost_ick = { - /* Handles both L3 and L4 clocks */ - .name = "usbhost_ick", +static struct clk usbhost_l3_ick = { + .name = "usbhost_l3_ick", + .parent = &l3_ick, + .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), + .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, + .flags = CLOCK_IN_OMAP3430ES2, + .recalc = &followparent_recalc, +}; + +static struct clk usbhost_l4_ick = { + .name = "usbhost_l4_ick", .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", .recalc = &followparent_recalc, }; static struct clk usbhost_sar_fck = { .name = "usbhost_sar_fck", .parent = &osc_sys_ck, - .init = &omap2_init_clk_clkdm, .enable_reg = OMAP_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL), .enable_bit = OMAP3430ES2_SAVEANDRESTORE_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", .recalc = &followparent_recalc, }; @@ -2257,7 +2175,6 @@ static struct clk usim_fck = { .recalc = &omap2_clksel_recalc, }; -/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */ static struct clk gpt1_fck = { .name = "gpt1_fck", .init = &omap2_init_clksel_parent, @@ -2267,16 +2184,13 @@ static struct clk gpt1_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT1_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &omap2_clksel_recalc, }; static struct clk wkup_32k_fck = { .name = "wkup_32k_fck", - .init = &omap2_init_clk_clkdm, .parent = &omap_32k_fck, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2286,7 +2200,6 @@ static struct clk gpio1_fck = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2296,7 +2209,6 @@ static struct clk wdt2_fck = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_WDT2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2304,7 +2216,6 @@ static struct clk wkup_l4_ick = { .name = "wkup_l4_ick", .parent = &sys_ck, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2316,7 +2227,6 @@ static struct clk usim_ick = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT, .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2326,7 +2236,6 @@ static struct clk wdt2_ick = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_WDT2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2336,7 +2245,6 @@ static struct clk wdt1_ick = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_WDT1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2346,7 +2254,6 @@ static struct clk gpio1_ick = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2356,18 +2263,15 @@ static struct clk omap_32ksync_ick = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_32KSYNC_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; -/* XXX This clock no longer exists in 3430 TRM rev F */ static struct clk gpt12_ick = { .name = "gpt12_ick", .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT12_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2377,7 +2281,6 @@ static struct clk gpt1_ick = { .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT1_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -2388,20 +2291,16 @@ static struct clk gpt1_ick = { static struct clk per_96m_fck = { .name = "per_96m_fck", .parent = &omap_96m_alwon_fck, - .init = &omap2_init_clk_clkdm, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; static struct clk per_48m_fck = { .name = "per_48m_fck", .parent = &omap_48m_fck, - .init = &omap2_init_clk_clkdm, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2411,7 +2310,6 @@ static struct clk uart3_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_UART3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2424,7 +2322,6 @@ static struct clk gpt2_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT2_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2437,7 +2334,6 @@ static struct clk gpt3_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT3_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2450,7 +2346,6 @@ static struct clk gpt4_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT4_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2463,7 +2358,6 @@ static struct clk gpt5_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT5_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2476,7 +2370,6 @@ static struct clk gpt6_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT6_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2489,7 +2382,6 @@ static struct clk gpt7_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT7_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2502,7 +2394,6 @@ static struct clk gpt8_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT8_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2515,14 +2406,12 @@ static struct clk gpt9_fck = { .clksel_mask = OMAP3430_CLKSEL_GPT9_MASK, .clksel = omap343x_gpt_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; static struct clk per_32k_alwon_fck = { .name = "per_32k_alwon_fck", .parent = &omap_32k_fck, - .clkdm_name = "per_clkdm", .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, .recalc = &followparent_recalc, }; @@ -2533,7 +2422,6 @@ static struct clk gpio6_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO6_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2543,7 +2431,6 @@ static struct clk gpio5_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO5_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2553,7 +2440,6 @@ static struct clk gpio4_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO4_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2563,7 +2449,6 @@ static struct clk gpio3_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2573,7 +2458,6 @@ static struct clk gpio2_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2583,7 +2467,6 @@ static struct clk wdt3_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_WDT3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2592,7 +2475,6 @@ static struct clk per_l4_ick = { .parent = &l4_ick, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2602,7 +2484,6 @@ static struct clk gpio6_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO6_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2612,7 +2493,6 @@ static struct clk gpio5_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO5_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2622,7 +2502,6 @@ static struct clk gpio4_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO4_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2632,7 +2511,6 @@ static struct clk gpio3_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2642,7 +2520,6 @@ static struct clk gpio2_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2652,7 +2529,6 @@ static struct clk wdt3_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_WDT3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2662,7 +2538,6 @@ static struct clk uart3_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_UART3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2672,7 +2547,6 @@ static struct clk gpt9_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT9_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2682,7 +2556,6 @@ static struct clk gpt8_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT8_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2692,7 +2565,6 @@ static struct clk gpt7_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT7_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2702,7 +2574,6 @@ static struct clk gpt6_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT6_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2712,7 +2583,6 @@ static struct clk gpt5_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT5_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2722,7 +2592,6 @@ static struct clk gpt4_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT4_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2732,7 +2601,6 @@ static struct clk gpt3_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2742,7 +2610,6 @@ static struct clk gpt2_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2753,7 +2620,6 @@ static struct clk mcbsp2_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2764,7 +2630,6 @@ static struct clk mcbsp3_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; @@ -2775,13 +2640,12 @@ static struct clk mcbsp4_ick = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &followparent_recalc, }; static const struct clksel mcbsp_234_clksel[] = { { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates }, - { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, + { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, { .parent = NULL } }; @@ -2795,7 +2659,6 @@ static struct clk mcbsp2_fck = { .clksel_mask = OMAP2_MCBSP2_CLKS_MASK, .clksel = mcbsp_234_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2809,7 +2672,6 @@ static struct clk mcbsp3_fck = { .clksel_mask = OMAP2_MCBSP3_CLKS_MASK, .clksel = mcbsp_234_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2823,7 +2685,6 @@ static struct clk mcbsp4_fck = { .clksel_mask = OMAP2_MCBSP4_CLKS_MASK, .clksel = mcbsp_234_clksel, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2871,7 +2732,6 @@ static struct clk emu_src_ck = { .clksel_mask = OMAP3430_MUX_CTRL_MASK, .clksel = emu_src_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2895,7 +2755,6 @@ static struct clk pclk_fck = { .clksel_mask = OMAP3430_CLKSEL_PCLK_MASK, .clksel = pclk_emu_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2918,7 +2777,6 @@ static struct clk pclkx2_fck = { .clksel_mask = OMAP3430_CLKSEL_PCLKX2_MASK, .clksel = pclkx2_emu_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2934,7 +2792,6 @@ static struct clk atclk_fck = { .clksel_mask = OMAP3430_CLKSEL_ATCLK_MASK, .clksel = atclk_emu_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2945,7 +2802,6 @@ static struct clk traceclk_src_fck = { .clksel_mask = OMAP3430_TRACE_MUX_CTRL_MASK, .clksel = emu_src_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2968,7 +2824,6 @@ static struct clk traceclk_fck = { .clksel_mask = OMAP3430_CLKSEL_TRACECLK_MASK, .clksel = traceclk_clksel, .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -2998,13 +2853,11 @@ static struct clk sr_l4_ick = { .name = "sr_l4_ick", .parent = &l4_ick, .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; /* SECURE_32K_FCK clocks */ -/* XXX This clock no longer exists in 3430 TRM rev F */ static struct clk gpt12_fck = { .name = "gpt12_fck", .parent = &secure_32k_fck, @@ -3080,7 +2933,6 @@ static struct clk *onchip_34xx_clks[] __initdata = { &l3_ick, &l4_ick, &rm_ick, - &gfx_l3_ck, &gfx_l3_fck, &gfx_l3_ick, &gfx_cg1_ck, @@ -3162,10 +3014,12 @@ static struct clk *onchip_34xx_clks[] __initdata = { &dss2_alwon_fck, &dss_ick, &cam_mclk, - &cam_ick, + &cam_l3_ick, + &cam_l4_ick, &usbhost_120m_fck, &usbhost_48m_fck, - &usbhost_ick, + &usbhost_l3_ick, + &usbhost_l4_ick, &usbhost_sar_fck, &usim_fck, &gpt1_fck, diff --git a/trunk/arch/arm/mach-omap2/clockdomain.c b/trunk/arch/arm/mach-omap2/clockdomain.c deleted file mode 100644 index 4c3ce9cfd948..000000000000 --- a/trunk/arch/arm/mach-omap2/clockdomain.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - * OMAP2/3 clockdomain framework functions - * - * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008 Nokia Corporation - * - * Written by Paul Walmsley and Jouni Högander - * - * 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. - */ -#ifdef CONFIG_OMAP_DEBUG_CLOCKDOMAIN -# define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include "prm.h" -#include "prm-regbits-24xx.h" -#include "cm.h" - -#include -#include - -/* clkdm_list contains all registered struct clockdomains */ -static LIST_HEAD(clkdm_list); - -/* clkdm_mutex protects clkdm_list add and del ops */ -static DEFINE_MUTEX(clkdm_mutex); - -/* array of powerdomain deps to be added/removed when clkdm in hwsup mode */ -static struct clkdm_pwrdm_autodep *autodeps; - - -/* Private functions */ - -/* - * _autodep_lookup - resolve autodep pwrdm names to pwrdm pointers; store - * @autodep: struct clkdm_pwrdm_autodep * to resolve - * - * Resolve autodep powerdomain names to powerdomain pointers via - * pwrdm_lookup() and store the pointers in the autodep structure. An - * "autodep" is a powerdomain sleep/wakeup dependency that is - * automatically added and removed whenever clocks in the associated - * clockdomain are enabled or disabled (respectively) when the - * clockdomain is in hardware-supervised mode. Meant to be called - * once at clockdomain layer initialization, since these should remain - * fixed for a particular architecture. No return value. - */ -static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep) -{ - struct powerdomain *pwrdm; - - if (!autodep) - return; - - if (!omap_chip_is(autodep->omap_chip)) - return; - - pwrdm = pwrdm_lookup(autodep->pwrdm_name); - if (!pwrdm) { - pr_debug("clockdomain: _autodep_lookup: powerdomain %s " - "does not exist\n", autodep->pwrdm_name); - WARN_ON(1); - return; - } - autodep->pwrdm = pwrdm; - - return; -} - -/* - * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable - * @clkdm: struct clockdomain * - * - * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' - * in hardware-supervised mode. Meant to be called from clock framework - * when a clock inside clockdomain 'clkdm' is enabled. No return value. - */ -static void _clkdm_add_autodeps(struct clockdomain *clkdm) -{ - struct clkdm_pwrdm_autodep *autodep; - - for (autodep = autodeps; autodep->pwrdm_name; autodep++) { - if (!autodep->pwrdm) - continue; - - pr_debug("clockdomain: adding %s sleepdep/wkdep for " - "pwrdm %s\n", autodep->pwrdm_name, - clkdm->pwrdm->name); - - pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm); - pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm); - } -} - -/* - * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm - * @clkdm: struct clockdomain * - * - * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' - * in hardware-supervised mode. Meant to be called from clock framework - * when a clock inside clockdomain 'clkdm' is disabled. No return value. - */ -static void _clkdm_del_autodeps(struct clockdomain *clkdm) -{ - struct clkdm_pwrdm_autodep *autodep; - - for (autodep = autodeps; autodep->pwrdm_name; autodep++) { - if (!autodep->pwrdm) - continue; - - pr_debug("clockdomain: removing %s sleepdep/wkdep for " - "pwrdm %s\n", autodep->pwrdm_name, - clkdm->pwrdm->name); - - pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm); - pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm); - } -} - - -static struct clockdomain *_clkdm_lookup(const char *name) -{ - struct clockdomain *clkdm, *temp_clkdm; - - if (!name) - return NULL; - - clkdm = NULL; - - list_for_each_entry(temp_clkdm, &clkdm_list, node) { - if (!strcmp(name, temp_clkdm->name)) { - clkdm = temp_clkdm; - break; - } - } - - return clkdm; -} - - -/* Public functions */ - -/** - * clkdm_init - set up the clockdomain layer - * @clkdms: optional pointer to an array of clockdomains to register - * @init_autodeps: optional pointer to an array of autodeps to register - * - * Set up internal state. If a pointer to an array of clockdomains - * was supplied, loop through the list of clockdomains, register all - * that are available on the current platform. Similarly, if a - * pointer to an array of clockdomain-powerdomain autodependencies was - * provided, register those. No return value. - */ -void clkdm_init(struct clockdomain **clkdms, - struct clkdm_pwrdm_autodep *init_autodeps) -{ - struct clockdomain **c = NULL; - struct clkdm_pwrdm_autodep *autodep = NULL; - - if (clkdms) - for (c = clkdms; *c; c++) - clkdm_register(*c); - - autodeps = init_autodeps; - if (autodeps) - for (autodep = autodeps; autodep->pwrdm_name; autodep++) - _autodep_lookup(autodep); -} - -/** - * clkdm_register - register a clockdomain - * @clkdm: struct clockdomain * to register - * - * Adds a clockdomain to the internal clockdomain list. - * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is - * already registered by the provided name, or 0 upon success. - */ -int clkdm_register(struct clockdomain *clkdm) -{ - int ret = -EINVAL; - struct powerdomain *pwrdm; - - if (!clkdm || !clkdm->name) - return -EINVAL; - - if (!omap_chip_is(clkdm->omap_chip)) - return -EINVAL; - - pwrdm = pwrdm_lookup(clkdm->pwrdm_name); - if (!pwrdm) { - pr_debug("clockdomain: clkdm_register %s: powerdomain %s " - "does not exist\n", clkdm->name, clkdm->pwrdm_name); - return -EINVAL; - } - clkdm->pwrdm = pwrdm; - - mutex_lock(&clkdm_mutex); - /* Verify that the clockdomain is not already registered */ - if (_clkdm_lookup(clkdm->name)) { - ret = -EEXIST; - goto cr_unlock; - }; - - list_add(&clkdm->node, &clkdm_list); - - pwrdm_add_clkdm(pwrdm, clkdm); - - pr_debug("clockdomain: registered %s\n", clkdm->name); - ret = 0; - -cr_unlock: - mutex_unlock(&clkdm_mutex); - - return ret; -} - -/** - * clkdm_unregister - unregister a clockdomain - * @clkdm: struct clockdomain * to unregister - * - * Removes a clockdomain from the internal clockdomain list. Returns - * -EINVAL if clkdm argument is NULL. - */ -int clkdm_unregister(struct clockdomain *clkdm) -{ - if (!clkdm) - return -EINVAL; - - pwrdm_del_clkdm(clkdm->pwrdm, clkdm); - - mutex_lock(&clkdm_mutex); - list_del(&clkdm->node); - mutex_unlock(&clkdm_mutex); - - pr_debug("clockdomain: unregistered %s\n", clkdm->name); - - return 0; -} - -/** - * clkdm_lookup - look up a clockdomain by name, return a pointer - * @name: name of clockdomain - * - * Find a registered clockdomain by its name. Returns a pointer to the - * struct clockdomain if found, or NULL otherwise. - */ -struct clockdomain *clkdm_lookup(const char *name) -{ - struct clockdomain *clkdm, *temp_clkdm; - - if (!name) - return NULL; - - clkdm = NULL; - - mutex_lock(&clkdm_mutex); - list_for_each_entry(temp_clkdm, &clkdm_list, node) { - if (!strcmp(name, temp_clkdm->name)) { - clkdm = temp_clkdm; - break; - } - } - mutex_unlock(&clkdm_mutex); - - return clkdm; -} - -/** - * clkdm_for_each - call function on each registered clockdomain - * @fn: callback function * - * - * Call the supplied function for each registered clockdomain. - * The callback function can return anything but 0 to bail - * out early from the iterator. The callback function is called with - * the clkdm_mutex held, so no clockdomain structure manipulation - * functions should be called from the callback, although hardware - * clockdomain control functions are fine. Returns the last return - * value of the callback function, which should be 0 for success or - * anything else to indicate failure; or -EINVAL if the function pointer - * is null. - */ -int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) -{ - struct clockdomain *clkdm; - int ret = 0; - - if (!fn) - return -EINVAL; - - mutex_lock(&clkdm_mutex); - list_for_each_entry(clkdm, &clkdm_list, node) { - ret = (*fn)(clkdm); - if (ret) - break; - } - mutex_unlock(&clkdm_mutex); - - return ret; -} - - -/** - * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in - * @clkdm: struct clockdomain * - * - * Return a pointer to the struct powerdomain that the specified clockdomain - * 'clkdm' exists in, or returns NULL if clkdm argument is NULL. - */ -struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm) -{ - if (!clkdm) - return NULL; - - return clkdm->pwrdm; -} - - -/* Hardware clockdomain control */ - -/** - * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode - * @clk: struct clk * of a clockdomain - * - * Return the clockdomain's current state transition mode from the - * corresponding domain CM_CLKSTCTRL register. Returns -EINVAL if clk - * is NULL or the current mode upon success. - */ -static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm) -{ - u32 v; - - if (!clkdm) - return -EINVAL; - - v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); - v &= clkdm->clktrctrl_mask; - v >>= __ffs(clkdm->clktrctrl_mask); - - return v; -} - -/** - * omap2_clkdm_sleep - force clockdomain sleep transition - * @clkdm: struct clockdomain * - * - * Instruct the CM to force a sleep transition on the specified - * clockdomain 'clkdm'. Returns -EINVAL if clk is NULL or if - * clockdomain does not support software-initiated sleep; 0 upon - * success. - */ -int omap2_clkdm_sleep(struct clockdomain *clkdm) -{ - if (!clkdm) - return -EINVAL; - - if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { - pr_debug("clockdomain: %s does not support forcing " - "sleep via software\n", clkdm->name); - return -EINVAL; - } - - pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); - - if (cpu_is_omap24xx()) { - - cm_set_mod_reg_bits(OMAP24XX_FORCESTATE, - clkdm->pwrdm->prcm_offs, PM_PWSTCTRL); - - } else if (cpu_is_omap34xx()) { - - u32 v = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP << - __ffs(clkdm->clktrctrl_mask)); - - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v, - clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); - - } else { - BUG(); - }; - - return 0; -} - -/** - * omap2_clkdm_wakeup - force clockdomain wakeup transition - * @clkdm: struct clockdomain * - * - * Instruct the CM to force a wakeup transition on the specified - * clockdomain 'clkdm'. Returns -EINVAL if clkdm is NULL or if the - * clockdomain does not support software-controlled wakeup; 0 upon - * success. - */ -int omap2_clkdm_wakeup(struct clockdomain *clkdm) -{ - if (!clkdm) - return -EINVAL; - - if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { - pr_debug("clockdomain: %s does not support forcing " - "wakeup via software\n", clkdm->name); - return -EINVAL; - } - - pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); - - if (cpu_is_omap24xx()) { - - cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE, - clkdm->pwrdm->prcm_offs, PM_PWSTCTRL); - - } else if (cpu_is_omap34xx()) { - - u32 v = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP << - __ffs(clkdm->clktrctrl_mask)); - - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v, - clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); - - } else { - BUG(); - }; - - return 0; -} - -/** - * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm - * @clkdm: struct clockdomain * - * - * Allow the hardware to automatically switch the clockdomain into - * active or idle states, as needed by downstream clocks. If the - * clockdomain has any downstream clocks enabled in the clock - * framework, wkdep/sleepdep autodependencies are added; this is so - * device drivers can read and write to the device. No return value. - */ -void omap2_clkdm_allow_idle(struct clockdomain *clkdm) -{ - u32 v; - - if (!clkdm) - return; - - if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) { - pr_debug("clock: automatic idle transitions cannot be enabled " - "on clockdomain %s\n", clkdm->name); - return; - } - - pr_debug("clockdomain: enabling automatic idle transitions for %s\n", - clkdm->name); - - if (atomic_read(&clkdm->usecount) > 0) - _clkdm_add_autodeps(clkdm); - - if (cpu_is_omap24xx()) - v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO; - else if (cpu_is_omap34xx()) - v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO; - else - BUG(); - - - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, - v << __ffs(clkdm->clktrctrl_mask), - clkdm->pwrdm->prcm_offs, - CM_CLKSTCTRL); -} - -/** - * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm - * @clkdm: struct clockdomain * - * - * Prevent the hardware from automatically switching the clockdomain - * into inactive or idle states. If the clockdomain has downstream - * clocks enabled in the clock framework, wkdep/sleepdep - * autodependencies are removed. No return value. - */ -void omap2_clkdm_deny_idle(struct clockdomain *clkdm) -{ - u32 v; - - if (!clkdm) - return; - - if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) { - pr_debug("clockdomain: automatic idle transitions cannot be " - "disabled on %s\n", clkdm->name); - return; - } - - pr_debug("clockdomain: disabling automatic idle transitions for %s\n", - clkdm->name); - - if (cpu_is_omap24xx()) - v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO; - else if (cpu_is_omap34xx()) - v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO; - else - BUG(); - - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, - v << __ffs(clkdm->clktrctrl_mask), - clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); - - if (atomic_read(&clkdm->usecount) > 0) - _clkdm_del_autodeps(clkdm); -} - - -/* Clockdomain-to-clock framework interface code */ - -/** - * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm - * @clkdm: struct clockdomain * - * @clk: struct clk * of the enabled downstream clock - * - * Increment the usecount of this clockdomain 'clkdm' and ensure that - * it is awake. Intended to be called by clk_enable() code. If the - * clockdomain is in software-supervised idle mode, force the - * clockdomain to wake. If the clockdomain is in hardware-supervised - * idle mode, add clkdm-pwrdm autodependencies, to ensure that devices - * in the clockdomain can be read from/written to by on-chip processors. - * Returns -EINVAL if passed null pointers; returns 0 upon success or - * if the clockdomain is in hwsup idle mode. - */ -int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) -{ - int v; - - /* - * XXX Rewrite this code to maintain a list of enabled - * downstream clocks for debugging purposes? - */ - - if (!clkdm || !clk) - return -EINVAL; - - if (atomic_inc_return(&clkdm->usecount) > 1) - return 0; - - /* Clockdomain now has one enabled downstream clock */ - - pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name, - clk->name); - - v = omap2_clkdm_clktrctrl_read(clkdm); - - if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || - (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) - _clkdm_add_autodeps(clkdm); - else - omap2_clkdm_wakeup(clkdm); - - return 0; -} - -/** - * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm - * @clkdm: struct clockdomain * - * @clk: struct clk * of the disabled downstream clock - * - * Decrement the usecount of this clockdomain 'clkdm'. Intended to be - * called by clk_disable() code. If the usecount goes to 0, put the - * clockdomain to sleep (software-supervised mode) or remove the - * clkdm-pwrdm autodependencies (hardware-supervised mode). Returns - * -EINVAL if passed null pointers; -ERANGE if the clkdm usecount - * underflows and debugging is enabled; or returns 0 upon success or - * if the clockdomain is in hwsup idle mode. - */ -int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) -{ - int v; - - /* - * XXX Rewrite this code to maintain a list of enabled - * downstream clocks for debugging purposes? - */ - - if (!clkdm || !clk) - return -EINVAL; - -#ifdef DEBUG - if (atomic_read(&clkdm->usecount) == 0) { - WARN_ON(1); /* underflow */ - return -ERANGE; - } -#endif - - if (atomic_dec_return(&clkdm->usecount) > 0) - return 0; - - /* All downstream clocks of this clockdomain are now disabled */ - - pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name, - clk->name); - - v = omap2_clkdm_clktrctrl_read(clkdm); - - if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || - (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) - _clkdm_del_autodeps(clkdm); - else - omap2_clkdm_sleep(clkdm); - - return 0; -} - diff --git a/trunk/arch/arm/mach-omap2/clockdomains.h b/trunk/arch/arm/mach-omap2/clockdomains.h deleted file mode 100644 index cd86dcc7b424..000000000000 --- a/trunk/arch/arm/mach-omap2/clockdomains.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * OMAP2/3 clockdomains - * - * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008 Nokia Corporation - * - * Written by Paul Walmsley - */ - -#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H -#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H - -#include - -/* - * OMAP2/3-common clockdomains - */ - -/* This is an implicit clockdomain - it is never defined as such in TRM */ -static struct clockdomain wkup_clkdm = { - .name = "wkup_clkdm", - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), -}; - -/* - * 2420-only clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP2420) - -static struct clockdomain mpu_2420_clkdm = { - .name = "mpu_clkdm", - .pwrdm_name = "mpu_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -}; - -static struct clockdomain iva1_2420_clkdm = { - .name = "iva1_clkdm", - .pwrdm_name = "dsp_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -}; - -#endif /* CONFIG_ARCH_OMAP2420 */ - - -/* - * 2430-only clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP2430) - -static struct clockdomain mpu_2430_clkdm = { - .name = "mpu_clkdm", - .pwrdm_name = "mpu_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -}; - -static struct clockdomain mdm_clkdm = { - .name = "mdm_clkdm", - .pwrdm_name = "mdm_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -}; - -#endif /* CONFIG_ARCH_OMAP2430 */ - - -/* - * 24XX-only clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP24XX) - -static struct clockdomain dsp_clkdm = { - .name = "dsp_clkdm", - .pwrdm_name = "dsp_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain gfx_24xx_clkdm = { - .name = "gfx_clkdm", - .pwrdm_name = "gfx_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain core_l3_24xx_clkdm = { - .name = "core_l3_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain core_l4_24xx_clkdm = { - .name = "core_l4_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain dss_24xx_clkdm = { - .name = "dss_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -#endif /* CONFIG_ARCH_OMAP24XX */ - - -/* - * 34xx clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP34XX) - -static struct clockdomain mpu_34xx_clkdm = { - .name = "mpu_clkdm", - .pwrdm_name = "mpu_pwrdm", - .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain neon_clkdm = { - .name = "neon_clkdm", - .pwrdm_name = "neon_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain iva2_clkdm = { - .name = "iva2_clkdm", - .pwrdm_name = "iva2_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain gfx_3430es1_clkdm = { - .name = "gfx_clkdm", - .pwrdm_name = "gfx_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1), -}; - -static struct clockdomain sgx_clkdm = { - .name = "sgx_clkdm", - .pwrdm_name = "sgx_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), -}; - -/* - * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but - * then that information was removed from the 34xx ES2+ TRM. It is - * unclear whether the core is still there, but the clockdomain logic - * is there, and must be programmed to an appropriate state if the - * CORE clockdomain is to become inactive. - */ -static struct clockdomain d2d_clkdm = { - .name = "d2d_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain core_l3_34xx_clkdm = { - .name = "core_l3_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain core_l4_34xx_clkdm = { - .name = "core_l4_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain dss_34xx_clkdm = { - .name = "dss_clkdm", - .pwrdm_name = "dss_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain cam_clkdm = { - .name = "cam_clkdm", - .pwrdm_name = "cam_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain usbhost_clkdm = { - .name = "usbhost_clkdm", - .pwrdm_name = "usbhost_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), -}; - -static struct clockdomain per_clkdm = { - .name = "per_clkdm", - .pwrdm_name = "per_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain emu_clkdm = { - .name = "emu_clkdm", - .pwrdm_name = "emu_pwrdm", - .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -#endif /* CONFIG_ARCH_OMAP34XX */ - -/* - * Clockdomain-powerdomain hwsup dependencies (34XX only) - */ - -static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL } -}; - -/* - * - */ - -static struct clockdomain *clockdomains_omap[] = { - - &wkup_clkdm, - -#ifdef CONFIG_ARCH_OMAP2420 - &mpu_2420_clkdm, - &iva1_2420_clkdm, -#endif - -#ifdef CONFIG_ARCH_OMAP2430 - &mpu_2430_clkdm, - &mdm_clkdm, -#endif - -#ifdef CONFIG_ARCH_OMAP24XX - &dsp_clkdm, - &gfx_24xx_clkdm, - &core_l3_24xx_clkdm, - &core_l4_24xx_clkdm, - &dss_24xx_clkdm, -#endif - -#ifdef CONFIG_ARCH_OMAP34XX - &mpu_34xx_clkdm, - &neon_clkdm, - &iva2_clkdm, - &gfx_3430es1_clkdm, - &sgx_clkdm, - &d2d_clkdm, - &core_l3_34xx_clkdm, - &core_l4_34xx_clkdm, - &dss_34xx_clkdm, - &cam_clkdm, - &usbhost_clkdm, - &per_clkdm, - &emu_clkdm, -#endif - - NULL, -}; - -#endif diff --git a/trunk/arch/arm/mach-omap2/cm-regbits-24xx.h b/trunk/arch/arm/mach-omap2/cm-regbits-24xx.h index 1098ecfab861..20ac38100678 100644 --- a/trunk/arch/arm/mach-omap2/cm-regbits-24xx.h +++ b/trunk/arch/arm/mach-omap2/cm-regbits-24xx.h @@ -63,8 +63,7 @@ #define OMAP24XX_CLKSEL_MPU_MASK (0x1f << 0) /* CM_CLKSTCTRL_MPU */ -#define OMAP24XX_AUTOSTATE_MPU_SHIFT 0 -#define OMAP24XX_AUTOSTATE_MPU_MASK (1 << 0) +#define OMAP24XX_AUTOSTATE_MPU (1 << 0) /* CM_FCLKEN1_CORE specific bits*/ #define OMAP24XX_EN_TV_SHIFT 2 @@ -239,12 +238,9 @@ #define OMAP24XX_CLKSEL_GPT2_MASK (0x3 << 2) /* CM_CLKSTCTRL_CORE */ -#define OMAP24XX_AUTOSTATE_DSS_SHIFT 2 -#define OMAP24XX_AUTOSTATE_DSS_MASK (1 << 2) -#define OMAP24XX_AUTOSTATE_L4_SHIFT 1 -#define OMAP24XX_AUTOSTATE_L4_MASK (1 << 1) -#define OMAP24XX_AUTOSTATE_L3_SHIFT 0 -#define OMAP24XX_AUTOSTATE_L3_MASK (1 << 0) +#define OMAP24XX_AUTOSTATE_DSS (1 << 2) +#define OMAP24XX_AUTOSTATE_L4 (1 << 1) +#define OMAP24XX_AUTOSTATE_L3 (1 << 0) /* CM_FCLKEN_GFX */ #define OMAP24XX_EN_3D_SHIFT 2 @@ -259,8 +255,7 @@ /* CM_CLKSEL_GFX specific bits */ /* CM_CLKSTCTRL_GFX */ -#define OMAP24XX_AUTOSTATE_GFX_SHIFT 0 -#define OMAP24XX_AUTOSTATE_GFX_MASK (1 << 0) +#define OMAP24XX_AUTOSTATE_GFX (1 << 0) /* CM_FCLKEN_WKUP specific bits */ @@ -372,10 +367,8 @@ #define OMAP24XX_CLKSEL_DSP_MASK (0x1f << 0) /* CM_CLKSTCTRL_DSP */ -#define OMAP2420_AUTOSTATE_IVA_SHIFT 8 -#define OMAP2420_AUTOSTATE_IVA_MASK (1 << 8) -#define OMAP24XX_AUTOSTATE_DSP_SHIFT 0 -#define OMAP24XX_AUTOSTATE_DSP_MASK (1 << 0) +#define OMAP2420_AUTOSTATE_IVA (1 << 8) +#define OMAP24XX_AUTOSTATE_DSP (1 << 0) /* CM_FCLKEN_MDM */ /* 2430 only */ @@ -403,7 +396,6 @@ /* CM_CLKSTCTRL_MDM */ /* 2430 only */ -#define OMAP2430_AUTOSTATE_MDM_SHIFT 0 -#define OMAP2430_AUTOSTATE_MDM_MASK (1 << 0) +#define OMAP2430_AUTOSTATE_MDM (1 << 0) #endif diff --git a/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h b/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h index 219f5c8d9659..ee4c0ca1a708 100644 --- a/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -96,8 +96,7 @@ #define OMAP3430_CLKTRCTRL_IVA2_MASK (0x3 << 0) /* CM_CLKSTST_IVA2 */ -#define OMAP3430_CLKACTIVITY_IVA2_SHIFT 0 -#define OMAP3430_CLKACTIVITY_IVA2_MASK (1 << 0) +#define OMAP3430_CLKACTIVITY_IVA2 (1 << 0) /* CM_REVISION specific bits */ @@ -141,8 +140,7 @@ #define OMAP3430_CLKTRCTRL_MPU_MASK (0x3 << 0) /* CM_CLKSTST_MPU */ -#define OMAP3430_CLKACTIVITY_MPU_SHIFT 0 -#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0) +#define OMAP3430_CLKACTIVITY_MPU (1 << 0) /* CM_FCLKEN1_CORE specific bits */ @@ -302,12 +300,9 @@ #define OMAP3430_CLKTRCTRL_L3_MASK (0x3 << 0) /* CM_CLKSTST_CORE */ -#define OMAP3430ES1_CLKACTIVITY_D2D_SHIFT 2 -#define OMAP3430ES1_CLKACTIVITY_D2D_MASK (1 << 2) -#define OMAP3430_CLKACTIVITY_L4_SHIFT 1 -#define OMAP3430_CLKACTIVITY_L4_MASK (1 << 1) -#define OMAP3430_CLKACTIVITY_L3_SHIFT 0 -#define OMAP3430_CLKACTIVITY_L3_MASK (1 << 0) +#define OMAP3430ES1_CLKACTIVITY_D2D (1 << 2) +#define OMAP3430_CLKACTIVITY_L4 (1 << 1) +#define OMAP3430_CLKACTIVITY_L3 (1 << 0) /* CM_FCLKEN_GFX */ #define OMAP3430ES1_EN_3D (1 << 2) @@ -328,8 +323,7 @@ #define OMAP3430ES1_CLKTRCTRL_GFX_MASK (0x3 << 0) /* CM_CLKSTST_GFX */ -#define OMAP3430ES1_CLKACTIVITY_GFX_SHIFT 0 -#define OMAP3430ES1_CLKACTIVITY_GFX_MASK (1 << 0) +#define OMAP3430ES1_CLKACTIVITY_GFX (1 << 0) /* CM_FCLKEN_SGX */ #define OMAP3430ES2_EN_SGX_SHIFT 1 @@ -339,14 +333,6 @@ #define OMAP3430ES2_CLKSEL_SGX_SHIFT 0 #define OMAP3430ES2_CLKSEL_SGX_MASK (0x7 << 0) -/* CM_CLKSTCTRL_SGX */ -#define OMAP3430ES2_CLKTRCTRL_SGX_SHIFT 0 -#define OMAP3430ES2_CLKTRCTRL_SGX_MASK (0x3 << 0) - -/* CM_CLKSTST_SGX */ -#define OMAP3430ES2_CLKACTIVITY_SGX_SHIFT 0 -#define OMAP3430ES2_CLKACTIVITY_SGX_MASK (1 << 0) - /* CM_FCLKEN_WKUP specific bits */ #define OMAP3430ES2_EN_USIMOCP_SHIFT 9 @@ -512,8 +498,7 @@ #define OMAP3430_CLKTRCTRL_DSS_MASK (0x3 << 0) /* CM_CLKSTST_DSS */ -#define OMAP3430_CLKACTIVITY_DSS_SHIFT 0 -#define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0) +#define OMAP3430_CLKACTIVITY_DSS (1 << 0) /* CM_FCLKEN_CAM specific bits */ @@ -537,8 +522,7 @@ #define OMAP3430_CLKTRCTRL_CAM_MASK (0x3 << 0) /* CM_CLKSTST_CAM */ -#define OMAP3430_CLKACTIVITY_CAM_SHIFT 0 -#define OMAP3430_CLKACTIVITY_CAM_MASK (1 << 0) +#define OMAP3430_CLKACTIVITY_CAM (1 << 0) /* CM_FCLKEN_PER specific bits */ @@ -614,8 +598,7 @@ #define OMAP3430_CLKTRCTRL_PER_MASK (0x3 << 0) /* CM_CLKSTST_PER */ -#define OMAP3430_CLKACTIVITY_PER_SHIFT 0 -#define OMAP3430_CLKACTIVITY_PER_MASK (1 << 0) +#define OMAP3430_CLKACTIVITY_PER (1 << 0) /* CM_CLKSEL1_EMU */ #define OMAP3430_DIV_DPLL4_SHIFT 24 @@ -640,8 +623,7 @@ #define OMAP3430_CLKTRCTRL_EMU_MASK (0x3 << 0) /* CM_CLKSTST_EMU */ -#define OMAP3430_CLKACTIVITY_EMU_SHIFT 0 -#define OMAP3430_CLKACTIVITY_EMU_MASK (1 << 0) +#define OMAP3430_CLKACTIVITY_EMU (1 << 0) /* CM_CLKSEL2_EMU specific bits */ #define OMAP3430_CORE_DPLL_EMU_MULT_SHIFT 8 @@ -691,8 +673,6 @@ #define OMAP3430ES2_CLKTRCTRL_USBHOST_SHIFT 0 #define OMAP3430ES2_CLKTRCTRL_USBHOST_MASK (3 << 0) -/* CM_CLKSTST_USBHOST */ -#define OMAP3430ES2_CLKACTIVITY_USBHOST_SHIFT 0 -#define OMAP3430ES2_CLKACTIVITY_USBHOST_MASK (1 << 0) + #endif diff --git a/trunk/arch/arm/mach-omap2/cm.h b/trunk/arch/arm/mach-omap2/cm.h index 65fdf78c91e1..87a44c715aa4 100644 --- a/trunk/arch/arm/mach-omap2/cm.h +++ b/trunk/arch/arm/mach-omap2/cm.h @@ -18,7 +18,7 @@ #ifndef __ASSEMBLER__ #define OMAP_CM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg)) + (void __iomem *)IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg)) #else #define OMAP2420_CM_REGADDR(module, reg) \ IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg)) diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index 90af2ac469aa..2ee954a0bc7c 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -23,7 +23,50 @@ #include #include #include -#include + +#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) + +#define OMAP2_I2C_BASE2 0x48072000 +#define OMAP2_I2C_INT2 57 + +static struct resource i2c_resources2[] = { + { + .start = OMAP2_I2C_BASE2, + .end = OMAP2_I2C_BASE2 + 0x3f, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP2_I2C_INT2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device omap_i2c_device2 = { + .name = "i2c_omap", + .id = 2, + .num_resources = ARRAY_SIZE(i2c_resources2), + .resource = i2c_resources2, +}; + +/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */ +static void omap_init_i2c(void) +{ + /* REVISIT: Second I2C not in use on H4? */ + if (machine_is_omap_h4()) + return; + + if (!cpu_is_omap2430()) { + omap_cfg_reg(J15_24XX_I2C2_SCL); + omap_cfg_reg(H19_24XX_I2C2_SDA); + } + (void) platform_device_register(&omap_i2c_device2); +} + +#else + +static void omap_init_i2c(void) {} + +#endif #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) #define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) @@ -61,9 +104,7 @@ static inline void omap_init_mbox(void) { } #if defined(CONFIG_OMAP_STI) -#if defined(CONFIG_ARCH_OMAP2) - -#define OMAP2_STI_BASE 0x48068000 +#define OMAP2_STI_BASE IO_ADDRESS(0x48068000) #define OMAP2_STI_CHANNEL_BASE 0x54000000 #define OMAP2_STI_IRQ 4 @@ -83,25 +124,6 @@ static struct resource sti_resources[] = { .flags = IORESOURCE_IRQ, } }; -#elif defined(CONFIG_ARCH_OMAP3) - -#define OMAP3_SDTI_BASE 0x54500000 -#define OMAP3_SDTI_CHANNEL_BASE 0x54600000 - -static struct resource sti_resources[] = { - { - .start = OMAP3_SDTI_BASE, - .end = OMAP3_SDTI_BASE + 0xFFF, - .flags = IORESOURCE_MEM, - }, - { - .start = OMAP3_SDTI_CHANNEL_BASE, - .end = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - } -}; - -#endif static struct platform_device sti_device = { .name = "sti", @@ -118,14 +140,12 @@ static inline void omap_init_sti(void) static inline void omap_init_sti(void) {} #endif -#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) +#if defined(CONFIG_SPI_OMAP24XX) #include #define OMAP2_MCSPI1_BASE 0x48098000 #define OMAP2_MCSPI2_BASE 0x4809a000 -#define OMAP2_MCSPI3_BASE 0x480b8000 -#define OMAP2_MCSPI4_BASE 0x480ba000 static struct omap2_mcspi_platform_config omap2_mcspi1_config = { .num_cs = 4, @@ -139,7 +159,7 @@ static struct resource omap2_mcspi1_resources[] = { }, }; -static struct platform_device omap2_mcspi1 = { +struct platform_device omap2_mcspi1 = { .name = "omap2_mcspi", .id = 1, .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), @@ -161,7 +181,7 @@ static struct resource omap2_mcspi2_resources[] = { }, }; -static struct platform_device omap2_mcspi2 = { +struct platform_device omap2_mcspi2 = { .name = "omap2_mcspi", .id = 2, .num_resources = ARRAY_SIZE(omap2_mcspi2_resources), @@ -171,162 +191,16 @@ static struct platform_device omap2_mcspi2 = { }, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) -static struct omap2_mcspi_platform_config omap2_mcspi3_config = { - .num_cs = 2, -}; - -static struct resource omap2_mcspi3_resources[] = { - { - .start = OMAP2_MCSPI3_BASE, - .end = OMAP2_MCSPI3_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_mcspi3 = { - .name = "omap2_mcspi", - .id = 3, - .num_resources = ARRAY_SIZE(omap2_mcspi3_resources), - .resource = omap2_mcspi3_resources, - .dev = { - .platform_data = &omap2_mcspi3_config, - }, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP3 -static struct omap2_mcspi_platform_config omap2_mcspi4_config = { - .num_cs = 1, -}; - -static struct resource omap2_mcspi4_resources[] = { - { - .start = OMAP2_MCSPI4_BASE, - .end = OMAP2_MCSPI4_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_mcspi4 = { - .name = "omap2_mcspi", - .id = 4, - .num_resources = ARRAY_SIZE(omap2_mcspi4_resources), - .resource = omap2_mcspi4_resources, - .dev = { - .platform_data = &omap2_mcspi4_config, - }, -}; -#endif - static void omap_init_mcspi(void) { platform_device_register(&omap2_mcspi1); platform_device_register(&omap2_mcspi2); -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) - platform_device_register(&omap2_mcspi3); -#endif -#ifdef CONFIG_ARCH_OMAP3 - platform_device_register(&omap2_mcspi4); -#endif } #else static inline void omap_init_mcspi(void) {} #endif -#ifdef CONFIG_SND_OMAP24XX_EAC - -#define OMAP2_EAC_BASE 0x48090000 - -static struct resource omap2_eac_resources[] = { - { - .start = OMAP2_EAC_BASE, - .end = OMAP2_EAC_BASE + 0x109, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_eac_device = { - .name = "omap24xx-eac", - .id = -1, - .num_resources = ARRAY_SIZE(omap2_eac_resources), - .resource = omap2_eac_resources, - .dev = { - .platform_data = NULL, - }, -}; - -void omap_init_eac(struct eac_platform_data *pdata) -{ - omap2_eac_device.dev.platform_data = pdata; - platform_device_register(&omap2_eac_device); -} - -#else -void omap_init_eac(struct eac_platform_data *pdata) {} -#endif - -#ifdef CONFIG_OMAP_SHA1_MD5 -static struct resource sha1_md5_resources[] = { - { - .start = OMAP24XX_SEC_SHA1MD5_BASE, - .end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_24XX_SHA1MD5, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device sha1_md5_device = { - .name = "OMAP SHA1/MD5", - .id = -1, - .num_resources = ARRAY_SIZE(sha1_md5_resources), - .resource = sha1_md5_resources, -}; - -static void omap_init_sha1_md5(void) -{ - platform_device_register(&sha1_md5_device); -} -#else -static inline void omap_init_sha1_md5(void) { } -#endif - -#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) -#define OMAP_HDQ_BASE 0x480B2000 -#endif -static struct resource omap_hdq_resources[] = { - { - .start = OMAP_HDQ_BASE, - .end = OMAP_HDQ_BASE + 0x1C, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_24XX_HDQ_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; -static struct platform_device omap_hdq_dev = { - .name = "omap_hdq", - .id = 0, - .dev = { - .platform_data = NULL, - }, - .num_resources = ARRAY_SIZE(omap_hdq_resources), - .resource = omap_hdq_resources, -}; -static inline void omap_hdq_init(void) -{ - (void) platform_device_register(&omap_hdq_dev); -} -#else -static inline void omap_hdq_init(void) {} -#endif - /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -334,11 +208,10 @@ static int __init omap2_init_devices(void) /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ + omap_init_i2c(); omap_init_mbox(); omap_init_mcspi(); - omap_hdq_init(); omap_init_sti(); - omap_init_sha1_md5(); return 0; } diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c index 763bdbeaf681..af1081a0b27c 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -9,8 +9,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#undef DEBUG - #include #include #include @@ -18,14 +16,20 @@ #include #include #include -#include #include #include -#include +#undef DEBUG + +#ifdef CONFIG_ARCH_OMAP2420 +#define GPMC_BASE 0x6800a000 +#endif + +#ifdef CONFIG_ARCH_OMAP2430 +#define GPMC_BASE 0x6E000000 +#endif -/* GPMC register offsets */ #define GPMC_REVISION 0x00 #define GPMC_SYSCONFIG 0x10 #define GPMC_SYSSTATUS 0x14 @@ -47,6 +51,7 @@ #define GPMC_CS0 0x60 #define GPMC_CS_SIZE 0x30 +#define GPMC_CS_NUM 8 #define GPMC_MEM_START 0x00000000 #define GPMC_MEM_END 0x3FFFFFFF #define BOOT_ROM_SPACE 0x100000 /* 1MB */ @@ -59,9 +64,12 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); static unsigned gpmc_cs_map; -static void __iomem *gpmc_base; +static void __iomem *gpmc_base = + (void __iomem *) IO_ADDRESS(GPMC_BASE); +static void __iomem *gpmc_cs_base = + (void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0; -static struct clk *gpmc_l3_clk; +static struct clk *gpmc_fck; static void gpmc_write_reg(int idx, u32 val) { @@ -77,32 +85,19 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; + reg_addr = gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx; __raw_writel(val, reg_addr); } u32 gpmc_cs_read_reg(int cs, int idx) { - void __iomem *reg_addr; - - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; - return __raw_readl(reg_addr); + return __raw_readl(gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx); } -/* TODO: Add support for gpmc_fck to clock framework and use it */ unsigned long gpmc_get_fclk_period(void) { - unsigned long rate = clk_get_rate(gpmc_l3_clk); - - if (rate == 0) { - printk(KERN_WARNING "gpmc_l3_clk not enabled\n"); - return 0; - } - - rate /= 1000; - rate = 1000000000 / rate; /* In picoseconds */ - - return rate; + /* In picoseconds */ + return 1000000000 / ((clk_get_rate(gpmc_fck)) / 1000); } unsigned int gpmc_ns_to_ticks(unsigned int time_ns) @@ -115,11 +110,6 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns) return (time_ns * 1000 + tick_ps - 1) / tick_ps; } -unsigned int gpmc_ticks_to_ns(unsigned int ticks) -{ - return ticks * gpmc_get_fclk_period() / 1000; -} - unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) { unsigned long ticks = gpmc_ns_to_ticks(time_ns); @@ -220,11 +210,6 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); - if (cpu_is_omap34xx()) { - GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); - GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); - } - /* caller is expected to have initialized CONFIG1 to cover * at least sync vs async */ @@ -365,7 +350,6 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) spin_unlock(&gpmc_mem_lock); return r; } -EXPORT_SYMBOL(gpmc_cs_request); void gpmc_cs_free(int cs) { @@ -381,9 +365,8 @@ void gpmc_cs_free(int cs) gpmc_cs_set_reserved(cs, 0); spin_unlock(&gpmc_mem_lock); } -EXPORT_SYMBOL(gpmc_cs_free); -static void __init gpmc_mem_init(void) +void __init gpmc_mem_init(void) { int cs; unsigned long boot_rom_space = 0; @@ -413,33 +396,12 @@ static void __init gpmc_mem_init(void) void __init gpmc_init(void) { u32 l; - char *ck; - - if (cpu_is_omap24xx()) { - ck = "core_l3_ck"; - if (cpu_is_omap2420()) - l = OMAP2420_GPMC_BASE; - else - l = OMAP34XX_GPMC_BASE; - } else if (cpu_is_omap34xx()) { - ck = "gpmc_fck"; - l = OMAP34XX_GPMC_BASE; - } - gpmc_l3_clk = clk_get(NULL, ck); - if (IS_ERR(gpmc_l3_clk)) { - printk(KERN_ERR "Could not get GPMC clock %s\n", ck); - return -ENODEV; - } - - gpmc_base = ioremap(l, SZ_4K); - if (!gpmc_base) { - clk_put(gpmc_l3_clk); - printk(KERN_ERR "Could not get GPMC register memory\n"); - return -ENOMEM; - } - - BUG_ON(IS_ERR(gpmc_l3_clk)); + gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ + if (IS_ERR(gpmc_fck)) + WARN_ON(1); + else + clk_enable(gpmc_fck); l = gpmc_read_reg(GPMC_REVISION); printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); diff --git a/trunk/arch/arm/mach-omap2/id.c b/trunk/arch/arm/mach-omap2/id.c index bf45ff39a7b5..209177c7f22f 100644 --- a/trunk/arch/arm/mach-omap2/id.c +++ b/trunk/arch/arm/mach-omap2/id.c @@ -18,15 +18,24 @@ #include -#include #include #include -static u32 class; -static void __iomem *tap_base; -static u16 tap_prod_id; +#if defined(CONFIG_ARCH_OMAP2420) +#define TAP_BASE io_p2v(0x48014000) +#elif defined(CONFIG_ARCH_OMAP2430) +#define TAP_BASE io_p2v(0x4900A000) +#elif defined(CONFIG_ARCH_OMAP34XX) +#define TAP_BASE io_p2v(0x4830A000) +#endif #define OMAP_TAP_IDCODE 0x0204 +#if defined(CONFIG_ARCH_OMAP34XX) +#define OMAP_TAP_PROD_ID 0x0210 +#else +#define OMAP_TAP_PROD_ID 0x0208 +#endif + #define OMAP_TAP_DIE_ID_0 0x0218 #define OMAP_TAP_DIE_ID_1 0x021C #define OMAP_TAP_DIE_ID_2 0x0220 @@ -85,24 +94,18 @@ static u32 __init read_tap_reg(int reg) * it means its Cortex r0p0 which is 3430 ES1 */ if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) { - - if (reg == tap_prod_id) { - regval = 0x000F00F0; - goto out; - } - switch (reg) { case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break; /* Making DevType as 0xF in ES1 to differ from ES2 */ + case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break; case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break; case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break; case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break; case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break; } } else - regval = __raw_readl(tap_base + reg); + regval = __raw_readl(TAP_BASE + reg); -out: return regval; } @@ -201,7 +204,7 @@ void __init omap2_check_revision(void) u8 rev; idcode = read_tap_reg(OMAP_TAP_IDCODE); - prod_id = read_tap_reg(tap_prod_id); + prod_id = read_tap_reg(OMAP_TAP_PROD_ID); hawkeye = (idcode >> 12) & 0xffff; rev = (idcode >> 28) & 0x0f; dev_type = (prod_id >> 16) & 0x0f; @@ -266,13 +269,3 @@ void __init omap2_check_revision(void) } -void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) -{ - class = omap2_globals->class; - tap_base = omap2_globals->tap; - - if (class == 0x3430) - tap_prod_id = 0x0210; - else - tap_prod_id = 0x0208; -} diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c index 5ea64f926ed5..7c3d6289c05f 100644 --- a/trunk/arch/arm/mach-omap2/io.c +++ b/trunk/arch/arm/mach-omap2/io.c @@ -4,11 +4,8 @@ * OMAP2 I/O mapping code * * Copyright (C) 2005 Nokia Corporation - * Copyright (C) 2007 Texas Instruments - * - * Author: - * Juha Yrjola - * Syed Khasim + * Author: Juha Yrjölä + * Updated map desc to add 2430 support : * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,26 +23,19 @@ #include #include -#include - -#include "memory.h" - -#include "clock.h" - -#include - -#include "powerdomains.h" -#include -#include "clockdomains.h" +extern void omap_sram_init(void); +extern int omap2_clk_init(void); +extern void omap2_check_revision(void); +extern void omap2_init_memory(void); +extern void gpmc_init(void); +extern void omapfb_reserve_sdram(void); /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. */ - -#ifdef CONFIG_ARCH_OMAP24XX -static struct map_desc omap24xx_io_desc[] __initdata = { +static struct map_desc omap2_io_desc[] __initdata = { { .virtual = L3_24XX_VIRT, .pfn = __phys_to_pfn(L3_24XX_PHYS), @@ -53,39 +43,12 @@ static struct map_desc omap24xx_io_desc[] __initdata = { .type = MT_DEVICE }, { - .virtual = L4_24XX_VIRT, - .pfn = __phys_to_pfn(L4_24XX_PHYS), - .length = L4_24XX_SIZE, - .type = MT_DEVICE + .virtual = L4_24XX_VIRT, + .pfn = __phys_to_pfn(L4_24XX_PHYS), + .length = L4_24XX_SIZE, + .type = MT_DEVICE }, -}; - -#ifdef CONFIG_ARCH_OMAP2420 -static struct map_desc omap242x_io_desc[] __initdata = { - { - .virtual = DSP_MEM_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), - .length = DSP_MEM_24XX_SIZE, - .type = MT_DEVICE - }, - { - .virtual = DSP_IPI_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), - .length = DSP_IPI_24XX_SIZE, - .type = MT_DEVICE - }, - { - .virtual = DSP_MMU_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), - .length = DSP_MMU_24XX_SIZE, - .type = MT_DEVICE - }, -}; - -#endif - #ifdef CONFIG_ARCH_OMAP2430 -static struct map_desc omap243x_io_desc[] __initdata = { { .virtual = L4_WK_243X_VIRT, .pfn = __phys_to_pfn(L4_WK_243X_PHYS), @@ -98,90 +61,30 @@ static struct map_desc omap243x_io_desc[] __initdata = { .length = OMAP243X_GPMC_SIZE, .type = MT_DEVICE }, - { - .virtual = OMAP243X_SDRC_VIRT, - .pfn = __phys_to_pfn(OMAP243X_SDRC_PHYS), - .length = OMAP243X_SDRC_SIZE, - .type = MT_DEVICE - }, - { - .virtual = OMAP243X_SMS_VIRT, - .pfn = __phys_to_pfn(OMAP243X_SMS_PHYS), - .length = OMAP243X_SMS_SIZE, - .type = MT_DEVICE - }, -}; -#endif #endif - -#ifdef CONFIG_ARCH_OMAP34XX -static struct map_desc omap34xx_io_desc[] __initdata = { - { - .virtual = L3_34XX_VIRT, - .pfn = __phys_to_pfn(L3_34XX_PHYS), - .length = L3_34XX_SIZE, - .type = MT_DEVICE - }, { - .virtual = L4_34XX_VIRT, - .pfn = __phys_to_pfn(L4_34XX_PHYS), - .length = L4_34XX_SIZE, - .type = MT_DEVICE - }, - { - .virtual = L4_WK_34XX_VIRT, - .pfn = __phys_to_pfn(L4_WK_34XX_PHYS), - .length = L4_WK_34XX_SIZE, - .type = MT_DEVICE - }, - { - .virtual = OMAP34XX_GPMC_VIRT, - .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS), - .length = OMAP34XX_GPMC_SIZE, - .type = MT_DEVICE - }, - { - .virtual = OMAP343X_SMS_VIRT, - .pfn = __phys_to_pfn(OMAP343X_SMS_PHYS), - .length = OMAP343X_SMS_SIZE, - .type = MT_DEVICE - }, - { - .virtual = OMAP343X_SDRC_VIRT, - .pfn = __phys_to_pfn(OMAP343X_SDRC_PHYS), - .length = OMAP343X_SDRC_SIZE, + .virtual = DSP_MEM_24XX_VIRT, + .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), + .length = DSP_MEM_24XX_SIZE, .type = MT_DEVICE }, { - .virtual = L4_PER_34XX_VIRT, - .pfn = __phys_to_pfn(L4_PER_34XX_PHYS), - .length = L4_PER_34XX_SIZE, + .virtual = DSP_IPI_24XX_VIRT, + .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), + .length = DSP_IPI_24XX_SIZE, .type = MT_DEVICE }, { - .virtual = L4_EMU_34XX_VIRT, - .pfn = __phys_to_pfn(L4_EMU_34XX_PHYS), - .length = L4_EMU_34XX_SIZE, + .virtual = DSP_MMU_24XX_VIRT, + .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), + .length = DSP_MMU_24XX_SIZE, .type = MT_DEVICE - }, + } }; -#endif void __init omap2_map_common_io(void) { -#if defined(CONFIG_ARCH_OMAP2420) - iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); - iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); -#endif - -#if defined(CONFIG_ARCH_OMAP2430) - iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); - iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); -#endif - -#if defined(CONFIG_ARCH_OMAP34XX) - iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); -#endif + iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); /* Normally devicemaps_init() would flush caches and tlb after * mdesc->map_io(), but we must also do it here because of the CPU @@ -198,9 +101,12 @@ void __init omap2_map_common_io(void) void __init omap2_init_common_hw(void) { omap2_mux_init(); - pwrdm_init(powerdomains_omap); - clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); omap2_clk_init(); +/* + * Need to Fix this for 2430 + */ +#ifndef CONFIG_ARCH_OMAP2430 omap2_init_memory(); +#endif gpmc_init(); } diff --git a/trunk/arch/arm/mach-omap2/irq.c b/trunk/arch/arm/mach-omap2/irq.c index d354e0fe4477..196a9565a8dc 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -16,20 +16,14 @@ #include #include #include +#include - -/* selected INTC register offsets */ - -#define INTC_REVISION 0x0000 -#define INTC_SYSCONFIG 0x0010 -#define INTC_SYSSTATUS 0x0014 -#define INTC_CONTROL 0x0048 -#define INTC_MIR_CLEAR0 0x0088 -#define INTC_MIR_SET0 0x008c -#define INTC_PENDING_IRQ0 0x0098 - -/* Number of IRQ state bits in each MIR register */ -#define IRQ_BITS_PER_REG 32 +#define INTC_REVISION 0x0000 +#define INTC_SYSCONFIG 0x0010 +#define INTC_SYSSTATUS 0x0014 +#define INTC_CONTROL 0x0048 +#define INTC_MIR_CLEAR0 0x0088 +#define INTC_MIR_SET0 0x008c /* * OMAP2 has a number of different interrupt controllers, each interrupt @@ -38,50 +32,48 @@ * for each bank.. when in doubt, consult the TRM. */ static struct omap_irq_bank { - void __iomem *base_reg; + unsigned long base_reg; unsigned int nr_irqs; } __attribute__ ((aligned(4))) irq_banks[] = { { /* MPU INTC */ - .base_reg = 0, + .base_reg = IO_ADDRESS(OMAP24XX_IC_BASE), .nr_irqs = 96, - }, + }, { + /* XXX: DSP INTC */ + } }; -/* INTC bank register get/set */ - -static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) -{ - __raw_writel(val, bank->base_reg + reg); -} - -static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) -{ - return __raw_readl(bank->base_reg + reg); -} - /* XXX: FIQ and additional INTC support (only MPU at the moment) */ static void omap_ack_irq(unsigned int irq) { - intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL); + __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL); } static void omap_mask_irq(unsigned int irq) { - int offset = irq & (~(IRQ_BITS_PER_REG - 1)); + int offset = (irq >> 5) << 5; - irq &= (IRQ_BITS_PER_REG - 1); + if (irq >= 64) { + irq %= 64; + } else if (irq >= 32) { + irq %= 32; + } - intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset); + __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset); } static void omap_unmask_irq(unsigned int irq) { - int offset = irq & (~(IRQ_BITS_PER_REG - 1)); + int offset = (irq >> 5) << 5; - irq &= (IRQ_BITS_PER_REG - 1); + if (irq >= 64) { + irq %= 64; + } else if (irq >= 32) { + irq %= 32; + } - intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset); + __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset); } static void omap_mask_ack_irq(unsigned int irq) @@ -101,20 +93,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) { unsigned long tmp; - tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff; - printk(KERN_INFO "IRQ: Found an INTC at 0x%p " + tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff; + printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx " "(revision %ld.%ld) with %d interrupts\n", bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); - tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG); + tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG); tmp |= 1 << 1; /* soft reset */ - intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG); + __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG); - while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1)) + while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1)) /* Wait for reset to complete */; /* Enable autoidle */ - intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG); + __raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG); } void __init omap_init_irq(void) @@ -126,10 +118,9 @@ void __init omap_init_irq(void) for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { struct omap_irq_bank *bank = irq_banks + i; - if (cpu_is_omap24xx()) - bank->base_reg = OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE); - else if (cpu_is_omap34xx()) - bank->base_reg = OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE); + /* XXX */ + if (!bank->base_reg) + continue; omap_irq_bank_init_one(bank); diff --git a/trunk/arch/arm/mach-omap2/mcbsp.c b/trunk/arch/arm/mach-omap2/mcbsp.c index cae3ebe249b3..b261f1f80b5e 100644 --- a/trunk/arch/arm/mach-omap2/mcbsp.c +++ b/trunk/arch/arm/mach-omap2/mcbsp.c @@ -89,30 +89,6 @@ static struct mcbsp_internal_clk omap_mcbsp_clks[] = { .disable = omap_mcbsp_clk_disable, }, }, - { - .clk = { - .name = "mcbsp_clk", - .id = 3, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, - { - .clk = { - .name = "mcbsp_clk", - .id = 4, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, - { - .clk = { - .name = "mcbsp_clk", - .id = 5, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, }; #define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) @@ -141,14 +117,25 @@ static void omap2_mcbsp_request(unsigned int id) omap2_mcbsp2_mux_setup(); } +static int omap2_mcbsp_check(unsigned int id) +{ + if (id > OMAP_MAX_MCBSP_COUNT - 1) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); + return -ENODEV; + } + return 0; +} + static struct omap_mcbsp_ops omap2_mcbsp_ops = { .request = omap2_mcbsp_request, + .check = omap2_mcbsp_check, }; -#ifdef CONFIG_ARCH_OMAP2420 -static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { +#ifdef CONFIG_ARCH_OMAP24XX +static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = { { .phys_base = OMAP24XX_MCBSP1_BASE, + .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, .rx_irq = INT_24XX_MCBSP1_IRQ_RX, @@ -158,6 +145,7 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { }, { .phys_base = OMAP24XX_MCBSP2_BASE, + .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, .rx_irq = INT_24XX_MCBSP2_IRQ_RX, @@ -166,70 +154,17 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { .clk_name = "mcbsp_clk", }, }; -#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) +#define OMAP24XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap24xx_mcbsp_pdata) #else -#define omap2420_mcbsp_pdata NULL -#define OMAP2420_MCBSP_PDATA_SZ 0 -#endif - -#ifdef CONFIG_ARCH_OMAP2430 -static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { - { - .phys_base = OMAP24XX_MCBSP1_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .phys_base = OMAP24XX_MCBSP2_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .phys_base = OMAP2430_MCBSP3_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, - .rx_irq = INT_24XX_MCBSP3_IRQ_RX, - .tx_irq = INT_24XX_MCBSP3_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .phys_base = OMAP2430_MCBSP4_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, - .rx_irq = INT_24XX_MCBSP4_IRQ_RX, - .tx_irq = INT_24XX_MCBSP4_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .phys_base = OMAP2430_MCBSP5_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, - .rx_irq = INT_24XX_MCBSP5_IRQ_RX, - .tx_irq = INT_24XX_MCBSP5_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, -}; -#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) -#else -#define omap2430_mcbsp_pdata NULL -#define OMAP2430_MCBSP_PDATA_SZ 0 +#define omap24xx_mcbsp_pdata NULL +#define OMAP24XX_MCBSP_PDATA_SZ 0 #endif #ifdef CONFIG_ARCH_OMAP34XX static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { { .phys_base = OMAP34XX_MCBSP1_BASE, + .virt_base = IO_ADDRESS(OMAP34XX_MCBSP1_BASE), .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, .rx_irq = INT_24XX_MCBSP1_IRQ_RX, @@ -239,6 +174,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { }, { .phys_base = OMAP34XX_MCBSP2_BASE, + .virt_base = IO_ADDRESS(OMAP34XX_MCBSP2_BASE), .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, .rx_irq = INT_24XX_MCBSP2_IRQ_RX, @@ -246,33 +182,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .ops = &omap2_mcbsp_ops, .clk_name = "mcbsp_clk", }, - { - .phys_base = OMAP34XX_MCBSP3_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, - .rx_irq = INT_24XX_MCBSP3_IRQ_RX, - .tx_irq = INT_24XX_MCBSP3_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .phys_base = OMAP34XX_MCBSP4_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, - .rx_irq = INT_24XX_MCBSP4_IRQ_RX, - .tx_irq = INT_24XX_MCBSP4_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .phys_base = OMAP34XX_MCBSP5_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, - .rx_irq = INT_24XX_MCBSP5_IRQ_RX, - .tx_irq = INT_24XX_MCBSP5_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, }; #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) #else @@ -280,7 +189,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { #define OMAP34XX_MCBSP_PDATA_SZ 0 #endif -static int __init omap2_mcbsp_init(void) +int __init omap2_mcbsp_init(void) { int i; @@ -290,24 +199,10 @@ static int __init omap2_mcbsp_init(void) clk_register(&omap_mcbsp_clks[i].clk); } - if (cpu_is_omap2420()) - omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; - if (cpu_is_omap2430()) - omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; - if (cpu_is_omap34xx()) - omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; - - mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), - GFP_KERNEL); - if (!mcbsp_ptr) - return -ENOMEM; + if (cpu_is_omap24xx()) + omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata, + OMAP24XX_MCBSP_PDATA_SZ); - if (cpu_is_omap2420()) - omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, - OMAP2420_MCBSP_PDATA_SZ); - if (cpu_is_omap2430()) - omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, - OMAP2430_MCBSP_PDATA_SZ); if (cpu_is_omap34xx()) omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, OMAP34XX_MCBSP_PDATA_SZ); diff --git a/trunk/arch/arm/mach-omap2/memory.c b/trunk/arch/arm/mach-omap2/memory.c index 882c70224292..ab1462b02e6e 100644 --- a/trunk/arch/arm/mach-omap2/memory.c +++ b/trunk/arch/arm/mach-omap2/memory.c @@ -101,17 +101,6 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force) return prev; } -#if !defined(CONFIG_ARCH_OMAP2) -void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, - u32 base_cs, u32 force_unlock) -{ -} -void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, - u32 mem_type) -{ -} -#endif - void omap2_init_memory_params(u32 force_lock_to_unlock_mode) { unsigned long dll_cnt; @@ -176,9 +165,6 @@ void __init omap2_init_memory(void) { u32 l; - if (!cpu_is_omap2420()) - return; - l = sms_read_reg(SMS_SYSCONFIG); l &= ~(0x3 << 3); l |= (0x2 << 3); diff --git a/trunk/arch/arm/mach-omap2/memory.h b/trunk/arch/arm/mach-omap2/memory.h index bb3db80a7c46..9a280b50a893 100644 --- a/trunk/arch/arm/mach-omap2/memory.h +++ b/trunk/arch/arm/mach-omap2/memory.h @@ -14,9 +14,6 @@ * published by the Free Software Foundation. */ -#ifndef ARCH_ARM_MACH_OMAP2_MEMORY_H -#define ARCH_ARM_MACH_OMAP2_MEMORY_H - /* Memory timings */ #define M_DDR 1 #define M_LOCK_CTRL (1 << 2) @@ -37,7 +34,3 @@ extern u32 omap2_memory_get_fast_dll_ctrl(void); extern u32 omap2_memory_get_type(void); u32 omap2_dll_force_needed(void); u32 omap2_reprogram_sdrc(u32 level, u32 force); -void __init omap2_init_memory(void); -void __init gpmc_init(void); - -#endif diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index b1393673d95d..6b7d672058b9 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-omap2/mux.c * - * OMAP2 and OMAP3 pin multiplexing configurations + * OMAP2 pin multiplexing configurations * * Copyright (C) 2004 - 2008 Texas Instruments Inc. * Copyright (C) 2003 - 2008 Nokia Corporation @@ -220,222 +220,16 @@ MUX_CFG_24XX("AD13_2430_MCBSP2_DR_OFF", 0x0131, 0, 0, 0, 1) #define OMAP24XX_PINS_SZ 0 #endif /* CONFIG_ARCH_OMAP24XX */ -#ifdef CONFIG_ARCH_OMAP34XX -static struct pin_config __initdata_or_module omap34xx_pins[] = { -/* - * Name, reg-offset, - * mux-mode | [active-mode | off-mode] - */ - -/* 34xx I2C */ -MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) - -/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/ -MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/ -MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB11_3430_USB2HS_PHY_NXT", 0x5f6, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB10_3430_USB2HS_PHY_D0", 0x5f8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB9_3430_USB2HS_PHY_D1", 0x5fa, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W3_3430_USB2HS_PHY_D2", 0x1d4, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T4_3430_USB2HS_PHY_D3", 0x1de, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T3_3430_USB2HS_PHY_D4", 0x1d8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R3_3430_USB2HS_PHY_D5", 0x1da, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R4_3430_USB2HS_PHY_D6", 0x1dc, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T2_3430_USB2HS_PHY_D7", 0x1d6, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* TLL - HSUSB: 12-pin TLL Port 1*/ -MUX_CFG_34XX("Y8_3430_USB1HS_TLL_CLK", 0x5da, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y9_3430_USB1HS_TLL_STP", 0x5d8, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AA14_3430_USB1HS_TLL_DIR", 0x5ec, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA11_3430_USB1HS_TLL_NXT", 0x5ee, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W13_3430_USB1HS_TLL_D0", 0x5dc, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W12_3430_USB1HS_TLL_D1", 0x5de, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W11_3430_USB1HS_TLL_D2", 0x5e0, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y11_3430_USB1HS_TLL_D3", 0x5ea, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W9_3430_USB1HS_TLL_D4", 0x5e4, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y12_3430_USB1HS_TLL_D5", 0x5e6, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W8_3430_USB1HS_TLL_D6", 0x5e8, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y13_3430_USB1HS_TLL_D7", 0x5e2, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* TLL - HSUSB: 12-pin TLL Port 2*/ -MUX_CFG_34XX("AA8_3430_USB2HS_TLL_CLK", 0x5f0, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA10_3430_USB2HS_TLL_STP", 0x5f2, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AA9_3430_USB2HS_TLL_DIR", 0x5f4, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB11_3430_USB2HS_TLL_NXT", 0x5f6, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB10_3430_USB2HS_TLL_D0", 0x5f8, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB9_3430_USB2HS_TLL_D1", 0x5fa, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W3_3430_USB2HS_TLL_D2", 0x1d4, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T4_3430_USB2HS_TLL_D3", 0x1de, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T3_3430_USB2HS_TLL_D4", 0x1d8, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R3_3430_USB2HS_TLL_D5", 0x1da, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R4_3430_USB2HS_TLL_D6", 0x1dc, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T2_3430_USB2HS_TLL_D7", 0x1d6, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* TLL - HSUSB: 12-pin TLL Port 3*/ -MUX_CFG_34XX("AA6_3430_USB3HS_TLL_CLK", 0x180, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB3_3430_USB3HS_TLL_STP", 0x166, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AA3_3430_USB3HS_TLL_DIR", 0x168, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y3_3430_USB3HS_TLL_NXT", 0x16a, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA5_3430_USB3HS_TLL_D0", 0x186, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y4_3430_USB3HS_TLL_D1", 0x184, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y5_3430_USB3HS_TLL_D2", 0x188, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W5_3430_USB3HS_TLL_D3", 0x18a, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB12_3430_USB3HS_TLL_D4", 0x16c, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB13_3430_USB3HS_TLL_D5", 0x16e, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA13_3430_USB3HS_TLL_D6", 0x170, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA12_3430_USB3HS_TLL_D7", 0x172, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */ -MUX_CFG_34XX("AF10_3430_USB1FS_PHY_MM1_RXDP", 0x5d8, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AG9_3430_USB1FS_PHY_MM1_RXDM", 0x5ee, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W13_3430_USB1FS_PHY_MM1_RXRCV", 0x5dc, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W12_3430_USB1FS_PHY_MM1_TXSE0", 0x5de, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W11_3430_USB1FS_PHY_MM1_TXDAT", 0x5e0, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y11_3430_USB1FS_PHY_MM1_TXEN_N", 0x5ea, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT) - -/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */ -MUX_CFG_34XX("AF7_3430_USB2FS_PHY_MM2_RXDP", 0x5f2, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AH7_3430_USB2FS_PHY_MM2_RXDM", 0x5f6, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB10_3430_USB2FS_PHY_MM2_RXRCV", 0x5f8, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB9_3430_USB2FS_PHY_MM2_TXSE0", 0x5fa, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W3_3430_USB2FS_PHY_MM2_TXDAT", 0x1d4, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T4_3430_USB2FS_PHY_MM2_TXEN_N", 0x1de, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT) - -/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */ -MUX_CFG_34XX("AH3_3430_USB3FS_PHY_MM3_RXDP", 0x166, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AE3_3430_USB3FS_PHY_MM3_RXDM", 0x16a, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AD1_3430_USB3FS_PHY_MM3_RXRCV", 0x186, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AE1_3430_USB3FS_PHY_MM3_TXSE0", 0x184, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AD2_3430_USB3FS_PHY_MM3_TXDAT", 0x188, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_OUTPUT) - -}; - -#define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) - -#else -#define omap34xx_pins NULL -#define OMAP34XX_PINS_SZ 0 -#endif /* CONFIG_ARCH_OMAP34XX */ +#define OMAP24XX_PULL_ENA (1 << 3) +#define OMAP24XX_PULL_UP (1 << 4) #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) -static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) +void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg) { u16 orig; u8 warn = 0, debug = 0; - if (cpu_is_omap24xx()) - orig = omap_ctrl_readb(cfg->mux_reg); - else - orig = omap_ctrl_readw(cfg->mux_reg); + orig = omap_ctrl_readb(cfg->mux_reg); #ifdef CONFIG_OMAP_MUX_DEBUG debug = cfg->debug; @@ -461,9 +255,9 @@ int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) spin_lock_irqsave(&mux_spin_lock, flags); reg |= cfg->mask & 0x7; if (cfg->pull_val) - reg |= OMAP2_PULL_ENA; + reg |= OMAP24XX_PULL_ENA; if (cfg->pu_pd_val) - reg |= OMAP2_PULL_UP; + reg |= OMAP24XX_PULL_UP; omap2_cfg_debug(cfg, reg); omap_ctrl_writeb(reg, cfg->mux_reg); spin_unlock_irqrestore(&mux_spin_lock, flags); @@ -471,26 +265,7 @@ int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) return 0; } #else -#define omap24xx_cfg_reg NULL -#endif - -#ifdef CONFIG_ARCH_OMAP34XX -static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg) -{ - static DEFINE_SPINLOCK(mux_spin_lock); - unsigned long flags; - u16 reg = 0; - - spin_lock_irqsave(&mux_spin_lock, flags); - reg |= cfg->mux_val; - omap2_cfg_debug(cfg, reg); - omap_ctrl_writew(reg, cfg->mux_reg); - spin_unlock_irqrestore(&mux_spin_lock, flags); - - return 0; -} -#else -#define omap34xx_cfg_reg NULL +#define omap24xx_cfg_reg 0 #endif int __init omap2_mux_init(void) @@ -499,10 +274,6 @@ int __init omap2_mux_init(void) arch_mux_cfg.pins = omap24xx_pins; arch_mux_cfg.size = OMAP24XX_PINS_SZ; arch_mux_cfg.cfg_reg = omap24xx_cfg_reg; - } else if (cpu_is_omap34xx()) { - arch_mux_cfg.pins = omap34xx_pins; - arch_mux_cfg.size = OMAP34XX_PINS_SZ; - arch_mux_cfg.cfg_reg = omap34xx_cfg_reg; } return omap_mux_register(&arch_mux_cfg); diff --git a/trunk/arch/arm/mach-omap2/powerdomain.c b/trunk/arch/arm/mach-omap2/powerdomain.c deleted file mode 100644 index 73e2971b1757..000000000000 --- a/trunk/arch/arm/mach-omap2/powerdomain.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* - * OMAP powerdomain control - * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation - * - * Written by Paul Walmsley - * - * 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. - */ -#ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN -# define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "cm.h" -#include "cm-regbits-34xx.h" -#include "prm.h" -#include "prm-regbits-34xx.h" - -#include -#include -#include - -/* pwrdm_list contains all registered struct powerdomains */ -static LIST_HEAD(pwrdm_list); - -/* - * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to - * protect pwrdm_clkdms[] during clkdm add/del ops - */ -static DEFINE_RWLOCK(pwrdm_rwlock); - - -/* Private functions */ - -static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) -{ - u32 v; - - v = prm_read_mod_reg(domain, idx); - v &= mask; - v >>= __ffs(mask); - - return v; -} - -static struct powerdomain *_pwrdm_lookup(const char *name) -{ - struct powerdomain *pwrdm, *temp_pwrdm; - - pwrdm = NULL; - - list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { - if (!strcmp(name, temp_pwrdm->name)) { - pwrdm = temp_pwrdm; - break; - } - } - - return pwrdm; -} - -/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */ -static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, - struct pwrdm_dep *deps) -{ - struct pwrdm_dep *pd; - - if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip)) - return ERR_PTR(-EINVAL); - - for (pd = deps; pd; pd++) { - - if (!omap_chip_is(pd->omap_chip)) - continue; - - if (!pd->pwrdm && pd->pwrdm_name) - pd->pwrdm = pwrdm_lookup(pd->pwrdm_name); - - if (pd->pwrdm == pwrdm) - break; - - } - - if (!pd) - return ERR_PTR(-ENOENT); - - return pd->pwrdm; -} - - -/* Public functions */ - -/** - * pwrdm_init - set up the powerdomain layer - * - * Loop through the list of powerdomains, registering all that are - * available on the current CPU. If pwrdm_list is supplied and not - * null, all of the referenced powerdomains will be registered. No - * return value. - */ -void pwrdm_init(struct powerdomain **pwrdm_list) -{ - struct powerdomain **p = NULL; - - if (pwrdm_list) - for (p = pwrdm_list; *p; p++) - pwrdm_register(*p); -} - -/** - * pwrdm_register - register a powerdomain - * @pwrdm: struct powerdomain * to register - * - * Adds a powerdomain to the internal powerdomain list. Returns - * -EINVAL if given a null pointer, -EEXIST if a powerdomain is - * already registered by the provided name, or 0 upon success. - */ -int pwrdm_register(struct powerdomain *pwrdm) -{ - unsigned long flags; - int ret = -EINVAL; - - if (!pwrdm) - return -EINVAL; - - if (!omap_chip_is(pwrdm->omap_chip)) - return -EINVAL; - - write_lock_irqsave(&pwrdm_rwlock, flags); - if (_pwrdm_lookup(pwrdm->name)) { - ret = -EEXIST; - goto pr_unlock; - } - - list_add(&pwrdm->node, &pwrdm_list); - - pr_debug("powerdomain: registered %s\n", pwrdm->name); - ret = 0; - -pr_unlock: - write_unlock_irqrestore(&pwrdm_rwlock, flags); - - return ret; -} - -/** - * pwrdm_unregister - unregister a powerdomain - * @pwrdm: struct powerdomain * to unregister - * - * Removes a powerdomain from the internal powerdomain list. Returns - * -EINVAL if pwrdm argument is NULL. - */ -int pwrdm_unregister(struct powerdomain *pwrdm) -{ - unsigned long flags; - - if (!pwrdm) - return -EINVAL; - - write_lock_irqsave(&pwrdm_rwlock, flags); - list_del(&pwrdm->node); - write_unlock_irqrestore(&pwrdm_rwlock, flags); - - pr_debug("powerdomain: unregistered %s\n", pwrdm->name); - - return 0; -} - -/** - * pwrdm_lookup - look up a powerdomain by name, return a pointer - * @name: name of powerdomain - * - * Find a registered powerdomain by its name. Returns a pointer to the - * struct powerdomain if found, or NULL otherwise. - */ -struct powerdomain *pwrdm_lookup(const char *name) -{ - struct powerdomain *pwrdm; - unsigned long flags; - - if (!name) - return NULL; - - read_lock_irqsave(&pwrdm_rwlock, flags); - pwrdm = _pwrdm_lookup(name); - read_unlock_irqrestore(&pwrdm_rwlock, flags); - - return pwrdm; -} - -/** - * pwrdm_for_each - call function on each registered clockdomain - * @fn: callback function * - * - * Call the supplied function for each registered powerdomain. The - * callback function can return anything but 0 to bail out early from - * the iterator. The callback function is called with the pwrdm_rwlock - * held for reading, so no powerdomain structure manipulation - * functions should be called from the callback, although hardware - * powerdomain control functions are fine. Returns the last return - * value of the callback function, which should be 0 for success or - * anything else to indicate failure; or -EINVAL if the function - * pointer is null. - */ -int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)) -{ - struct powerdomain *temp_pwrdm; - unsigned long flags; - int ret = 0; - - if (!fn) - return -EINVAL; - - read_lock_irqsave(&pwrdm_rwlock, flags); - list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { - ret = (*fn)(temp_pwrdm); - if (ret) - break; - } - read_unlock_irqrestore(&pwrdm_rwlock, flags); - - return ret; -} - -/** - * pwrdm_add_clkdm - add a clockdomain to a powerdomain - * @pwrdm: struct powerdomain * to add the clockdomain to - * @clkdm: struct clockdomain * to associate with a powerdomain - * - * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This - * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if - * presented with invalid pointers; -ENOMEM if memory could not be allocated; - * or 0 upon success. - */ -int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) -{ - unsigned long flags; - int i; - int ret = -EINVAL; - - if (!pwrdm || !clkdm) - return -EINVAL; - - pr_debug("powerdomain: associating clockdomain %s with powerdomain " - "%s\n", clkdm->name, pwrdm->name); - - write_lock_irqsave(&pwrdm_rwlock, flags); - - for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { - if (!pwrdm->pwrdm_clkdms[i]) - break; -#ifdef DEBUG - if (pwrdm->pwrdm_clkdms[i] == clkdm) { - ret = -EINVAL; - goto pac_exit; - } -#endif - } - - if (i == PWRDM_MAX_CLKDMS) { - pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for " - "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name); - WARN_ON(1); - ret = -ENOMEM; - goto pac_exit; - } - - pwrdm->pwrdm_clkdms[i] = clkdm; - - ret = 0; - -pac_exit: - write_unlock_irqrestore(&pwrdm_rwlock, flags); - - return ret; -} - -/** - * pwrdm_del_clkdm - remove a clockdomain from a powerdomain - * @pwrdm: struct powerdomain * to add the clockdomain to - * @clkdm: struct clockdomain * to associate with a powerdomain - * - * Dissociate the clockdomain 'clkdm' from the powerdomain - * 'pwrdm'. Returns -EINVAL if presented with invalid pointers; - * -ENOENT if the clkdm was not associated with the powerdomain, or 0 - * upon success. - */ -int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) -{ - unsigned long flags; - int ret = -EINVAL; - int i; - - if (!pwrdm || !clkdm) - return -EINVAL; - - pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " - "%s\n", clkdm->name, pwrdm->name); - - write_lock_irqsave(&pwrdm_rwlock, flags); - - for (i = 0; i < PWRDM_MAX_CLKDMS; i++) - if (pwrdm->pwrdm_clkdms[i] == clkdm) - break; - - if (i == PWRDM_MAX_CLKDMS) { - pr_debug("powerdomain: clkdm %s not associated with pwrdm " - "%s ?!\n", clkdm->name, pwrdm->name); - ret = -ENOENT; - goto pdc_exit; - } - - pwrdm->pwrdm_clkdms[i] = NULL; - - ret = 0; - -pdc_exit: - write_unlock_irqrestore(&pwrdm_rwlock, flags); - - return ret; -} - -/** - * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm - * @pwrdm: struct powerdomain * to iterate over - * @fn: callback function * - * - * Call the supplied function for each clockdomain in the powerdomain - * 'pwrdm'. The callback function can return anything but 0 to bail - * out early from the iterator. The callback function is called with - * the pwrdm_rwlock held for reading, so no powerdomain structure - * manipulation functions should be called from the callback, although - * hardware powerdomain control functions are fine. Returns -EINVAL - * if presented with invalid pointers; or passes along the last return - * value of the callback function, which should be 0 for success or - * anything else to indicate failure. - */ -int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, - int (*fn)(struct powerdomain *pwrdm, - struct clockdomain *clkdm)) -{ - unsigned long flags; - int ret = 0; - int i; - - if (!fn) - return -EINVAL; - - read_lock_irqsave(&pwrdm_rwlock, flags); - - for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) - ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); - - read_unlock_irqrestore(&pwrdm_rwlock, flags); - - return ret; -} - - -/** - * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1 - * @pwrdm1: wake this struct powerdomain * up (dependent) - * @pwrdm2: when this struct powerdomain * wakes up (source) - * - * When the powerdomain represented by pwrdm2 wakes up (due to an - * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP, - * this feature is designed to reduce wakeup latency of the dependent - * powerdomain. Returns -EINVAL if presented with invalid powerdomain - * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or - * 0 upon success. - */ -int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear wake up of " - "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n", - pwrdm1->name, pwrdm2->name); - - prm_set_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, PM_WKDEP); - - return 0; -} - -/** - * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1 - * @pwrdm1: wake this struct powerdomain * up (dependent) - * @pwrdm2: when this struct powerdomain * wakes up (source) - * - * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2 - * wakes up. Returns -EINVAL if presented with invalid powerdomain - * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or - * 0 upon success. - */ -int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear wake up of " - "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: hardware will no longer wake up %s after %s " - "wakes up\n", pwrdm1->name, pwrdm2->name); - - prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, PM_WKDEP); - - return 0; -} - -/** - * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1 - * @pwrdm1: wake this struct powerdomain * up (dependent) - * @pwrdm2: when this struct powerdomain * wakes up (source) - * - * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be - * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL - * if either powerdomain pointer is invalid; or -ENOENT if the hardware - * is incapable. - * - * REVISIT: Currently this function only represents software-controllable - * wakeup dependencies. Wakeup dependencies fixed in hardware are not - * yet handled here. - */ -int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear wake up of " - "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); - return IS_ERR(p); - } - - return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP, - (1 << pwrdm2->dep_bit)); -} - -/** - * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1 - * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) - * @pwrdm2: when this struct powerdomain * is active (source) - * - * Prevent pwrdm1 from automatically going inactive (and then to - * retention or off) if pwrdm2 is still active. Returns -EINVAL if - * presented with invalid powerdomain pointers or called on a machine - * that does not support software-configurable hardware sleep dependencies, - * -ENOENT if the specified dependency cannot be set in hardware, or - * 0 upon success. - */ -int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - if (!cpu_is_omap34xx()) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear sleep " - "dependency affecting %s from %s\n", pwrdm1->name, - pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n", - pwrdm1->name, pwrdm2->name); - - cm_set_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP); - - return 0; -} - -/** - * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1 - * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) - * @pwrdm2: when this struct powerdomain * is active (source) - * - * Allow pwrdm1 to automatically go inactive (and then to retention or - * off), independent of the activity state of pwrdm2. Returns -EINVAL - * if presented with invalid powerdomain pointers or called on a machine - * that does not support software-configurable hardware sleep dependencies, - * -ENOENT if the specified dependency cannot be cleared in hardware, or - * 0 upon success. - */ -int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - if (!cpu_is_omap34xx()) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear sleep " - "dependency affecting %s from %s\n", pwrdm1->name, - pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: will no longer prevent %s from sleeping if " - "%s is active\n", pwrdm1->name, pwrdm2->name); - - cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP); - - return 0; -} - -/** - * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1 - * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) - * @pwrdm2: when this struct powerdomain * is active (source) - * - * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will - * not be allowed to automatically go inactive if pwrdm2 is active; - * 0 if pwrdm1's automatic power state inactivity transition is independent - * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called - * on a machine that does not support software-configurable hardware sleep - * dependencies; or -ENOENT if the hardware is incapable. - * - * REVISIT: Currently this function only represents software-controllable - * sleep dependencies. Sleep dependencies fixed in hardware are not - * yet handled here. - */ -int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - if (!cpu_is_omap34xx()) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear sleep " - "dependency affecting %s from %s\n", pwrdm1->name, - pwrdm2->name); - return IS_ERR(p); - } - - return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP, - (1 << pwrdm2->dep_bit)); -} - -/** - * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain - * @pwrdm: struct powerdomain * - * - * Return the number of controllable memory banks in powerdomain pwrdm, - * starting with 1. Returns -EINVAL if the powerdomain pointer is null. - */ -int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - return pwrdm->banks; -} - -/** - * pwrdm_set_next_pwrst - set next powerdomain power state - * @pwrdm: struct powerdomain * to set - * @pwrst: one of the PWRDM_POWER_* macros - * - * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain - * may not enter this state immediately if the preconditions for this state - * have not been satisfied. Returns -EINVAL if the powerdomain pointer is - * null or if the power state is invalid for the powerdomin, or returns 0 - * upon success. - */ -int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) -{ - if (!pwrdm) - return -EINVAL; - - if (!(pwrdm->pwrsts & (1 << pwrst))) - return -EINVAL; - - pr_debug("powerdomain: setting next powerstate for %s to %0x\n", - pwrdm->name, pwrst); - - prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, - (pwrst << OMAP_POWERSTATE_SHIFT), - pwrdm->prcm_offs, PM_PWSTCTRL); - - return 0; -} - -/** - * pwrdm_read_next_pwrst - get next powerdomain power state - * @pwrdm: struct powerdomain * to get power state - * - * Return the powerdomain pwrdm's next power state. Returns -EINVAL - * if the powerdomain pointer is null or returns the next power state - * upon success. - */ -int pwrdm_read_next_pwrst(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL, - OMAP_POWERSTATE_MASK); -} - -/** - * pwrdm_read_pwrst - get current powerdomain power state - * @pwrdm: struct powerdomain * to get power state - * - * Return the powerdomain pwrdm's current power state. Returns -EINVAL - * if the powerdomain pointer is null or returns the current power state - * upon success. - */ -int pwrdm_read_pwrst(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, - OMAP_POWERSTATEST_MASK); -} - -/** - * pwrdm_read_prev_pwrst - get previous powerdomain power state - * @pwrdm: struct powerdomain * to get previous power state - * - * Return the powerdomain pwrdm's previous power state. Returns -EINVAL - * if the powerdomain pointer is null or returns the previous power state - * upon success. - */ -int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, - OMAP3430_LASTPOWERSTATEENTERED_MASK); -} - -/** - * pwrdm_set_logic_retst - set powerdomain logic power state upon retention - * @pwrdm: struct powerdomain * to set - * @pwrst: one of the PWRDM_POWER_* macros - * - * Set the next power state that the logic portion of the powerdomain - * pwrdm will enter when the powerdomain enters retention. This will - * be either RETENTION or OFF, if supported. Returns -EINVAL if the - * powerdomain pointer is null or the target power state is not not - * supported, or returns 0 upon success. - */ -int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) -{ - if (!pwrdm) - return -EINVAL; - - if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) - return -EINVAL; - - pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n", - pwrdm->name, pwrst); - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE, - (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)), - pwrdm->prcm_offs, PM_PWSTCTRL); - - return 0; -} - -/** - * pwrdm_set_mem_onst - set memory power state while powerdomain ON - * @pwrdm: struct powerdomain * to set - * @bank: memory bank number to set (0-3) - * @pwrst: one of the PWRDM_POWER_* macros - * - * Set the next power state that memory bank x of the powerdomain - * pwrdm will enter when the powerdomain enters the ON state. Bank - * will be a number from 0 to 3, and represents different types of - * memory, depending on the powerdomain. Returns -EINVAL if the - * powerdomain pointer is null or the target power state is not not - * supported for this memory bank, -EEXIST if the target memory bank - * does not exist or is not controllable, or returns 0 upon success. - */ -int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) -{ - u32 m; - - if (!pwrdm) - return -EINVAL; - - if (pwrdm->banks < (bank + 1)) - return -EEXIST; - - if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) - return -EINVAL; - - pr_debug("powerdomain: setting next memory powerstate for domain %s " - "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK; - break; - case 1: - m = OMAP3430_L1FLATMEMONSTATE_MASK; - break; - case 2: - m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK; - break; - case 3: - m = OMAP3430_L2FLATMEMONSTATE_MASK; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } - - prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), - pwrdm->prcm_offs, PM_PWSTCTRL); - - return 0; -} - -/** - * pwrdm_set_mem_retst - set memory power state while powerdomain in RET - * @pwrdm: struct powerdomain * to set - * @bank: memory bank number to set (0-3) - * @pwrst: one of the PWRDM_POWER_* macros - * - * Set the next power state that memory bank x of the powerdomain - * pwrdm will enter when the powerdomain enters the RETENTION state. - * Bank will be a number from 0 to 3, and represents different types - * of memory, depending on the powerdomain. pwrst will be either - * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain - * pointer is null or the target power state is not not supported for - * this memory bank, -EEXIST if the target memory bank does not exist - * or is not controllable, or returns 0 upon success. - */ -int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) -{ - u32 m; - - if (!pwrdm) - return -EINVAL; - - if (pwrdm->banks < (bank + 1)) - return -EEXIST; - - if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) - return -EINVAL; - - pr_debug("powerdomain: setting next memory powerstate for domain %s " - "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_SHAREDL1CACHEFLATRETSTATE; - break; - case 1: - m = OMAP3430_L1FLATMEMRETSTATE; - break; - case 2: - m = OMAP3430_SHAREDL2CACHEFLATRETSTATE; - break; - case 3: - m = OMAP3430_L2FLATMEMRETSTATE; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } - - prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, - PM_PWSTCTRL); - - return 0; -} - -/** - * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state - * @pwrdm: struct powerdomain * to get current logic retention power state - * - * Return the current power state that the logic portion of - * powerdomain pwrdm will enter - * Returns -EINVAL if the powerdomain pointer is null or returns the - * current logic retention power state upon success. - */ -int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, - OMAP3430_LOGICSTATEST); -} - -/** - * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state - * @pwrdm: struct powerdomain * to get previous logic power state - * - * Return the powerdomain pwrdm's logic power state. Returns -EINVAL - * if the powerdomain pointer is null or returns the previous logic - * power state upon success. - */ -int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, - OMAP3430_LASTLOGICSTATEENTERED); -} - -/** - * pwrdm_read_mem_pwrst - get current memory bank power state - * @pwrdm: struct powerdomain * to get current memory bank power state - * @bank: memory bank number (0-3) - * - * Return the powerdomain pwrdm's current memory power state for bank - * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if - * the target memory bank does not exist or is not controllable, or - * returns the current memory power state upon success. - */ -int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) -{ - u32 m; - - if (!pwrdm) - return -EINVAL; - - if (pwrdm->banks < (bank + 1)) - return -EEXIST; - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK; - break; - case 1: - m = OMAP3430_L1FLATMEMSTATEST_MASK; - break; - case 2: - m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK; - break; - case 3: - m = OMAP3430_L2FLATMEMSTATEST_MASK; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } - - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m); -} - -/** - * pwrdm_read_prev_mem_pwrst - get previous memory bank power state - * @pwrdm: struct powerdomain * to get previous memory bank power state - * @bank: memory bank number (0-3) - * - * Return the powerdomain pwrdm's previous memory power state for bank - * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if - * the target memory bank does not exist or is not controllable, or - * returns the previous memory power state upon success. - */ -int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) -{ - u32 m; - - if (!pwrdm) - return -EINVAL; - - if (pwrdm->banks < (bank + 1)) - return -EEXIST; - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_LASTMEM1STATEENTERED_MASK; - break; - case 1: - m = OMAP3430_LASTMEM2STATEENTERED_MASK; - break; - case 2: - m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; - break; - case 3: - m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } - - return prm_read_mod_bits_shift(pwrdm->prcm_offs, - OMAP3430_PM_PREPWSTST, m); -} - -/** - * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm - * @pwrdm: struct powerdomain * to clear - * - * Clear the powerdomain's previous power state register. Clears the - * entire register, including logic and memory bank previous power states. - * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon - * success. - */ -int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - /* - * XXX should get the powerdomain's current state here; - * warn & fail if it is not ON. - */ - - pr_debug("powerdomain: clearing previous power state reg for %s\n", - pwrdm->name); - - prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); - - return 0; -} - -/** - * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm - * @pwrdm: struct powerdomain * - * - * Enable automatic context save-and-restore upon power state change - * for some devices in a powerdomain. Warning: this only affects a - * subset of devices in a powerdomain; check the TRM closely. Returns - * -EINVAL if the powerdomain pointer is null or if the powerdomain - * does not support automatic save-and-restore, or returns 0 upon - * success. - */ -int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) - return -EINVAL; - - pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", - pwrdm->name); - - prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, - pwrdm->prcm_offs, PM_PWSTCTRL); - - return 0; -} - -/** - * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm - * @pwrdm: struct powerdomain * - * - * Disable automatic context save-and-restore upon power state change - * for some devices in a powerdomain. Warning: this only affects a - * subset of devices in a powerdomain; check the TRM closely. Returns - * -EINVAL if the powerdomain pointer is null or if the powerdomain - * does not support automatic save-and-restore, or returns 0 upon - * success. - */ -int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) -{ - if (!pwrdm) - return -EINVAL; - - if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) - return -EINVAL; - - pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", - pwrdm->name); - - prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0, - pwrdm->prcm_offs, PM_PWSTCTRL); - - return 0; -} - -/** - * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR - * @pwrdm: struct powerdomain * - * - * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore - * for some devices, or 0 if it does not. - */ -bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) -{ - return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; -} - -/** - * pwrdm_wait_transition - wait for powerdomain power transition to finish - * @pwrdm: struct powerdomain * to wait for - * - * If the powerdomain pwrdm is in the process of a state transition, - * spin until it completes the power transition, or until an iteration - * bailout value is reached. Returns -EINVAL if the powerdomain - * pointer is null, -EAGAIN if the bailout value was reached, or - * returns 0 upon success. - */ -int pwrdm_wait_transition(struct powerdomain *pwrdm) -{ - u32 c = 0; - - if (!pwrdm) - return -EINVAL; - - /* - * REVISIT: pwrdm_wait_transition() may be better implemented - * via a callback and a periodic timer check -- how long do we expect - * powerdomain transitions to take? - */ - - /* XXX Is this udelay() value meaningful? */ - while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) & - OMAP_INTRANSITION) && - (c++ < PWRDM_TRANSITION_BAILOUT)) - udelay(1); - - if (c >= PWRDM_TRANSITION_BAILOUT) { - printk(KERN_ERR "powerdomain: waited too long for " - "powerdomain %s to complete transition\n", pwrdm->name); - return -EAGAIN; - } - - pr_debug("powerdomain: completed transition in %d loops\n", c); - - return 0; -} - - diff --git a/trunk/arch/arm/mach-omap2/powerdomains.h b/trunk/arch/arm/mach-omap2/powerdomains.h deleted file mode 100644 index 1e151faebbd3..000000000000 --- a/trunk/arch/arm/mach-omap2/powerdomains.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * OMAP2/3 common powerdomain definitions - * - * Copyright (C) 2007-8 Texas Instruments, Inc. - * Copyright (C) 2007-8 Nokia Corporation - * - * Written by Paul Walmsley - * Debugging and integration fixes by Jouni Högander - * - * 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS -#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS - -/* - * This file contains all of the powerdomains that have some element - * of software control for the OMAP24xx and OMAP34XX chips. - * - * A few notes: - * - * This is not an exhaustive listing of powerdomains on the chips; only - * powerdomains that can be controlled in software. - * - * A useful validation rule for struct powerdomain: - * Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array - * must have a dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really - * just software-controllable dependencies. Non-software-controllable - * dependencies do exist, but they are not encoded below (yet). - * - * 24xx does not support programmable sleep dependencies (SLEEPDEP) - * - */ - -/* - * The names for the DSP/IVA2 powerdomains are confusing. - * - * Most OMAP chips have an on-board DSP. - * - * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its - * powerdomain is called the "DSP power domain." On the 2430, the - * on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1. Its - * powerdomain is still called the "DSP power domain." On the 3430, - * the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but - * its powerdomain is now called the "IVA2 power domain." - * - * The 2420 also has something called the IVA, which is a separate ARM - * core, and has nothing to do with the DSP/IVA2. - * - * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM - * address offset is different between the C55 and C64 DSPs. - * - * The overly-specific dep_bit names are due to a bit name collision - * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift - * value are the same for all powerdomains: 2 - */ - -/* - * XXX should dep_bit be a mask, so we can test to see if it is 0 as a - * sanity check? - * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE - */ - -#include - -#include "prcm-common.h" -#include "prm.h" -#include "cm.h" - -/* OMAP2/3-common powerdomains and wakeup dependencies */ - -/* - * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP - * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE - * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE - */ -static struct pwrdm_dep gfx_sgx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | - CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | - CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* - * 3430: CM_SLEEPDEP_CAM: MPU - * 3430ES1: CM_SLEEPDEP_GFX: MPU - * 3430ES2: CM_SLEEPDEP_SGX: MPU - */ -static struct pwrdm_dep cam_gfx_sleepdeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -#include "powerdomains24xx.h" -#include "powerdomains34xx.h" - - -/* - * OMAP2/3 common powerdomains - */ - -/* - * The GFX powerdomain is not present on 3430ES2, but currently we do not - * have a macro to filter it out at compile-time. - */ -static struct powerdomain gfx_pwrdm = { - .name = "gfx_pwrdm", - .prcm_offs = GFX_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | - CHIP_IS_OMAP3430ES1), - .wkdep_srcs = gfx_sgx_wkdeps, - .sleepdep_srcs = cam_gfx_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain wkup_pwrdm = { - .name = "wkup_pwrdm", - .prcm_offs = WKUP_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), - .dep_bit = OMAP_EN_WKUP_SHIFT, -}; - - - -/* As powerdomains are added or removed above, this list must also be changed */ -static struct powerdomain *powerdomains_omap[] __initdata = { - - &gfx_pwrdm, - &wkup_pwrdm, - -#ifdef CONFIG_ARCH_OMAP24XX - &dsp_pwrdm, - &mpu_24xx_pwrdm, - &core_24xx_pwrdm, -#endif - -#ifdef CONFIG_ARCH_OMAP2430 - &mdm_pwrdm, -#endif - -#ifdef CONFIG_ARCH_OMAP34XX - &iva2_pwrdm, - &mpu_34xx_pwrdm, - &neon_pwrdm, - &core_34xx_pwrdm, - &cam_pwrdm, - &dss_pwrdm, - &per_pwrdm, - &emu_pwrdm, - &sgx_pwrdm, - &usbhost_pwrdm, -#endif - - NULL -}; - - -#endif diff --git a/trunk/arch/arm/mach-omap2/powerdomains24xx.h b/trunk/arch/arm/mach-omap2/powerdomains24xx.h deleted file mode 100644 index 9f08dc3f7fd2..000000000000 --- a/trunk/arch/arm/mach-omap2/powerdomains24xx.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * OMAP24XX powerdomain definitions - * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation - * - * Written by Paul Walmsley - * Debugging and integration fixes by Jouni Högander - * - * 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX -#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX - -/* - * N.B. If powerdomains are added or removed from this file, update - * the array in mach-omap2/powerdomains.h. - */ - -#include - -#include "prcm-common.h" -#include "prm.h" -#include "prm-regbits-24xx.h" -#include "cm.h" -#include "cm-regbits-24xx.h" - -/* 24XX powerdomains and dependencies */ - -#ifdef CONFIG_ARCH_OMAP24XX - - -/* Wakeup dependency source arrays */ - -/* - * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP - * 2430 PM_WKDEP_MDM: same as above - */ -static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { NULL }, -}; - -/* - * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP - * 2430 adds MDM - */ -static struct pwrdm_dep mpu_24xx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "dsp_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mdm_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }, - { NULL }, -}; - -/* - * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP - * 2430 adds MDM - */ -static struct pwrdm_dep core_24xx_wkdeps[] = { - { - .pwrdm_name = "dsp_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "gfx_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mdm_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }, - { NULL }, -}; - - -/* Powerdomains */ - -static struct powerdomain dsp_pwrdm = { - .name = "dsp_pwrdm", - .prcm_offs = OMAP24XX_DSP_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), - .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT, - .wkdep_srcs = dsp_mdm_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - }, -}; - -static struct powerdomain mpu_24xx_pwrdm = { - .name = "mpu_pwrdm", - .prcm_offs = MPU_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), - .dep_bit = OMAP24XX_EN_MPU_SHIFT, - .wkdep_srcs = mpu_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - }, -}; - -static struct powerdomain core_24xx_pwrdm = { - .name = "core_pwrdm", - .prcm_offs = CORE_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), - .wkdep_srcs = core_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .dep_bit = OMAP24XX_EN_CORE_SHIFT, - .banks = 3, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ - [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ - [2] = PWRSTS_OFF_RET, /* MEM3RETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ - [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ - [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ - }, -}; - -#endif /* CONFIG_ARCH_OMAP24XX */ - - - -/* - * 2430-specific powerdomains - */ - -#ifdef CONFIG_ARCH_OMAP2430 - -/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */ - -/* Another case of bit name collisions between several registers: EN_MDM */ -static struct powerdomain mdm_pwrdm = { - .name = "mdm_pwrdm", - .prcm_offs = OMAP2430_MDM_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT, - .wkdep_srcs = dsp_mdm_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -#endif /* CONFIG_ARCH_OMAP2430 */ - - -#endif diff --git a/trunk/arch/arm/mach-omap2/powerdomains34xx.h b/trunk/arch/arm/mach-omap2/powerdomains34xx.h deleted file mode 100644 index f573f7108398..000000000000 --- a/trunk/arch/arm/mach-omap2/powerdomains34xx.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * OMAP34XX powerdomain definitions - * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation - * - * Written by Paul Walmsley - * Debugging and integration fixes by Jouni Högander - * - * 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX -#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX - -/* - * N.B. If powerdomains are added or removed from this file, update - * the array in mach-omap2/powerdomains.h. - */ - -#include - -#include "prcm-common.h" -#include "prm.h" -#include "prm-regbits-34xx.h" -#include "cm.h" -#include "cm-regbits-34xx.h" - -/* - * 34XX-specific powerdomains, dependencies - */ - -#ifdef CONFIG_ARCH_OMAP34XX - -/* - * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP - * (USBHOST is ES2 only) - */ -static struct pwrdm_dep per_usbhost_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* - * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER - */ -static struct pwrdm_dep mpu_34xx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "dss_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "per_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* - * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER - */ -static struct pwrdm_dep iva2_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "dss_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "per_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */ -static struct pwrdm_dep cam_dss_wkdeps[] = { - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* 3430: PM_WKDEP_NEON: MPU */ -static struct pwrdm_dep neon_wkdeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */ - -/* - * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA - * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA - */ -static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -/* - * Powerdomains - */ - -static struct powerdomain iva2_pwrdm = { - .name = "iva2_pwrdm", - .prcm_offs = OMAP3430_IVA2_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT, - .wkdep_srcs = iva2_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 4, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, - [1] = PWRSTS_OFF_RET, - [2] = PWRSTS_OFF_RET, - [3] = PWRSTS_OFF_RET, - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - [1] = PWRDM_POWER_ON, - [2] = PWRSTS_OFF_ON, - [3] = PWRDM_POWER_ON, - }, -}; - -static struct powerdomain mpu_34xx_pwrdm = { - .name = "mpu_pwrdm", - .prcm_offs = MPU_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .dep_bit = OMAP3430_EN_MPU_SHIFT, - .wkdep_srcs = mpu_34xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, - }, - .pwrsts_mem_on = { - [0] = PWRSTS_OFF_ON, - }, -}; - -/* No wkdeps or sleepdeps for 34xx core apparently */ -static struct powerdomain core_34xx_pwrdm = { - .name = "core_pwrdm", - .prcm_offs = CORE_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .pwrsts = PWRSTS_OFF_RET_ON, - .dep_bit = OMAP3430_EN_CORE_SHIFT, - .banks = 2, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ - [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ - [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ - }, -}; - -/* Another case of bit name collisions between several registers: EN_DSS */ -static struct powerdomain dss_pwrdm = { - .name = "dss_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .prcm_offs = OMAP3430_DSS_MOD, - .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT, - .wkdep_srcs = cam_dss_wkdeps, - .sleepdep_srcs = dss_per_usbhost_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain sgx_pwrdm = { - .name = "sgx_pwrdm", - .prcm_offs = OMAP3430ES2_SGX_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), - .wkdep_srcs = gfx_sgx_wkdeps, - .sleepdep_srcs = cam_gfx_sleepdeps, - /* XXX This is accurate for 3430 SGX, but what about GFX? */ - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain cam_pwrdm = { - .name = "cam_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .prcm_offs = OMAP3430_CAM_MOD, - .wkdep_srcs = cam_dss_wkdeps, - .sleepdep_srcs = cam_gfx_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain per_pwrdm = { - .name = "per_pwrdm", - .prcm_offs = OMAP3430_PER_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .dep_bit = OMAP3430_EN_PER_SHIFT, - .wkdep_srcs = per_usbhost_wkdeps, - .sleepdep_srcs = dss_per_usbhost_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain emu_pwrdm = { - .name = "emu_pwrdm", - .prcm_offs = OMAP3430_EMU_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct powerdomain neon_pwrdm = { - .name = "neon_pwrdm", - .prcm_offs = OMAP3430_NEON_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .wkdep_srcs = neon_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, -}; - -static struct powerdomain usbhost_pwrdm = { - .name = "usbhost_pwrdm", - .prcm_offs = OMAP3430ES2_USBHOST_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), - .wkdep_srcs = per_usbhost_wkdeps, - .sleepdep_srcs = dss_per_usbhost_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -#endif /* CONFIG_ARCH_OMAP34XX */ - - -#endif diff --git a/trunk/arch/arm/mach-omap2/prcm-common.h b/trunk/arch/arm/mach-omap2/prcm-common.h index 4a32822ff3fc..54c32f482131 100644 --- a/trunk/arch/arm/mach-omap2/prcm-common.h +++ b/trunk/arch/arm/mach-omap2/prcm-common.h @@ -312,8 +312,7 @@ #define OMAP3430_ST_GPT2 (1 << 3) /* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */ -#define OMAP3430_EN_CORE_SHIFT 0 -#define OMAP3430_EN_CORE_MASK (1 << 0) +#define OMAP3430_EN_CORE (1 << 0) #endif diff --git a/trunk/arch/arm/mach-omap2/prm-regbits-24xx.h b/trunk/arch/arm/mach-omap2/prm-regbits-24xx.h index 4002051c20b9..c6d17a3378ec 100644 --- a/trunk/arch/arm/mach-omap2/prm-regbits-24xx.h +++ b/trunk/arch/arm/mach-omap2/prm-regbits-24xx.h @@ -29,10 +29,8 @@ #define OMAP24XX_WKUP1_EN (1 << 0) /* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */ -#define OMAP24XX_EN_MPU_SHIFT 1 -#define OMAP24XX_EN_MPU_MASK (1 << 1) -#define OMAP24XX_EN_CORE_SHIFT 0 -#define OMAP24XX_EN_CORE_MASK (1 << 0) +#define OMAP24XX_EN_MPU (1 << 1) +#define OMAP24XX_EN_CORE (1 << 0) /* * PM_PWSTCTRL_MPU, PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM @@ -142,10 +140,8 @@ /* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */ /* PM_WKDEP_MPU specific bits */ -#define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT 5 -#define OMAP2430_PM_WKDEP_MPU_EN_MDM_MASK (1 << 5) -#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT 2 -#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_MASK (1 << 2) +#define OMAP2430_PM_WKDEP_MPU_EN_MDM (1 << 5) +#define OMAP24XX_PM_WKDEP_MPU_EN_DSP (1 << 2) /* PM_EVGENCTRL_MPU specific bits */ diff --git a/trunk/arch/arm/mach-omap2/prm-regbits-34xx.h b/trunk/arch/arm/mach-omap2/prm-regbits-34xx.h index 5b5ecfe6c999..b4686bc345ca 100644 --- a/trunk/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/trunk/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -68,8 +68,7 @@ #define OMAP3430_VPINIDLE (1 << 0) /* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */ -#define OMAP3430_EN_PER_SHIFT 7 -#define OMAP3430_EN_PER_MASK (1 << 7) +#define OMAP3430_EN_PER (1 << 7) /* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */ #define OMAP3430_MEMORYCHANGE (1 << 3) @@ -78,7 +77,7 @@ #define OMAP3430_LOGICSTATEST (1 << 2) /* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */ -#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2) +#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2) /* * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE, @@ -279,10 +278,8 @@ #define OMAP3430_EMULATION_MPU_RST (1 << 11) /* PM_WKDEP_MPU specific bits */ -#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5 -#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK (1 << 5) -#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2 -#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK (1 << 2) +#define OMAP3430_PM_WKDEP_MPU_EN_DSS (1 << 5) +#define OMAP3430_PM_WKDEP_MPU_EN_IVA2 (1 << 2) /* PM_EVGENCTRL_MPU */ #define OMAP3430_OFFLOADMODE_SHIFT 3 diff --git a/trunk/arch/arm/mach-omap2/prm.h b/trunk/arch/arm/mach-omap2/prm.h index e4dc4b17881d..bbf41fc8e9a9 100644 --- a/trunk/arch/arm/mach-omap2/prm.h +++ b/trunk/arch/arm/mach-omap2/prm.h @@ -18,7 +18,7 @@ #ifndef __ASSEMBLER__ #define OMAP_PRM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg)) + (void __iomem *)IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg)) #else #define OMAP2420_PRM_REGADDR(module, reg) \ IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg)) @@ -305,8 +305,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM, * PM_WKDEP_PER */ -#define OMAP_EN_WKUP_SHIFT 4 -#define OMAP_EN_WKUP_MASK (1 << 4) +#define OMAP_EN_WKUP (1 << 4) /* * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, diff --git a/trunk/arch/arm/mach-omap2/serial.c b/trunk/arch/arm/mach-omap2/serial.c index 4dcf39c285b9..7d9444adc5df 100644 --- a/trunk/arch/arm/mach-omap2/serial.c +++ b/trunk/arch/arm/mach-omap2/serial.c @@ -3,7 +3,7 @@ * * OMAP2 serial support. * - * Copyright (C) 2005-2008 Nokia Corporation + * Copyright (C) 2005 Nokia Corporation * Author: Paul Mundt * * Based off of arch/arm/mach-omap/omap1/serial.c @@ -22,34 +22,38 @@ #include #include -static struct clk *uart_ick[OMAP_MAX_NR_PORTS]; -static struct clk *uart_fck[OMAP_MAX_NR_PORTS]; +static struct clk * uart1_ick = NULL; +static struct clk * uart1_fck = NULL; +static struct clk * uart2_ick = NULL; +static struct clk * uart2_fck = NULL; +static struct clk * uart3_ick = NULL; +static struct clk * uart3_fck = NULL; static struct plat_serial8250_port serial_platform_data[] = { { - .membase = IO_ADDRESS(OMAP_UART1_BASE), - .mapbase = OMAP_UART1_BASE, + .membase = (char *)IO_ADDRESS(OMAP_UART1_BASE), + .mapbase = (unsigned long)OMAP_UART1_BASE, .irq = 72, .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = OMAP24XX_BASE_BAUD * 16, + .uartclk = OMAP16XX_BASE_BAUD * 16, }, { - .membase = IO_ADDRESS(OMAP_UART2_BASE), - .mapbase = OMAP_UART2_BASE, + .membase = (char *)IO_ADDRESS(OMAP_UART2_BASE), + .mapbase = (unsigned long)OMAP_UART2_BASE, .irq = 73, .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = OMAP24XX_BASE_BAUD * 16, + .uartclk = OMAP16XX_BASE_BAUD * 16, }, { - .membase = IO_ADDRESS(OMAP_UART3_BASE), - .mapbase = OMAP_UART3_BASE, + .membase = (char *)IO_ADDRESS(OMAP_UART3_BASE), + .mapbase = (unsigned long)OMAP_UART3_BASE, .irq = 74, .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = OMAP24XX_BASE_BAUD * 16, + .uartclk = OMAP16XX_BASE_BAUD * 16, }, { .flags = 0 } @@ -66,7 +70,7 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, int value) { offset <<= p->regshift; - __raw_writeb(value, p->membase + offset); + __raw_writeb(value, (unsigned long)(p->membase + offset)); } /* @@ -82,27 +86,10 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p) serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0)); } -void omap_serial_enable_clocks(int enable) -{ - int i; - for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { - if (uart_ick[i] && uart_fck[i]) { - if (enable) { - clk_enable(uart_ick[i]); - clk_enable(uart_fck[i]); - } else { - clk_disable(uart_ick[i]); - clk_disable(uart_fck[i]); - } - } - } -} - -void __init omap_serial_init(void) +void __init omap_serial_init() { int i; const struct omap_uart_config *info; - char name[16]; /* * Make sure the serial ports are muxed on at this point. @@ -110,7 +97,8 @@ void __init omap_serial_init(void) * if not needed. */ - info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); + info = omap_get_config(OMAP_TAG_UART, + struct omap_uart_config); if (info == NULL) return; @@ -119,26 +107,58 @@ void __init omap_serial_init(void) struct plat_serial8250_port *p = serial_platform_data + i; if (!(info->enabled_uarts & (1 << i))) { - p->membase = NULL; + p->membase = 0; p->mapbase = 0; continue; } - sprintf(name, "uart%d_ick", i+1); - uart_ick[i] = clk_get(NULL, name); - if (IS_ERR(uart_ick[i])) { - printk(KERN_ERR "Could not get uart%d_ick\n", i+1); - uart_ick[i] = NULL; - } else - clk_enable(uart_ick[i]); - - sprintf(name, "uart%d_fck", i+1); - uart_fck[i] = clk_get(NULL, name); - if (IS_ERR(uart_fck[i])) { - printk(KERN_ERR "Could not get uart%d_fck\n", i+1); - uart_fck[i] = NULL; - } else - clk_enable(uart_fck[i]); + switch (i) { + case 0: + uart1_ick = clk_get(NULL, "uart1_ick"); + if (IS_ERR(uart1_ick)) + printk("Could not get uart1_ick\n"); + else { + clk_enable(uart1_ick); + } + + uart1_fck = clk_get(NULL, "uart1_fck"); + if (IS_ERR(uart1_fck)) + printk("Could not get uart1_fck\n"); + else { + clk_enable(uart1_fck); + } + break; + case 1: + uart2_ick = clk_get(NULL, "uart2_ick"); + if (IS_ERR(uart2_ick)) + printk("Could not get uart2_ick\n"); + else { + clk_enable(uart2_ick); + } + + uart2_fck = clk_get(NULL, "uart2_fck"); + if (IS_ERR(uart2_fck)) + printk("Could not get uart2_fck\n"); + else { + clk_enable(uart2_fck); + } + break; + case 2: + uart3_ick = clk_get(NULL, "uart3_ick"); + if (IS_ERR(uart3_ick)) + printk("Could not get uart3_ick\n"); + else { + clk_enable(uart3_ick); + } + + uart3_fck = clk_get(NULL, "uart3_fck"); + if (IS_ERR(uart3_fck)) + printk("Could not get uart3_fck\n"); + else { + clk_enable(uart3_fck); + } + break; + } omap_serial_reset(p); } diff --git a/trunk/arch/arm/mach-omap2/sleep24xx.S b/trunk/arch/arm/mach-omap2/sleep.S similarity index 85% rename from trunk/arch/arm/mach-omap2/sleep24xx.S rename to trunk/arch/arm/mach-omap2/sleep.S index 43336b93b21c..87a706fd5f82 100644 --- a/trunk/arch/arm/mach-omap2/sleep24xx.S +++ b/trunk/arch/arm/mach-omap2/sleep.S @@ -5,10 +5,6 @@ * Texas Instruments, * Richard Woodruff * - * (C) Copyright 2006 Nokia Corporation - * Fixed idle loop sleep - * Igor Stoppa - * * 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 @@ -30,8 +26,6 @@ #include #include -#include - #include "sdrc.h" /* First address of reserved address space? apparently valid for OMAP2 & 3 */ @@ -58,14 +52,15 @@ ENTRY(omap24xx_idle_loop_suspend_sz) .word . - omap24xx_idle_loop_suspend /* - * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing + * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore * SDRC. * * Input: * R0 : DLL ctrl value pre-Sleep - * R1 : SDRC_DLLA_CTRL - * R2 : SDRC_POWER + * R1 : Processor+Revision + * 2420: 0x21 = 242xES1, 0x26 = 242xES2.2 + * 2430: 0x31 = 2430ES1, 0x32 = 2430ES2 * * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on * when we get called, but the DLL probably isn't. We will wait a bit more in @@ -85,14 +80,15 @@ ENTRY(omap24xx_idle_loop_suspend_sz) */ ENTRY(omap24xx_cpu_suspend) stmfd sp!, {r0 - r12, lr} @ save registers on stack - mov r3, #0x0 @ clear for mcr call + mov r3, #0x0 @ clear for mrc call mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished nop nop - ldr r4, [r2] @ read SDRC_POWER + ldr r3, A_SDRC_POWER @ addr of sdrc power + ldr r4, [r3] @ value of sdrc power orr r4, r4, #0x40 @ enable self refresh on idle req mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) - str r4, [r2] @ make it so + str r4, [r3] @ make it so mov r2, #0 nop mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt @@ -101,13 +97,14 @@ loop: subs r5, r5, #0x1 @ awake, wait just a bit bne loop - /* The DPLL has to be on before we take the DDR out of self refresh */ + /* The DPLL has on before we take the DDR out of self refresh */ bic r4, r4, #0x40 @ now clear self refresh bit. - str r4, [r2] @ write to SDRC_POWER + str r4, [r3] @ put vlaue back. ldr r4, A_SDRC0 @ make a clock happen - ldr r4, [r4] @ read A_SDRC0 + ldr r4, [r4] nop @ start auto refresh only after clk ok movs r0, r0 @ see if DDR or SDR + ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl strne r0, [r1] @ rewrite DLLA to force DLL reload addne r1, r1, #0x8 @ move to DLLB strne r0, [r1] @ rewrite DLLB to force DLL reload @@ -119,8 +116,13 @@ loop2: /* resume*/ ldmfd sp!, {r0 - r12, pc} @ restore regs and return +A_SDRC_POWER: + .word OMAP242X_SDRC_REGADDR(SDRC_POWER) A_SDRC0: .word A_SDRC0_V +A_SDRC_DLLA_CTRL_S: + .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) ENTRY(omap24xx_cpu_suspend_sz) .word . - omap24xx_cpu_suspend + diff --git a/trunk/arch/arm/mach-omap2/sram34xx.S b/trunk/arch/arm/mach-omap2/sram34xx.S deleted file mode 100644 index 2c7146136342..000000000000 --- a/trunk/arch/arm/mach-omap2/sram34xx.S +++ /dev/null @@ -1,179 +0,0 @@ -/* - * linux/arch/arm/mach-omap3/sram.S - * - * Omap3 specific functions that need to be run in internal SRAM - * - * (C) Copyright 2007 - * Texas Instruments Inc. - * Rajendra Nayak - * - * (C) Copyright 2004 - * Texas Instruments, - * Richard Woodruff - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include - -#include - -#include "sdrc.h" -#include "cm.h" - - .text - -/* - * Change frequency of core dpll - * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2 - */ -ENTRY(omap3_sram_configure_core_dpll) - stmfd sp!, {r1-r12, lr} @ store regs to stack - cmp r3, #0x2 - blne configure_sdrc - cmp r3, #0x2 - blne lock_dll - cmp r3, #0x1 - blne unlock_dll - bl sdram_in_selfrefresh @ put the SDRAM in self refresh - bl configure_core_dpll - bl enable_sdrc - cmp r3, #0x1 - blne wait_dll_unlock - cmp r3, #0x2 - blne wait_dll_lock - cmp r3, #0x1 - blne configure_sdrc - mov r0, #0 @ return value - ldmfd sp!, {r1-r12, pc} @ restore regs and return -unlock_dll: - ldr r4, omap3_sdrc_dlla_ctrl - ldr r5, [r4] - orr r5, r5, #0x4 - str r5, [r4] - bx lr -lock_dll: - ldr r4, omap3_sdrc_dlla_ctrl - ldr r5, [r4] - bic r5, r5, #0x4 - str r5, [r4] - bx lr -sdram_in_selfrefresh: - mov r5, #0x0 @ Move 0 to R5 - mcr p15, 0, r5, c7, c10, 5 @ memory barrier - ldr r4, omap3_sdrc_power @ read the SDRC_POWER register - ldr r5, [r4] @ read the contents of SDRC_POWER - orr r5, r5, #0x40 @ enable self refresh on idle req - str r5, [r4] @ write back to SDRC_POWER register - ldr r4, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg - ldr r5, [r4] - bic r5, r5, #0x2 @ disable iclk bit for SRDC - str r5, [r4] -wait_sdrc_idle: - ldr r4, omap3_cm_idlest1_core - ldr r5, [r4] - and r5, r5, #0x2 @ check for SDRC idle - cmp r5, #2 - bne wait_sdrc_idle - bx lr -configure_core_dpll: - ldr r4, omap3_cm_clksel1_pll - ldr r5, [r4] - ldr r6, core_m2_mask_val @ modify m2 for core dpll - and r5, r5, r6 - orr r5, r5, r3, lsl #0x1B @ r3 contains the M2 val - str r5, [r4] - mov r5, #0x800 @ wait for the clock to stabilise - cmp r3, #2 - bne wait_clk_stable - bx lr -wait_clk_stable: - subs r5, r5, #1 - bne wait_clk_stable - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - bx lr -enable_sdrc: - ldr r4, omap3_cm_iclken1_core - ldr r5, [r4] - orr r5, r5, #0x2 @ enable iclk bit for SDRC - str r5, [r4] -wait_sdrc_idle1: - ldr r4, omap3_cm_idlest1_core - ldr r5, [r4] - and r5, r5, #0x2 - cmp r5, #0 - bne wait_sdrc_idle1 - ldr r4, omap3_sdrc_power - ldr r5, [r4] - bic r5, r5, #0x40 - str r5, [r4] - bx lr -wait_dll_lock: - ldr r4, omap3_sdrc_dlla_status - ldr r5, [r4] - and r5, r5, #0x4 - cmp r5, #0x4 - bne wait_dll_lock - bx lr -wait_dll_unlock: - ldr r4, omap3_sdrc_dlla_status - ldr r5, [r4] - and r5, r5, #0x4 - cmp r5, #0x0 - bne wait_dll_unlock - bx lr -configure_sdrc: - ldr r4, omap3_sdrc_rfr_ctrl - str r0, [r4] - ldr r4, omap3_sdrc_actim_ctrla - str r1, [r4] - ldr r4, omap3_sdrc_actim_ctrlb - str r2, [r4] - bx lr - -omap3_sdrc_power: - .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) -omap3_cm_clksel1_pll: - .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1) -omap3_cm_idlest1_core: - .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) -omap3_cm_iclken1_core: - .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) -omap3_sdrc_rfr_ctrl: - .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) -omap3_sdrc_actim_ctrla: - .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) -omap3_sdrc_actim_ctrlb: - .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) -omap3_sdrc_dlla_status: - .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) -omap3_sdrc_dlla_ctrl: - .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) -core_m2_mask_val: - .word 0x07FFFFFF - -ENTRY(omap3_sram_configure_core_dpll_sz) - .word . - omap3_sram_configure_core_dpll diff --git a/trunk/arch/arm/mach-pxa/cm-x270.c b/trunk/arch/arm/mach-pxa/cm-x270.c index df83b97f303f..a82dad1a8cc8 100644 --- a/trunk/arch/arm/mach-pxa/cm-x270.c +++ b/trunk/arch/arm/mach-pxa/cm-x270.c @@ -162,7 +162,7 @@ static void __init cmx270_init_rtc(void) platform_device_register(&cmx270_rtc_device); } #else -static inline void cmx270_init_rtc(void) {} +static inline void cmx2xx_init_rtc(void) {} #endif /* 2700G graphics */ diff --git a/trunk/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/trunk/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 1f272ea83f36..d82528e74bd0 100644 --- a/trunk/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/trunk/arch/arm/mach-pxa/cpufreq-pxa2xx.c @@ -335,6 +335,9 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) pxa27x_guess_max_freq(); /* set default policy and cpuinfo */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + if (cpu_is_pxa25x()) + policy->policy = CPUFREQ_POLICY_PERFORMANCE; policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ policy->cur = get_clk_frequency_khz(0); /* current freq */ policy->min = policy->max = policy->cur; diff --git a/trunk/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/trunk/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 968c8309ec37..1ea0c9c0adaf 100644 --- a/trunk/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/trunk/arch/arm/mach-pxa/cpufreq-pxa3xx.c @@ -210,6 +210,7 @@ static __init int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) int ret = -EINVAL; /* set default policy and cpuinfo */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = 104000; policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000; policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ diff --git a/trunk/arch/arm/mach-pxa/include/mach/camera.h b/trunk/arch/arm/mach-pxa/include/mach/camera.h index 31abe6d514b8..39516ced8b1f 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/camera.h +++ b/trunk/arch/arm/mach-pxa/include/mach/camera.h @@ -36,6 +36,8 @@ struct pxacamera_platform_data { int (*init)(struct device *); + int (*power)(struct device *, int); + int (*reset)(struct device *, int); unsigned long flags; unsigned long mclk_10khz; diff --git a/trunk/arch/arm/mach-pxa/viper.c b/trunk/arch/arm/mach-pxa/viper.c index 4b3120dbc049..d7632f63603c 100644 --- a/trunk/arch/arm/mach-pxa/viper.c +++ b/trunk/arch/arm/mach-pxa/viper.c @@ -204,54 +204,25 @@ static void viper_set_core_cpu_voltage(unsigned long khz, int force) /* Interrupt handling */ static unsigned long viper_irq_enabled_mask; -static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 }; -static const int viper_isa_irq_map[] = { - 0, /* ISA irq #0, invalid */ - 0, /* ISA irq #1, invalid */ - 0, /* ISA irq #2, invalid */ - 1 << 0, /* ISA irq #3 */ - 1 << 1, /* ISA irq #4 */ - 1 << 2, /* ISA irq #5 */ - 1 << 3, /* ISA irq #6 */ - 1 << 4, /* ISA irq #7 */ - 0, /* ISA irq #8, invalid */ - 1 << 8, /* ISA irq #9 */ - 1 << 5, /* ISA irq #10 */ - 1 << 6, /* ISA irq #11 */ - 1 << 7, /* ISA irq #12 */ - 0, /* ISA irq #13, invalid */ - 1 << 9, /* ISA irq #14 */ - 1 << 10, /* ISA irq #15 */ -}; - -static inline int viper_irq_to_bitmask(unsigned int irq) -{ - return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)]; -} - -static inline int viper_bit_to_irq(int bit) -{ - return viper_isa_irqs[bit] + PXA_ISA_IRQ(0); -} static void viper_ack_irq(unsigned int irq) { - int viper_irq = viper_irq_to_bitmask(irq); + int viper_irq = irq - PXA_ISA_IRQ(0); - if (viper_irq & 0xff) - VIPER_LO_IRQ_STATUS = viper_irq; + if (viper_irq < 8) + VIPER_LO_IRQ_STATUS = 1 << viper_irq; else - VIPER_HI_IRQ_STATUS = (viper_irq >> 8); + VIPER_HI_IRQ_STATUS = 1 << (viper_irq - 8); } static void viper_mask_irq(unsigned int irq) { - viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(irq)); + viper_irq_enabled_mask &= ~(1 << (irq - PXA_ISA_IRQ(0))); } static void viper_unmask_irq(unsigned int irq) { - viper_irq_enabled_mask |= viper_irq_to_bitmask(irq); + viper_irq_enabled_mask |= (1 << (irq - PXA_ISA_IRQ(0))); } static inline unsigned long viper_irq_pending(void) @@ -266,12 +237,8 @@ static void viper_irq_handler(unsigned int irq, struct irq_desc *desc) pending = viper_irq_pending(); do { - /* we're in a chained irq handler, - * so ack the interrupt by hand */ - GEDR(VIPER_CPLD_GPIO) = GPIO_bit(VIPER_CPLD_GPIO); - if (likely(pending)) { - irq = viper_bit_to_irq(__ffs(pending)); + irq = PXA_ISA_IRQ(0) + __ffs(pending); generic_handle_irq(irq); } pending = viper_irq_pending(); @@ -287,14 +254,15 @@ static struct irq_chip viper_irq_chip = { static void __init viper_init_irq(void) { - int level; + const int isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 }; + int irq; int isa_irq; pxa25x_init_irq(); /* setup ISA IRQs */ - for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) { - isa_irq = viper_bit_to_irq(level); + for (irq = 0; irq < ARRAY_SIZE(isa_irqs); irq++) { + isa_irq = isa_irqs[irq]; set_irq_chip(isa_irq, &viper_irq_chip); set_irq_handler(isa_irq, handle_edge_irq); set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); diff --git a/trunk/arch/arm/mach-s3c2410/bast-irq.c b/trunk/arch/arm/mach-s3c2410/bast-irq.c index 9a37c87152b0..75738000272b 100644 --- a/trunk/arch/arm/mach-s3c2410/bast-irq.c +++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c @@ -38,7 +38,7 @@ #include #include -#include +#include #if 0 #include diff --git a/trunk/arch/arm/mach-s3c2410/clock.c b/trunk/arch/arm/mach-s3c2410/clock.c index 4e07943c1e29..fef646c36b54 100644 --- a/trunk/arch/arm/mach-s3c2410/clock.c +++ b/trunk/arch/arm/mach-s3c2410/clock.c @@ -37,13 +37,13 @@ #include -#include +#include #include #include -#include -#include -#include +#include +#include +#include int s3c2410_clkcon_enable(struct clk *clk, int enable) { diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index 7d914a470b6c..8730797749e3 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -20,10 +20,10 @@ #include #include -#include -#include +#include +#include -#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/trunk/arch/arm/mach-s3c2410/include/mach/debug-macro.S index 4c29a89ad077..682df23087ab 100644 --- a/trunk/arch/arm/mach-s3c2410/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-s3c2410/include/mach/debug-macro.S @@ -14,7 +14,7 @@ #include #include -#include +#include #define S3C2410_UART1_OFF (0x4000) #define SHIFT_2440TXF (14-9) @@ -99,4 +99,4 @@ /* include the reset of the code which will do the work */ -#include +#include diff --git a/trunk/arch/arm/mach-s3c2410/include/mach/map.h b/trunk/arch/arm/mach-s3c2410/include/mach/map.h index 23c470c2e5b1..64bf7e94a5bf 100644 --- a/trunk/arch/arm/mach-s3c2410/include/mach/map.h +++ b/trunk/arch/arm/mach-s3c2410/include/mach/map.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MAP_H #define __ASM_ARCH_MAP_H -#include +#include #define S3C2410_ADDR(x) S3C_ADDR(x) diff --git a/trunk/arch/arm/mach-s3c2410/include/mach/spi.h b/trunk/arch/arm/mach-s3c2410/include/mach/spi.h index 46d46f5b99f2..921b13b4f0a0 100644 --- a/trunk/arch/arm/mach-s3c2410/include/mach/spi.h +++ b/trunk/arch/arm/mach-s3c2410/include/mach/spi.h @@ -18,7 +18,6 @@ struct s3c2410_spi_info { unsigned int num_cs; /* total chipselects */ int bus_num; /* bus number to use. */ - void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); }; diff --git a/trunk/arch/arm/mach-s3c2410/include/mach/uncompress.h b/trunk/arch/arm/mach-s3c2410/include/mach/uncompress.h index ab39491beee2..708e47459ffc 100644 --- a/trunk/arch/arm/mach-s3c2410/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-s3c2410/include/mach/uncompress.h @@ -21,7 +21,7 @@ #undef S3C2410_GPIOREG #define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x))) -#include +#include static inline int is_arm926(void) { diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c index 92150399563b..f5c5c53e1cc1 100644 --- a/trunk/arch/arm/mach-s3c2410/irq.c +++ b/trunk/arch/arm/mach-s3c2410/irq.c @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include static int s3c2410_irq_add(struct sys_device *sysdev) { diff --git a/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c b/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c index d061fea01900..527f88a288ec 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -48,12 +48,12 @@ #include #include -#include +#include #include #include -#include -#include +#include +#include #ifdef CONFIG_MTD_PARTITIONS diff --git a/trunk/arch/arm/mach-s3c2410/mach-bast.c b/trunk/arch/arm/mach-s3c2410/mach-bast.c index 8db9c700e3c2..e4368e6e7e6c 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-bast.c +++ b/trunk/arch/arm/mach-s3c2410/mach-bast.c @@ -39,7 +39,7 @@ #include //#include -#include +#include #include #include #include @@ -55,9 +55,9 @@ #include -#include -#include -#include +#include +#include +#include #include "usb-simtec.h" #include "nor-simtec.h" diff --git a/trunk/arch/arm/mach-s3c2410/mach-h1940.c b/trunk/arch/arm/mach-s3c2410/mach-h1940.c index 98716d0108e9..85e710f2863b 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-h1940.c +++ b/trunk/arch/arm/mach-s3c2410/mach-h1940.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include #include @@ -40,10 +40,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include static struct map_desc h1940_iodesc[] __initdata = { [0] = { diff --git a/trunk/arch/arm/mach-s3c2410/mach-n30.c b/trunk/arch/arm/mach-s3c2410/mach-n30.c index 82505517846c..3ece2d04934e 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-n30.c +++ b/trunk/arch/arm/mach-s3c2410/mach-n30.c @@ -41,12 +41,12 @@ #include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include static struct map_desc n30_iodesc[] __initdata = { diff --git a/trunk/arch/arm/mach-s3c2410/mach-otom.c b/trunk/arch/arm/mach-s3c2410/mach-otom.c index d8255cf87e44..c4dfe3eabe1d 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-otom.c +++ b/trunk/arch/arm/mach-s3c2410/mach-otom.c @@ -29,13 +29,13 @@ #include #include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include static struct map_desc otom11_iodesc[] __initdata = { /* Device area */ diff --git a/trunk/arch/arm/mach-s3c2410/mach-qt2410.c b/trunk/arch/arm/mach-s3c2410/mach-qt2410.c index 661807e14e8a..97c13192315b 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/trunk/arch/arm/mach-s3c2410/mach-qt2410.c @@ -48,17 +48,17 @@ #include #include -#include +#include #include #include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include static struct map_desc qt2410_iodesc[] __initdata = { { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE } diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c index 152527bb2872..d49e58acb03b 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -46,12 +46,12 @@ #include #include -#include +#include -#include -#include +#include +#include -#include +#include static struct map_desc smdk2410_iodesc[] __initdata = { /* nothing here yet */ diff --git a/trunk/arch/arm/mach-s3c2410/mach-tct_hammer.c b/trunk/arch/arm/mach-s3c2410/mach-tct_hammer.c index 309dcf4c870a..cc2e79fe4f9f 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-tct_hammer.c +++ b/trunk/arch/arm/mach-s3c2410/mach-tct_hammer.c @@ -44,9 +44,9 @@ #include #include -#include -#include -#include +#include +#include +#include #ifdef CONFIG_MTD_PARTITIONS diff --git a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c index 941353af16dc..ed3acb05c855 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c @@ -40,13 +40,13 @@ #include #include -#include +#include #include #include -#include -#include -#include +#include +#include +#include #include "usb-simtec.h" #include "nor-simtec.h" diff --git a/trunk/arch/arm/mach-s3c2410/pm.c b/trunk/arch/arm/mach-s3c2410/pm.c index a6970f613192..733f8a227775 100644 --- a/trunk/arch/arm/mach-s3c2410/pm.c +++ b/trunk/arch/arm/mach-s3c2410/pm.c @@ -34,8 +34,8 @@ #include #include -#include -#include +#include +#include #ifdef CONFIG_S3C2410_PM_DEBUG extern void pm_dbg(const char *fmt, ...); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410.c b/trunk/arch/arm/mach-s3c2410/s3c2410.c index ac79b536c4c3..b1e658c917a0 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.c @@ -29,12 +29,12 @@ #include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include /* Initial IO mappings */ diff --git a/trunk/arch/arm/mach-s3c2410/sleep.S b/trunk/arch/arm/mach-s3c2410/sleep.S index dd5b6388a5a5..be37f221a177 100644 --- a/trunk/arch/arm/mach-s3c2410/sleep.S +++ b/trunk/arch/arm/mach-s3c2410/sleep.S @@ -32,7 +32,7 @@ #include #include #include -#include +#include /* s3c2410_cpu_suspend * diff --git a/trunk/arch/arm/mach-s3c2410/usb-simtec.c b/trunk/arch/arm/mach-s3c2410/usb-simtec.c index 6078f09b7df5..eb6fc0bfd47e 100644 --- a/trunk/arch/arm/mach-s3c2410/usb-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/usb-simtec.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include "usb-simtec.h" /* control power and monitor over-current events on various Simtec diff --git a/trunk/arch/arm/mach-s3c2412/clock.c b/trunk/arch/arm/mach-s3c2412/clock.c index 96d9eb15424f..5fbaac6054f8 100644 --- a/trunk/arch/arm/mach-s3c2412/clock.c +++ b/trunk/arch/arm/mach-s3c2412/clock.c @@ -37,13 +37,13 @@ #include -#include +#include #include #include -#include -#include -#include +#include +#include +#include /* We currently have to assume that the system is running * from the XTPll input, and that all ***REFCLKs are being diff --git a/trunk/arch/arm/mach-s3c2412/dma.c b/trunk/arch/arm/mach-s3c2412/dma.c index ba0591e71f32..dcfff6b8b958 100644 --- a/trunk/arch/arm/mach-s3c2412/dma.c +++ b/trunk/arch/arm/mach-s3c2412/dma.c @@ -21,10 +21,10 @@ #include #include -#include -#include +#include +#include -#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-s3c2412/irq.c b/trunk/arch/arm/mach-s3c2412/irq.c index 6000ca9d1815..41720f2c1fea 100644 --- a/trunk/arch/arm/mach-s3c2412/irq.c +++ b/trunk/arch/arm/mach-s3c2412/irq.c @@ -35,9 +35,9 @@ #include #include -#include -#include -#include +#include +#include +#include #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) #define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0)))) diff --git a/trunk/arch/arm/mach-s3c2412/mach-jive.c b/trunk/arch/arm/mach-s3c2412/mach-jive.c index b08f18c8c47a..ad980a1690c2 100644 --- a/trunk/arch/arm/mach-s3c2412/mach-jive.c +++ b/trunk/arch/arm/mach-s3c2412/mach-jive.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -48,10 +48,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include static struct map_desc jive_iodesc[] __initdata = { diff --git a/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c b/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c index c719b5a740a9..8f8d9117b968 100644 --- a/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -32,7 +32,7 @@ #include //#include -#include +#include #include #include @@ -40,13 +40,13 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include +#include static struct map_desc smdk2413_iodesc[] __initdata = { }; diff --git a/trunk/arch/arm/mach-s3c2412/mach-vstms.c b/trunk/arch/arm/mach-s3c2412/mach-vstms.c index 4cfa19ad9be0..bb9bf63b2e02 100644 --- a/trunk/arch/arm/mach-s3c2412/mach-vstms.c +++ b/trunk/arch/arm/mach-s3c2412/mach-vstms.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include @@ -41,11 +41,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include static struct map_desc vstms_iodesc[] __initdata = { diff --git a/trunk/arch/arm/mach-s3c2412/pm.c b/trunk/arch/arm/mach-s3c2412/pm.c index 217e9e4ed45f..9540ef752f73 100644 --- a/trunk/arch/arm/mach-s3c2412/pm.c +++ b/trunk/arch/arm/mach-s3c2412/pm.c @@ -28,10 +28,10 @@ #include #include -#include -#include +#include +#include -#include +#include extern void s3c2412_sleep_enter(void); diff --git a/trunk/arch/arm/mach-s3c2412/s3c2412.c b/trunk/arch/arm/mach-s3c2412/s3c2412.c index 313759c3da69..42440fc55681 100644 --- a/trunk/arch/arm/mach-s3c2412/s3c2412.c +++ b/trunk/arch/arm/mach-s3c2412/s3c2412.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include #include @@ -42,11 +42,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #ifndef CONFIG_CPU_S3C2412_ONLY void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; diff --git a/trunk/arch/arm/mach-s3c2440/clock.c b/trunk/arch/arm/mach-s3c2440/clock.c index d1c29b2537cd..40503a65bacf 100644 --- a/trunk/arch/arm/mach-s3c2440/clock.c +++ b/trunk/arch/arm/mach-s3c2440/clock.c @@ -41,8 +41,8 @@ #include -#include -#include +#include +#include /* S3C2440 extended clock support */ diff --git a/trunk/arch/arm/mach-s3c2440/dma.c b/trunk/arch/arm/mach-s3c2440/dma.c index 32303f6a8321..cdd4e6e79ac0 100644 --- a/trunk/arch/arm/mach-s3c2440/dma.c +++ b/trunk/arch/arm/mach-s3c2440/dma.c @@ -20,10 +20,10 @@ #include #include -#include -#include +#include +#include -#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-s3c2440/dsc.c b/trunk/arch/arm/mach-s3c2440/dsc.c index 554044272771..4f7d06baf0d3 100644 --- a/trunk/arch/arm/mach-s3c2440/dsc.c +++ b/trunk/arch/arm/mach-s3c2440/dsc.c @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include int s3c2440_set_dsc(unsigned int pin, unsigned int value) { diff --git a/trunk/arch/arm/mach-s3c2440/irq.c b/trunk/arch/arm/mach-s3c2440/irq.c index 63c5ab65727f..33e3ede0a2b3 100644 --- a/trunk/arch/arm/mach-s3c2440/irq.c +++ b/trunk/arch/arm/mach-s3c2440/irq.c @@ -34,9 +34,9 @@ #include #include -#include -#include -#include +#include +#include +#include /* WDT/AC97 */ diff --git a/trunk/arch/arm/mach-s3c2440/mach-anubis.c b/trunk/arch/arm/mach-s3c2440/mach-anubis.c index e2beca470484..19eb0e5269ac 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-anubis.c +++ b/trunk/arch/arm/mach-s3c2440/mach-anubis.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include @@ -48,9 +48,9 @@ #include -#include -#include -#include +#include +#include +#include #define COPYRIGHT ", (c) 2005 Simtec Electronics" diff --git a/trunk/arch/arm/mach-s3c2440/mach-at2440evb.c b/trunk/arch/arm/mach-s3c2440/mach-at2440evb.c index 66876c6f2f1c..f0f0cc6afcf4 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/trunk/arch/arm/mach-s3c2440/mach-at2440evb.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include @@ -42,9 +42,9 @@ #include #include -#include -#include -#include +#include +#include +#include static struct map_desc at2440evb_iodesc[] __initdata = { /* Nothing here */ diff --git a/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c b/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c index a546307fd53d..49e828d1d4d8 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c @@ -36,13 +36,13 @@ //#include #include -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include static struct map_desc nexcoder_iodesc[] __initdata = { /* nothing here yet */ diff --git a/trunk/arch/arm/mach-s3c2440/mach-osiris.c b/trunk/arch/arm/mach-s3c2440/mach-osiris.c index 2361d606abc5..85144aa52c27 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-osiris.c +++ b/trunk/arch/arm/mach-s3c2440/mach-osiris.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include #include @@ -44,9 +44,9 @@ #include #include -#include -#include -#include +#include +#include +#include /* onboard perihperal map */ diff --git a/trunk/arch/arm/mach-s3c2440/mach-rx3715.c b/trunk/arch/arm/mach-s3c2440/mach-rx3715.c index 4d14c7cff892..a4c690456d19 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/trunk/arch/arm/mach-s3c2440/mach-rx3715.c @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include @@ -45,10 +45,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include static struct map_desc rx3715_iodesc[] __initdata = { /* dump ISA space somewhere unused */ diff --git a/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c b/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c index fefeaaa4155f..7ac60b869e7f 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -31,20 +31,20 @@ #include #include -#include +#include #include #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include +#include static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ diff --git a/trunk/arch/arm/mach-s3c2440/s3c2440.c b/trunk/arch/arm/mach-s3c2440/s3c2440.c index ac1f7ea5f405..c81cdb330712 100644 --- a/trunk/arch/arm/mach-s3c2440/s3c2440.c +++ b/trunk/arch/arm/mach-s3c2440/s3c2440.c @@ -29,9 +29,9 @@ #include #include -#include -#include -#include +#include +#include +#include static struct sys_device s3c2440_sysdev = { .cls = &s3c2440_sysclass, diff --git a/trunk/arch/arm/mach-s3c2442/clock.c b/trunk/arch/arm/mach-s3c2442/clock.c index ea1aa1f5157a..18f2ce4d7b23 100644 --- a/trunk/arch/arm/mach-s3c2442/clock.c +++ b/trunk/arch/arm/mach-s3c2442/clock.c @@ -41,8 +41,8 @@ #include -#include -#include +#include +#include /* S3C2442 extended clock support */ diff --git a/trunk/arch/arm/mach-s3c2442/s3c2442.c b/trunk/arch/arm/mach-s3c2442/s3c2442.c index 4663bdc7fff6..fbf8264249da 100644 --- a/trunk/arch/arm/mach-s3c2442/s3c2442.c +++ b/trunk/arch/arm/mach-s3c2442/s3c2442.c @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include static struct sys_device s3c2442_sysdev = { .cls = &s3c2442_sysclass, diff --git a/trunk/arch/arm/mach-s3c2443/clock.c b/trunk/arch/arm/mach-s3c2443/clock.c index 2f60bf6b8d43..603b5ea1deab 100644 --- a/trunk/arch/arm/mach-s3c2443/clock.c +++ b/trunk/arch/arm/mach-s3c2443/clock.c @@ -39,9 +39,9 @@ #include -#include -#include -#include +#include +#include +#include /* We currently have to assume that the system is running * from the XTPll input, and that all ***REFCLKs are being diff --git a/trunk/arch/arm/mach-s3c2443/dma.c b/trunk/arch/arm/mach-s3c2443/dma.c index f73ccb25ff94..5d9ee772659b 100644 --- a/trunk/arch/arm/mach-s3c2443/dma.c +++ b/trunk/arch/arm/mach-s3c2443/dma.c @@ -21,10 +21,10 @@ #include #include -#include -#include +#include +#include -#include +#include #include #include #include diff --git a/trunk/arch/arm/mach-s3c2443/irq.c b/trunk/arch/arm/mach-s3c2443/irq.c index 0e0d693f3974..e44341d7dfef 100644 --- a/trunk/arch/arm/mach-s3c2443/irq.c +++ b/trunk/arch/arm/mach-s3c2443/irq.c @@ -34,9 +34,9 @@ #include #include -#include -#include -#include +#include +#include +#include #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) diff --git a/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c b/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c index a7fe65f3dcc1..f0d119dc0409 100644 --- a/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c @@ -31,20 +31,20 @@ #include #include -#include +#include #include #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include +#include static struct map_desc smdk2443_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ diff --git a/trunk/arch/arm/mach-s3c2443/s3c2443.c b/trunk/arch/arm/mach-s3c2443/s3c2443.c index bbeddf9ddcb1..c973b68cc735 100644 --- a/trunk/arch/arm/mach-s3c2443/s3c2443.c +++ b/trunk/arch/arm/mach-s3c2443/s3c2443.c @@ -32,9 +32,9 @@ #include #include -#include -#include -#include +#include +#include +#include static struct map_desc s3c2443_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), diff --git a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c index 244d5956312c..f7fa03478efd 100644 --- a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c @@ -224,6 +224,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; policy->cur = policy->min = policy->max = sa11x0_getspeed(0); + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = 59000; policy->cpuinfo.max_freq = 287000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index d1193884d76d..330814d1ee25 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -428,7 +428,7 @@ config CPU_32v6K # ARMv7 config CPU_V7 bool "Support ARM V7 processor" - depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3 + depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB select CPU_32v6K select CPU_32v7 select CPU_ABRT_EV7 diff --git a/trunk/arch/arm/plat-omap/Kconfig b/trunk/arch/arm/plat-omap/Kconfig index a94f0c44ebc8..b917206ee906 100644 --- a/trunk/arch/arm/plat-omap/Kconfig +++ b/trunk/arch/arm/plat-omap/Kconfig @@ -15,9 +15,6 @@ config ARCH_OMAP1 config ARCH_OMAP2 bool "TI OMAP2" -config ARCH_OMAP3 - bool "TI OMAP3" - endchoice comment "OMAP Feature Selections" @@ -32,30 +29,6 @@ config OMAP_DEBUG_LEDS depends on OMAP_DEBUG_DEVICES default y if LEDS || LEDS_OMAP_DEBUG -config OMAP_DEBUG_POWERDOMAIN - bool "Emit debug messages from powerdomain layer" - depends on ARCH_OMAP2 || ARCH_OMAP3 - default n - help - Say Y here if you want to compile in powerdomain layer - debugging messages for OMAP2/3. These messages can - provide more detail as to why some powerdomain calls - may be failing, and will also emit a descriptive message - for every powerdomain register write. However, the - extra detail costs some memory. - -config OMAP_DEBUG_CLOCKDOMAIN - bool "Emit debug messages from clockdomain layer" - depends on ARCH_OMAP2 || ARCH_OMAP3 - default n - help - Say Y here if you want to compile in clockdomain layer - debugging messages for OMAP2/3. These messages can - provide more detail as to why some clockdomain calls - may be failing, and will also emit a descriptive message - for every clockdomain register write. However, the - extra detail costs some memory. - config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAP @@ -115,13 +88,13 @@ config OMAP_MPU_TIMER config OMAP_32K_TIMER bool "Use 32KHz timer" - depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX + depends on ARCH_OMAP16XX || ARCH_OMAP24XX help Select this option if you want to enable the OMAP 32KHz timer. This timer saves power compared to the OMAP_MPU_TIMER, and has support for no tick during idle. The 32KHz timer provides less intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is - currently only available for OMAP16XX, 24XX and 34XX. + currently only available for OMAP16XX and 24XX. endchoice @@ -136,7 +109,7 @@ config OMAP_32K_TIMER_HZ config OMAP_DM_TIMER bool "Use dual-mode timer" - depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX + depends on ARCH_OMAP16XX || ARCH_OMAP24XX help Select this option if you want to use OMAP Dual-Mode timers. diff --git a/trunk/arch/arm/plat-omap/Makefile b/trunk/arch/arm/plat-omap/Makefile index deaff58878a2..2c4051cc79a1 100644 --- a/trunk/arch/arm/plat-omap/Makefile +++ b/trunk/arch/arm/plat-omap/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \ - usb.o fb.o io.o + usb.o fb.o obj-m := obj-n := obj- := diff --git a/trunk/arch/arm/plat-omap/common.c b/trunk/arch/arm/plat-omap/common.c index 0843b8882f93..8bdf0ead0cf3 100644 --- a/trunk/arch/arm/plat-omap/common.c +++ b/trunk/arch/arm/plat-omap/common.c @@ -248,7 +248,6 @@ static struct omap_globals *omap2_globals; static void __init __omap2_set_globals(void) { - omap2_set_globals_tap(omap2_globals); omap2_set_globals_memory(omap2_globals); omap2_set_globals_control(omap2_globals); omap2_set_globals_prcm(omap2_globals); @@ -259,13 +258,12 @@ static void __init __omap2_set_globals(void) #if defined(CONFIG_ARCH_OMAP2420) static struct omap_globals omap242x_globals = { - .class = OMAP242X_CLASS, - .tap = OMAP2_IO_ADDRESS(0x48014000), - .sdrc = OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE), - .sms = OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE), - .ctrl = OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE), - .prm = OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE), - .cm = OMAP2_IO_ADDRESS(OMAP2420_CM_BASE), + .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x48014000), + .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE), + .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE), + .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE), + .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE), + .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CM_BASE), }; void __init omap2_set_globals_242x(void) @@ -278,13 +276,12 @@ void __init omap2_set_globals_242x(void) #if defined(CONFIG_ARCH_OMAP2430) static struct omap_globals omap243x_globals = { - .class = OMAP243X_CLASS, - .tap = OMAP2_IO_ADDRESS(0x4900a000), - .sdrc = OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE), - .sms = OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE), - .ctrl = OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE), - .prm = OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE), - .cm = OMAP2_IO_ADDRESS(OMAP2430_CM_BASE), + .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4900a000), + .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE), + .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE), + .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE), + .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE), + .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_CM_BASE), }; void __init omap2_set_globals_243x(void) @@ -297,13 +294,12 @@ void __init omap2_set_globals_243x(void) #if defined(CONFIG_ARCH_OMAP3430) static struct omap_globals omap343x_globals = { - .class = OMAP343X_CLASS, - .tap = OMAP2_IO_ADDRESS(0x4830A000), - .sdrc = OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE), - .sms = OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE), - .ctrl = OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE), - .prm = OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE), - .cm = OMAP2_IO_ADDRESS(OMAP3430_CM_BASE), + .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4830A000), + .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE), + .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE), + .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE), + .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE), + .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_CM_BASE), }; void __init omap2_set_globals_343x(void) diff --git a/trunk/arch/arm/plat-omap/devices.c b/trunk/arch/arm/plat-omap/devices.c index 0cb2b22388e9..97187fa0ae52 100644 --- a/trunk/arch/arm/plat-omap/devices.c +++ b/trunk/arch/arm/plat-omap/devices.c @@ -20,17 +20,17 @@ #include #include -#include #include #include #include #include #include #include -#include #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) +#include "../plat-omap/dsp/dsp_common.h" + static struct dsp_platform_data dsp_pdata = { .kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list), }; @@ -76,7 +76,7 @@ int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev) { static DEFINE_MUTEX(dsp_pdata_lock); - spin_lock_init(&kdev->lock); + mutex_init(&kdev->lock); mutex_lock(&dsp_pdata_lock); list_add_tail(&kdev->entry, &dsp_pdata.kdev_list); @@ -95,10 +95,6 @@ static inline void omap_init_dsp(void) { } static void omap_init_kp(void) { - /* 2430 and 34xx keypad is on TWL4030 */ - if (cpu_is_omap2430() || cpu_is_omap34xx()) - return; - if (machine_is_omap_h2() || machine_is_omap_h3()) { omap_cfg_reg(F18_1610_KBC0); omap_cfg_reg(D20_1610_KBC1); @@ -160,6 +156,13 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, { int i; + if (size > OMAP_MAX_MCBSP_COUNT) { + printk(KERN_WARNING "Registered too many McBSPs platform_data." + " Using maximum (%d) available.\n", + OMAP_MAX_MCBSP_COUNT); + size = OMAP_MAX_MCBSP_COUNT; + } + omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *), GFP_KERNEL); if (!omap_mcbsp_devices) { @@ -527,6 +530,10 @@ static inline void omap_init_rng(void) {} */ static int __init omap_init_devices(void) { +/* + * Need to enable relevant once for 2430 SDP + */ +#ifndef CONFIG_MACH_OMAP_2430SDP /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ @@ -536,6 +543,7 @@ static int __init omap_init_devices(void) omap_init_uwire(); omap_init_wdt(); omap_init_rng(); +#endif return 0; } arch_initcall(omap_init_devices); diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index 50f8b4ad9a09..a63b644ad305 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -1233,7 +1233,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, /* request and reserve DMA channels for the chain */ for (i = 0; i < no_of_chans; i++) { err = omap_request_dma(dev_id, dev_name, - callback, NULL, &channels[i]); + callback, 0, &channels[i]); if (err < 0) { int j; for (j = 0; j < i; j++) @@ -2297,13 +2297,13 @@ static int __init omap_init_dma(void) int ch, r; if (cpu_class_is_omap1()) { - omap_dma_base = IO_ADDRESS(OMAP1_DMA_BASE); + omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP1_DMA_BASE); dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; } else if (cpu_is_omap24xx()) { - omap_dma_base = IO_ADDRESS(OMAP24XX_DMA4_BASE); + omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP24XX_DMA4_BASE); dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; } else if (cpu_is_omap34xx()) { - omap_dma_base = IO_ADDRESS(OMAP34XX_DMA4_BASE); + omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP34XX_DMA4_BASE); dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; } else { pr_err("DMA init failed for unsupported omap\n"); diff --git a/trunk/arch/arm/plat-omap/dmtimer.c b/trunk/arch/arm/plat-omap/dmtimer.c index 963c31cd1541..606fcffdcefc 100644 --- a/trunk/arch/arm/plat-omap/dmtimer.c +++ b/trunk/arch/arm/plat-omap/dmtimer.c @@ -693,7 +693,7 @@ int __init omap_dm_timer_init(void) for (i = 0; i < dm_timer_count; i++) { timer = &dm_timers[i]; - timer->io_base = IO_ADDRESS(timer->phys_base); + timer->io_base = (void __iomem *)io_p2v(timer->phys_base); #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) if (cpu_class_is_omap2()) { char clk_name[16]; diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 8679fbca6bbe..5935ae4e550b 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -28,7 +28,7 @@ /* * OMAP1510 GPIO registers */ -#define OMAP1510_GPIO_BASE IO_ADDRESS(0xfffce000) +#define OMAP1510_GPIO_BASE (void __iomem *)0xfffce000 #define OMAP1510_GPIO_DATA_INPUT 0x00 #define OMAP1510_GPIO_DATA_OUTPUT 0x04 #define OMAP1510_GPIO_DIR_CONTROL 0x08 @@ -42,10 +42,10 @@ /* * OMAP1610 specific GPIO registers */ -#define OMAP1610_GPIO1_BASE IO_ADDRESS(0xfffbe400) -#define OMAP1610_GPIO2_BASE IO_ADDRESS(0xfffbec00) -#define OMAP1610_GPIO3_BASE IO_ADDRESS(0xfffbb400) -#define OMAP1610_GPIO4_BASE IO_ADDRESS(0xfffbbc00) +#define OMAP1610_GPIO1_BASE (void __iomem *)0xfffbe400 +#define OMAP1610_GPIO2_BASE (void __iomem *)0xfffbec00 +#define OMAP1610_GPIO3_BASE (void __iomem *)0xfffbb400 +#define OMAP1610_GPIO4_BASE (void __iomem *)0xfffbbc00 #define OMAP1610_GPIO_REVISION 0x0000 #define OMAP1610_GPIO_SYSCONFIG 0x0010 #define OMAP1610_GPIO_SYSSTATUS 0x0014 @@ -67,12 +67,12 @@ /* * OMAP730 specific GPIO registers */ -#define OMAP730_GPIO1_BASE IO_ADDRESS(0xfffbc000) -#define OMAP730_GPIO2_BASE IO_ADDRESS(0xfffbc800) -#define OMAP730_GPIO3_BASE IO_ADDRESS(0xfffbd000) -#define OMAP730_GPIO4_BASE IO_ADDRESS(0xfffbd800) -#define OMAP730_GPIO5_BASE IO_ADDRESS(0xfffbe000) -#define OMAP730_GPIO6_BASE IO_ADDRESS(0xfffbe800) +#define OMAP730_GPIO1_BASE (void __iomem *)0xfffbc000 +#define OMAP730_GPIO2_BASE (void __iomem *)0xfffbc800 +#define OMAP730_GPIO3_BASE (void __iomem *)0xfffbd000 +#define OMAP730_GPIO4_BASE (void __iomem *)0xfffbd800 +#define OMAP730_GPIO5_BASE (void __iomem *)0xfffbe000 +#define OMAP730_GPIO6_BASE (void __iomem *)0xfffbe800 #define OMAP730_GPIO_DATA_INPUT 0x00 #define OMAP730_GPIO_DATA_OUTPUT 0x04 #define OMAP730_GPIO_DIR_CONTROL 0x08 @@ -83,16 +83,16 @@ /* * omap24xx specific GPIO registers */ -#define OMAP242X_GPIO1_BASE IO_ADDRESS(0x48018000) -#define OMAP242X_GPIO2_BASE IO_ADDRESS(0x4801a000) -#define OMAP242X_GPIO3_BASE IO_ADDRESS(0x4801c000) -#define OMAP242X_GPIO4_BASE IO_ADDRESS(0x4801e000) +#define OMAP242X_GPIO1_BASE (void __iomem *)0x48018000 +#define OMAP242X_GPIO2_BASE (void __iomem *)0x4801a000 +#define OMAP242X_GPIO3_BASE (void __iomem *)0x4801c000 +#define OMAP242X_GPIO4_BASE (void __iomem *)0x4801e000 -#define OMAP243X_GPIO1_BASE IO_ADDRESS(0x4900C000) -#define OMAP243X_GPIO2_BASE IO_ADDRESS(0x4900E000) -#define OMAP243X_GPIO3_BASE IO_ADDRESS(0x49010000) -#define OMAP243X_GPIO4_BASE IO_ADDRESS(0x49012000) -#define OMAP243X_GPIO5_BASE IO_ADDRESS(0x480B6000) +#define OMAP243X_GPIO1_BASE (void __iomem *)0x4900C000 +#define OMAP243X_GPIO2_BASE (void __iomem *)0x4900E000 +#define OMAP243X_GPIO3_BASE (void __iomem *)0x49010000 +#define OMAP243X_GPIO4_BASE (void __iomem *)0x49012000 +#define OMAP243X_GPIO5_BASE (void __iomem *)0x480B6000 #define OMAP24XX_GPIO_REVISION 0x0000 #define OMAP24XX_GPIO_SYSCONFIG 0x0010 @@ -122,14 +122,13 @@ * omap34xx specific GPIO registers */ -#define OMAP34XX_GPIO1_BASE IO_ADDRESS(0x48310000) -#define OMAP34XX_GPIO2_BASE IO_ADDRESS(0x49050000) -#define OMAP34XX_GPIO3_BASE IO_ADDRESS(0x49052000) -#define OMAP34XX_GPIO4_BASE IO_ADDRESS(0x49054000) -#define OMAP34XX_GPIO5_BASE IO_ADDRESS(0x49056000) -#define OMAP34XX_GPIO6_BASE IO_ADDRESS(0x49058000) +#define OMAP34XX_GPIO1_BASE (void __iomem *)0x48310000 +#define OMAP34XX_GPIO2_BASE (void __iomem *)0x49050000 +#define OMAP34XX_GPIO3_BASE (void __iomem *)0x49052000 +#define OMAP34XX_GPIO4_BASE (void __iomem *)0x49054000 +#define OMAP34XX_GPIO5_BASE (void __iomem *)0x49056000 +#define OMAP34XX_GPIO6_BASE (void __iomem *)0x49058000 -#define OMAP_MPUIO_VBASE IO_ADDRESS(OMAP_MPUIO_BASE) struct gpio_bank { void __iomem *base; @@ -161,7 +160,7 @@ struct gpio_bank { #ifdef CONFIG_ARCH_OMAP16XX static struct gpio_bank gpio_bank_1610[5] = { - { OMAP_MPUIO_VBASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO}, + { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO}, { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 }, { OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 }, { OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 }, @@ -171,14 +170,14 @@ static struct gpio_bank gpio_bank_1610[5] = { #ifdef CONFIG_ARCH_OMAP15XX static struct gpio_bank gpio_bank_1510[2] = { - { OMAP_MPUIO_VBASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, + { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 } }; #endif #ifdef CONFIG_ARCH_OMAP730 static struct gpio_bank gpio_bank_730[7] = { - { OMAP_MPUIO_VBASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, + { OMAP_MPUIO_BASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, { OMAP730_GPIO1_BASE, INT_730_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_730 }, { OMAP730_GPIO2_BASE, INT_730_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_730 }, { OMAP730_GPIO3_BASE, INT_730_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_730 }, @@ -1390,7 +1389,7 @@ static int __init _omap_gpio_init(void) gpio_bank_count = 5; gpio_bank = gpio_bank_1610; - rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION); + rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION); printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n", (rev >> 4) & 0x0f, rev & 0x0f); } @@ -1409,7 +1408,7 @@ static int __init _omap_gpio_init(void) gpio_bank_count = 4; gpio_bank = gpio_bank_242x; - rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); + rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n", (rev >> 4) & 0x0f, rev & 0x0f); } @@ -1418,7 +1417,7 @@ static int __init _omap_gpio_init(void) gpio_bank_count = 5; gpio_bank = gpio_bank_243x; - rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); + rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n", (rev >> 4) & 0x0f, rev & 0x0f); } @@ -1429,7 +1428,7 @@ static int __init _omap_gpio_init(void) gpio_bank_count = OMAP34XX_NR_GPIOS; gpio_bank = gpio_bank_34xx; - rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); + rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); printk(KERN_INFO "OMAP34xx GPIO hardware version %d.%d\n", (rev >> 4) & 0x0f, rev & 0x0f); } @@ -1438,9 +1437,10 @@ static int __init _omap_gpio_init(void) int j, gpio_count = 16; bank = &gpio_bank[i]; + bank->base = IO_ADDRESS(bank->base); spin_lock_init(&bank->lock); if (bank_is_mpuio(bank)) - __raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT); + omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) { __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); diff --git a/trunk/arch/arm/plat-omap/include/mach/board-2430sdp.h b/trunk/arch/arm/plat-omap/include/mach/board-2430sdp.h index 10d449ea7ed0..cf1dc0223949 100644 --- a/trunk/arch/arm/plat-omap/include/mach/board-2430sdp.h +++ b/trunk/arch/arm/plat-omap/include/mach/board-2430sdp.h @@ -30,12 +30,10 @@ #define __ASM_ARCH_OMAP_2430SDP_H /* Placeholder for 2430SDP specific defines */ -#define OMAP24XX_ETHR_START 0x08000300 +#define OMAP24XX_ETHR_START 0x08000300 #define OMAP24XX_ETHR_GPIO_IRQ 149 #define SDP2430_CS0_BASE 0x04000000 -/* Function prototypes */ -extern void sdp2430_flash_init(void); -extern void sdp2430_usb_init(void); +#define TWL4030_IRQNUM INT_24XX_SYS_NIRQ #endif /* __ASM_ARCH_OMAP_2430SDP_H */ diff --git a/trunk/arch/arm/plat-omap/include/mach/board-apollon.h b/trunk/arch/arm/plat-omap/include/mach/board-apollon.h index 731c858cf3fe..d6f2a8e963d5 100644 --- a/trunk/arch/arm/plat-omap/include/mach/board-apollon.h +++ b/trunk/arch/arm/plat-omap/include/mach/board-apollon.h @@ -31,12 +31,6 @@ extern void apollon_mmc_init(void); -static inline int apollon_plus(void) -{ - /* The apollon plus has IDCODE revision 5 */ - return system_rev & 0xc0; -} - /* Placeholder for APOLLON specific defines */ #define APOLLON_ETHR_GPIO_IRQ 74 diff --git a/trunk/arch/arm/plat-omap/include/mach/board-h4.h b/trunk/arch/arm/plat-omap/include/mach/board-h4.h index 7c3fa0f0a65e..1470cd3e519b 100644 --- a/trunk/arch/arm/plat-omap/include/mach/board-h4.h +++ b/trunk/arch/arm/plat-omap/include/mach/board-h4.h @@ -1,7 +1,7 @@ /* * arch/arm/plat-omap/include/mach/board-h4.h * - * Hardware definitions for TI OMAP2420 H4 board. + * Hardware definitions for TI OMAP1610 H4 board. * * Initial creation by Dirk Behme * @@ -29,9 +29,6 @@ #ifndef __ASM_ARCH_OMAP_H4_H #define __ASM_ARCH_OMAP_H4_H -/* MMC Prototypes */ -extern void h4_mmc_init(void); - /* Placeholder for H4 specific defines */ #define OMAP24XX_ETHR_GPIO_IRQ 92 #endif /* __ASM_ARCH_OMAP_H4_H */ diff --git a/trunk/arch/arm/plat-omap/include/mach/board-ldp.h b/trunk/arch/arm/plat-omap/include/mach/board-ldp.h deleted file mode 100644 index 66e2746c04ca..000000000000 --- a/trunk/arch/arm/plat-omap/include/mach/board-ldp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/board-ldp.h - * - * Hardware definitions for TI OMAP3 LDP. - * - * Copyright (C) 2008 Texas Instruments 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 - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_OMAP_LDP_H -#define __ASM_ARCH_OMAP_LDP_H - -extern void twl4030_bci_battery_init(void); - -#define TWL4030_IRQNUM INT_34XX_SYS_NIRQ - -#endif /* __ASM_ARCH_OMAP_LDP_H */ diff --git a/trunk/arch/arm/plat-omap/include/mach/board-omap3beagle.h b/trunk/arch/arm/plat-omap/include/mach/board-omap3beagle.h deleted file mode 100644 index 3080d52d877a..000000000000 --- a/trunk/arch/arm/plat-omap/include/mach/board-omap3beagle.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/board-omap3beagle.h - * - * Hardware definitions for TI OMAP3 BEAGLE. - * - * Initial creation by Syed Mohammed Khasim - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_OMAP3_BEAGLE_H -#define __ASM_ARCH_OMAP3_BEAGLE_H - -#endif /* __ASM_ARCH_OMAP3_BEAGLE_H */ - diff --git a/trunk/arch/arm/plat-omap/include/mach/board-overo.h b/trunk/arch/arm/plat-omap/include/mach/board-overo.h deleted file mode 100644 index 7ecae66966d1..000000000000 --- a/trunk/arch/arm/plat-omap/include/mach/board-overo.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * board-overo.h (Gumstix Overo) - * - * Initial code: Steve Sakoman - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_OVERO_H -#define __ASM_ARCH_OVERO_H - -#define OVERO_GPIO_BT_XGATE 15 -#define OVERO_GPIO_W2W_NRESET 16 -#define OVERO_GPIO_BT_NRESET 164 -#define OVERO_GPIO_USBH_CPEN 168 -#define OVERO_GPIO_USBH_NRESET 183 - -#endif /* ____ASM_ARCH_OVERO_H */ - diff --git a/trunk/arch/arm/plat-omap/include/mach/board.h b/trunk/arch/arm/plat-omap/include/mach/board.h index c23c12ccb353..54445642f35d 100644 --- a/trunk/arch/arm/plat-omap/include/mach/board.h +++ b/trunk/arch/arm/plat-omap/include/mach/board.h @@ -45,8 +45,6 @@ struct omap_mmc_conf { unsigned cover:1; /* 4 wire signaling is optional, and is only used for SD/SDIO */ unsigned wire4:1; - /* use the internal clock */ - unsigned internal_clock:1; s16 power_pin; s16 switch_pin; s16 wp_pin; diff --git a/trunk/arch/arm/plat-omap/include/mach/clock.h b/trunk/arch/arm/plat-omap/include/mach/clock.h index 719298554ed7..92f7c7238fcd 100644 --- a/trunk/arch/arm/plat-omap/include/mach/clock.h +++ b/trunk/arch/arm/plat-omap/include/mach/clock.h @@ -15,7 +15,6 @@ struct module; struct clk; -struct clockdomain; #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) @@ -80,8 +79,6 @@ struct clk { u32 clksel_mask; const struct clksel *clksel; struct dpll_data *dpll_data; - const char *clkdm_name; - struct clockdomain *clkdm; #else __u8 rate_offset; __u8 src_offset; diff --git a/trunk/arch/arm/plat-omap/include/mach/clockdomain.h b/trunk/arch/arm/plat-omap/include/mach/clockdomain.h deleted file mode 100644 index 1f51f0173784..000000000000 --- a/trunk/arch/arm/plat-omap/include/mach/clockdomain.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * linux/include/asm-arm/arch-omap/clockdomain.h - * - * OMAP2/3 clockdomain framework functions - * - * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008 Nokia Corporation - * - * Written by Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H -#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H - -#include -#include -#include - -/* Clockdomain capability flags */ -#define CLKDM_CAN_FORCE_SLEEP (1 << 0) -#define CLKDM_CAN_FORCE_WAKEUP (1 << 1) -#define CLKDM_CAN_ENABLE_AUTO (1 << 2) -#define CLKDM_CAN_DISABLE_AUTO (1 << 3) - -#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) -#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) -#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP) - -/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */ -#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0 -#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1 - -/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */ -#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0 -#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1 -#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2 -#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3 - -/* - * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps - * and sleepdeps added when a powerdomain should stay active in hwsup mode; - * and conversely, removed when the powerdomain should be allowed to go - * inactive in hwsup mode. - */ -struct clkdm_pwrdm_autodep { - - /* Name of the powerdomain to add a wkdep/sleepdep on */ - const char *pwrdm_name; - - /* Powerdomain pointer (looked up at clkdm_init() time) */ - struct powerdomain *pwrdm; - - /* OMAP chip types that this clockdomain dep is valid on */ - const struct omap_chip_id omap_chip; - -}; - -struct clockdomain { - - /* Clockdomain name */ - const char *name; - - /* Powerdomain enclosing this clockdomain */ - const char *pwrdm_name; - - /* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */ - const u16 clktrctrl_mask; - - /* Clockdomain capability flags */ - const u8 flags; - - /* OMAP chip types that this clockdomain is valid on */ - const struct omap_chip_id omap_chip; - - /* Usecount tracking */ - atomic_t usecount; - - /* Powerdomain pointer assigned at clkdm_register() */ - struct powerdomain *pwrdm; - - struct list_head node; - -}; - -void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps); -int clkdm_register(struct clockdomain *clkdm); -int clkdm_unregister(struct clockdomain *clkdm); -struct clockdomain *clkdm_lookup(const char *name); - -int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)); -struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm); - -void omap2_clkdm_allow_idle(struct clockdomain *clkdm); -void omap2_clkdm_deny_idle(struct clockdomain *clkdm); - -int omap2_clkdm_wakeup(struct clockdomain *clkdm); -int omap2_clkdm_sleep(struct clockdomain *clkdm); - -int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); -int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); - -#endif diff --git a/trunk/arch/arm/plat-omap/include/mach/common.h b/trunk/arch/arm/plat-omap/include/mach/common.h index ef70e2b0f054..06093112b665 100644 --- a/trunk/arch/arm/plat-omap/include/mach/common.h +++ b/trunk/arch/arm/plat-omap/include/mach/common.h @@ -34,7 +34,6 @@ struct sys_timer; extern void omap_map_common_io(void); extern struct sys_timer omap_timer; extern void omap_serial_init(void); -extern void omap_serial_enable_clocks(int enable); #ifdef CONFIG_I2C_OMAP extern int omap_register_i2c_bus(int bus_id, u32 clkrate, struct i2c_board_info const *info, @@ -50,7 +49,6 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, /* IO bases for various OMAP processors */ struct omap_globals { - u32 class; /* OMAP class to detect */ void __iomem *tap; /* Control module ID code */ void __iomem *sdrc; /* SDRAM Controller */ void __iomem *sms; /* SDRAM Memory Scheduler */ @@ -64,7 +62,6 @@ void omap2_set_globals_243x(void); void omap2_set_globals_343x(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ -void omap2_set_globals_tap(struct omap_globals *); void omap2_set_globals_memory(struct omap_globals *); void omap2_set_globals_control(struct omap_globals *); void omap2_set_globals_prcm(struct omap_globals *); diff --git a/trunk/arch/arm/plat-omap/include/mach/control.h b/trunk/arch/arm/plat-omap/include/mach/control.h index dc9886760577..e3fd62d9a995 100644 --- a/trunk/arch/arm/plat-omap/include/mach/control.h +++ b/trunk/arch/arm/plat-omap/include/mach/control.h @@ -1,10 +1,13 @@ +#ifndef __ASM_ARCH_CONTROL_H +#define __ASM_ARCH_CONTROL_H + /* * arch/arm/plat-omap/include/mach/control.h * * OMAP2/3 System Control Module definitions * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation + * Copyright (C) 2007 Texas Instruments, Inc. + * Copyright (C) 2007 Nokia Corporation * * Written by Paul Walmsley * @@ -13,23 +16,14 @@ * the Free Software Foundation. */ -#ifndef __ASM_ARCH_CONTROL_H -#define __ASM_ARCH_CONTROL_H - #include -#ifndef __ASSEMBLY__ #define OMAP242X_CTRL_REGADDR(reg) \ - IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) + (void __iomem *)IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) #define OMAP243X_CTRL_REGADDR(reg) \ - IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) + (void __iomem *)IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) #define OMAP343X_CTRL_REGADDR(reg) \ - IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) -#else -#define OMAP242X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) -#define OMAP243X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) -#define OMAP343X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) -#endif /* __ASSEMBLY__ */ + (void __iomem *)IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) /* * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for @@ -140,7 +134,6 @@ #define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) -#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) /* * REVISIT: This list of registers is not comprehensive - there are more diff --git a/trunk/arch/arm/plat-omap/include/mach/cpu.h b/trunk/arch/arm/plat-omap/include/mach/cpu.h index e0464187209d..05aee0eda34f 100644 --- a/trunk/arch/arm/plat-omap/include/mach/cpu.h +++ b/trunk/arch/arm/plat-omap/include/mach/cpu.h @@ -346,14 +346,9 @@ IS_OMAP_TYPE(3430, 0x3430) get_sil_revision(system_rev) /* Various silicon macros defined here */ -#define OMAP242X_CLASS 0x24200000 #define OMAP2420_REV_ES1_0 0x24200000 #define OMAP2420_REV_ES2_0 0x24201000 - -#define OMAP243X_CLASS 0x24300000 #define OMAP2430_REV_ES1_0 0x24300000 - -#define OMAP343X_CLASS 0x34300000 #define OMAP3430_REV_ES1_0 0x34300000 #define OMAP3430_REV_ES2_0 0x34301000 #define OMAP3430_REV_ES2_1 0x34302000 diff --git a/trunk/arch/arm/plat-omap/include/mach/debug-macro.S b/trunk/arch/arm/plat-omap/include/mach/debug-macro.S index 1b11f5c6a2d9..1b0039bdeb4e 100644 --- a/trunk/arch/arm/plat-omap/include/mach/debug-macro.S +++ b/trunk/arch/arm/plat-omap/include/mach/debug-macro.S @@ -35,18 +35,6 @@ #ifdef CONFIG_OMAP_LL_DEBUG_UART3 add \rx, \rx, #0x00004000 @ UART 3 #endif - -#elif CONFIG_ARCH_OMAP3 - moveq \rx, #0x48000000 @ physical base address - movne \rx, #0xd8000000 @ virtual base - orr \rx, \rx, #0x0006a000 -#ifdef CONFIG_OMAP_LL_DEBUG_UART2 - add \rx, \rx, #0x00002000 @ UART 2 -#endif -#ifdef CONFIG_OMAP_LL_DEBUG_UART3 - add \rx, \rx, #0x00fb0000 @ UART 3 - add \rx, \rx, #0x00006000 -#endif #endif .endm diff --git a/trunk/arch/arm/plat-omap/include/mach/entry-macro.S b/trunk/arch/arm/plat-omap/include/mach/entry-macro.S index 030118ee204a..d4e9043bf201 100644 --- a/trunk/arch/arm/plat-omap/include/mach/entry-macro.S +++ b/trunk/arch/arm/plat-omap/include/mach/entry-macro.S @@ -55,17 +55,9 @@ 1510: .endm -#endif -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#elif defined(CONFIG_ARCH_OMAP24XX) -#if defined(CONFIG_ARCH_OMAP24XX) #include -#endif -#if defined(CONFIG_ARCH_OMAP34XX) -#include -#endif - -#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* Active interrupt number */ .macro disable_fiq .endm @@ -87,7 +79,7 @@ ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */ cmp \irqnr, #0x0 2222: - ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET] + ldrne \irqnr, [\base, #IRQ_SIR_IRQ] .endm diff --git a/trunk/arch/arm/plat-omap/include/mach/fpga.h b/trunk/arch/arm/plat-omap/include/mach/fpga.h index f1864a652f7a..c92e4b42b289 100644 --- a/trunk/arch/arm/plat-omap/include/mach/fpga.h +++ b/trunk/arch/arm/plat-omap/include/mach/fpga.h @@ -34,9 +34,9 @@ extern void omap1510_fpga_init_irq(void); * --------------------------------------------------------------------------- */ /* maps in the FPGA registers and the ETHR registers */ -#define H2P2_DBG_FPGA_BASE IOMEM(0xE8000000) /* VA */ -#define H2P2_DBG_FPGA_SIZE SZ_4K /* SIZE */ -#define H2P2_DBG_FPGA_START 0x04000000 /* PA */ +#define H2P2_DBG_FPGA_BASE 0xE8000000 /* VA */ +#define H2P2_DBG_FPGA_SIZE SZ_4K /* SIZE */ +#define H2P2_DBG_FPGA_START 0x04000000 /* PA */ #define H2P2_DBG_FPGA_ETHR_START (H2P2_DBG_FPGA_START + 0x300) #define H2P2_DBG_FPGA_FPGA_REV (H2P2_DBG_FPGA_BASE + 0x10) /* FPGA Revision */ @@ -85,9 +85,9 @@ struct h2p2_dbg_fpga { * OMAP-1510 FPGA * --------------------------------------------------------------------------- */ -#define OMAP1510_FPGA_BASE IOMEM(0xE8000000) /* VA */ -#define OMAP1510_FPGA_SIZE SZ_4K -#define OMAP1510_FPGA_START 0x08000000 /* PA */ +#define OMAP1510_FPGA_BASE 0xE8000000 /* Virtual */ +#define OMAP1510_FPGA_SIZE SZ_4K +#define OMAP1510_FPGA_START 0x08000000 /* Physical */ /* Revision */ #define OMAP1510_FPGA_REV_LOW (OMAP1510_FPGA_BASE + 0x0) diff --git a/trunk/arch/arm/plat-omap/include/mach/gpio.h b/trunk/arch/arm/plat-omap/include/mach/gpio.h index 98e9008b7e9d..8c71e288860f 100644 --- a/trunk/arch/arm/plat-omap/include/mach/gpio.h +++ b/trunk/arch/arm/plat-omap/include/mach/gpio.h @@ -29,7 +29,7 @@ #include #include -#define OMAP_MPUIO_BASE 0xfffb5000 +#define OMAP_MPUIO_BASE (void __iomem *)0xfffb5000 #ifdef CONFIG_ARCH_OMAP730 #define OMAP_MPUIO_INPUT_LATCH 0x00 @@ -76,8 +76,6 @@ extern void omap_free_gpio(int gpio); extern void omap_set_gpio_direction(int gpio, int is_input); extern void omap_set_gpio_dataout(int gpio, int enable); extern int omap_get_gpio_datain(int gpio); -extern void omap2_gpio_prepare_for_retention(void); -extern void omap2_gpio_resume_after_retention(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); diff --git a/trunk/arch/arm/plat-omap/include/mach/gpmc.h b/trunk/arch/arm/plat-omap/include/mach/gpmc.h index 45b678439bb7..6a8e07ffc2d0 100644 --- a/trunk/arch/arm/plat-omap/include/mach/gpmc.h +++ b/trunk/arch/arm/plat-omap/include/mach/gpmc.h @@ -11,9 +11,6 @@ #ifndef __OMAP2_GPMC_H #define __OMAP2_GPMC_H -/* Maximum Number of Chip Selects */ -#define GPMC_CS_NUM 8 - #define GPMC_CS_CONFIG1 0x00 #define GPMC_CS_CONFIG2 0x04 #define GPMC_CS_CONFIG3 0x08 @@ -25,9 +22,6 @@ #define GPMC_CS_NAND_ADDRESS 0x20 #define GPMC_CS_NAND_DATA 0x24 -#define GPMC_CONFIG 0x50 -#define GPMC_STATUS 0x54 - #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) #define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) @@ -84,14 +78,9 @@ struct gpmc_timings { u16 access; /* Start-cycle to first data valid delay */ u16 rd_cycle; /* Total read cycle time */ u16 wr_cycle; /* Total write cycle time */ - - /* The following are only on OMAP3430 */ - u16 wr_access; /* WRACCESSTIME */ - u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ }; extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); -extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns); extern unsigned long gpmc_get_fclk_period(void); @@ -103,6 +92,5 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); extern int gpmc_cs_set_reserved(int cs, int reserved); extern int gpmc_cs_reserved(int cs); -extern void gpmc_init(void); #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/hardware.h b/trunk/arch/arm/plat-omap/include/mach/hardware.h index 6589ddbb63b2..07f5d7f21528 100644 --- a/trunk/arch/arm/plat-omap/include/mach/hardware.h +++ b/trunk/arch/arm/plat-omap/include/mach/hardware.h @@ -89,7 +89,7 @@ #define DPLL_CTL (0xfffecf00) /* DSP clock control. Must use __raw_readw() and __raw_writew() with these */ -#define DSP_CONFIG_REG_BASE IOMEM(0xe1008000) +#define DSP_CONFIG_REG_BASE (0xe1008000) #define DSP_CKCTL (DSP_CONFIG_REG_BASE + 0x0) #define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4) #define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8) @@ -282,8 +282,8 @@ #include "omap730.h" #include "omap1510.h" -#include "omap16xx.h" #include "omap24xx.h" +#include "omap16xx.h" #include "omap34xx.h" #ifndef __ASSEMBLER__ @@ -322,14 +322,6 @@ #include "board-2430sdp.h" #endif -#ifdef CONFIG_MACH_OMAP3_BEAGLE -#include "board-omap3beagle.h" -#endif - -#ifdef CONFIG_MACH_OMAP_LDP -#include "board-ldp.h" -#endif - #ifdef CONFIG_MACH_OMAP_APOLLON #include "board-apollon.h" #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/io.h b/trunk/arch/arm/plat-omap/include/mach/io.h index adc83b7b8205..2a30b7d88cde 100644 --- a/trunk/arch/arm/plat-omap/include/mach/io.h +++ b/trunk/arch/arm/plat-omap/include/mach/io.h @@ -55,13 +55,14 @@ #if defined(CONFIG_ARCH_OMAP1) -#define IO_PHYS 0xFFFB0000 -#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */ -#define IO_SIZE 0x40000 -#define IO_VIRT (IO_PHYS - IO_OFFSET) -#define __IO_ADDRESS(pa) ((pa) - IO_OFFSET) -#define __OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET) -#define io_v2p(va) ((va) + IO_OFFSET) +#define IO_PHYS 0xFFFB0000 +#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */ +#define IO_SIZE 0x40000 +#define IO_VIRT (IO_PHYS - IO_OFFSET) +#define IO_ADDRESS(pa) ((pa) - IO_OFFSET) +#define OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET) +#define io_p2v(pa) ((pa) - IO_OFFSET) +#define io_v2p(va) ((va) + IO_OFFSET) #elif defined(CONFIG_ARCH_OMAP2) @@ -73,6 +74,7 @@ #define L4_24XX_VIRT 0xd8000000 #define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */ +#ifdef CONFIG_ARCH_OMAP2430 #define L4_WK_243X_PHYS L4_WK_243X_BASE /* 0x49000000 */ #define L4_WK_243X_VIRT 0xd9000000 #define L4_WK_243X_SIZE SZ_1M @@ -86,10 +88,13 @@ #define OMAP243X_SMS_VIRT 0xFC000000 #define OMAP243X_SMS_SIZE SZ_1M -#define IO_OFFSET 0x90000000 -#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ -#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ -#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */ +#endif + +#define IO_OFFSET 0x90000000 +#define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ +#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ +#define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ +#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */ /* DSP */ #define DSP_MEM_24XX_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */ @@ -144,8 +149,9 @@ #define IO_OFFSET 0x90000000 -#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ -#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ +#define IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ +#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ +#define io_p2v(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ #define io_v2p(va) ((va) - IO_OFFSET)/* Works for L3 and L4 */ /* DSP */ @@ -161,14 +167,7 @@ #endif -#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa)) -#define OMAP1_IO_ADDRESS(pa) IOMEM(__OMAP1_IO_ADDRESS(pa)) -#define OMAP2_IO_ADDRESS(pa) IOMEM(__OMAP2_IO_ADDRESS(pa)) - -#ifdef __ASSEMBLER__ -#define IOMEM(x) x -#else -#define IOMEM(x) ((void __force __iomem *)(x)) +#ifndef __ASSEMBLER__ /* * Functions to access the OMAP IO region @@ -179,13 +178,13 @@ * - DO NOT use hardcoded virtual addresses to allow changing the * IO address space again if needed */ -#define omap_readb(a) __raw_readb(IO_ADDRESS(a)) -#define omap_readw(a) __raw_readw(IO_ADDRESS(a)) -#define omap_readl(a) __raw_readl(IO_ADDRESS(a)) +#define omap_readb(a) (*(volatile unsigned char *)IO_ADDRESS(a)) +#define omap_readw(a) (*(volatile unsigned short *)IO_ADDRESS(a)) +#define omap_readl(a) (*(volatile unsigned int *)IO_ADDRESS(a)) -#define omap_writeb(v,a) __raw_writeb(v, IO_ADDRESS(a)) -#define omap_writew(v,a) __raw_writew(v, IO_ADDRESS(a)) -#define omap_writel(v,a) __raw_writel(v, IO_ADDRESS(a)) +#define omap_writeb(v,a) (*(volatile unsigned char *)IO_ADDRESS(a) = (v)) +#define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v)) +#define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v)) extern void omap1_map_common_io(void); extern void omap1_init_common_hw(void); @@ -193,12 +192,6 @@ extern void omap1_init_common_hw(void); extern void omap2_map_common_io(void); extern void omap2_init_common_hw(void); -#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t) -#define __arch_iounmap(v) omap_iounmap(v) - -void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type); -void omap_iounmap(volatile void __iomem *addr); - #endif #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/irqs.h b/trunk/arch/arm/plat-omap/include/mach/irqs.h index a2929ac8c687..62aa7dfb9464 100644 --- a/trunk/arch/arm/plat-omap/include/mach/irqs.h +++ b/trunk/arch/arm/plat-omap/include/mach/irqs.h @@ -125,7 +125,6 @@ #define INT_UART2 (15 + IH2_BASE) #define INT_BT_MCSI1TX (16 + IH2_BASE) #define INT_BT_MCSI1RX (17 + IH2_BASE) -#define INT_SOSSI_MATCH (19 + IH2_BASE) #define INT_USB_W2FC (20 + IH2_BASE) #define INT_1WIRE (21 + IH2_BASE) #define INT_OS_TIMER (22 + IH2_BASE) @@ -177,7 +176,6 @@ #define INT_1610_DMA_CH14 (61 + IH2_BASE) #define INT_1610_DMA_CH15 (62 + IH2_BASE) #define INT_1610_NAND (63 + IH2_BASE) -#define INT_1610_SHA1MD5 (91 + IH2_BASE) /* * OMAP-730 specific IRQ numbers for interrupt handler 2 @@ -265,18 +263,12 @@ #define INT_24XX_GPTIMER10 46 #define INT_24XX_GPTIMER11 47 #define INT_24XX_GPTIMER12 48 -#define INT_24XX_SHA1MD5 51 -#define INT_24XX_MCBSP4_IRQ_TX 54 -#define INT_24XX_MCBSP4_IRQ_RX 55 #define INT_24XX_I2C1_IRQ 56 #define INT_24XX_I2C2_IRQ 57 -#define INT_24XX_HDQ_IRQ 58 #define INT_24XX_MCBSP1_IRQ_TX 59 #define INT_24XX_MCBSP1_IRQ_RX 60 #define INT_24XX_MCBSP2_IRQ_TX 62 #define INT_24XX_MCBSP2_IRQ_RX 63 -#define INT_24XX_SPI1_IRQ 65 -#define INT_24XX_SPI2_IRQ 66 #define INT_24XX_UART1_IRQ 72 #define INT_24XX_UART2_IRQ 73 #define INT_24XX_UART3_IRQ 74 @@ -286,58 +278,7 @@ #define INT_24XX_USB_IRQ_HGEN 78 #define INT_24XX_USB_IRQ_HSOF 79 #define INT_24XX_USB_IRQ_OTG 80 -#define INT_24XX_MCBSP5_IRQ_TX 81 -#define INT_24XX_MCBSP5_IRQ_RX 82 #define INT_24XX_MMC_IRQ 83 -#define INT_24XX_MMC2_IRQ 86 -#define INT_24XX_MCBSP3_IRQ_TX 89 -#define INT_24XX_MCBSP3_IRQ_RX 90 -#define INT_24XX_SPI3_IRQ 91 - -#define INT_243X_MCBSP2_IRQ 16 -#define INT_243X_MCBSP3_IRQ 17 -#define INT_243X_MCBSP4_IRQ 18 -#define INT_243X_MCBSP5_IRQ 19 -#define INT_243X_MCBSP1_IRQ 64 -#define INT_243X_HS_USB_MC 92 -#define INT_243X_HS_USB_DMA 93 -#define INT_243X_CARKIT_IRQ 94 - -#define INT_34XX_BENCH_MPU_EMUL 3 -#define INT_34XX_ST_MCBSP2_IRQ 4 -#define INT_34XX_ST_MCBSP3_IRQ 5 -#define INT_34XX_SSM_ABORT_IRQ 6 -#define INT_34XX_SYS_NIRQ 7 -#define INT_34XX_D2D_FW_IRQ 8 -#define INT_34XX_PRCM_MPU_IRQ 11 -#define INT_34XX_MCBSP1_IRQ 16 -#define INT_34XX_MCBSP2_IRQ 17 -#define INT_34XX_MCBSP3_IRQ 22 -#define INT_34XX_MCBSP4_IRQ 23 -#define INT_34XX_CAM_IRQ 24 -#define INT_34XX_MCBSP5_IRQ 27 -#define INT_34XX_GPIO_BANK1 29 -#define INT_34XX_GPIO_BANK2 30 -#define INT_34XX_GPIO_BANK3 31 -#define INT_34XX_GPIO_BANK4 32 -#define INT_34XX_GPIO_BANK5 33 -#define INT_34XX_GPIO_BANK6 34 -#define INT_34XX_USIM_IRQ 35 -#define INT_34XX_WDT3_IRQ 36 -#define INT_34XX_SPI4_IRQ 48 -#define INT_34XX_SHA1MD52_IRQ 49 -#define INT_34XX_FPKA_READY_IRQ 50 -#define INT_34XX_SHA1MD51_IRQ 51 -#define INT_34XX_RNG_IRQ 52 -#define INT_34XX_I2C3_IRQ 61 -#define INT_34XX_FPKA_ERROR_IRQ 64 -#define INT_34XX_PBIAS_IRQ 75 -#define INT_34XX_OHCI_IRQ 76 -#define INT_34XX_EHCI_IRQ 77 -#define INT_34XX_TLL_IRQ 78 -#define INT_34XX_PARTHASH_IRQ 79 -#define INT_34XX_MMC3_IRQ 94 -#define INT_34XX_GPT12_IRQ 95 #define INT_34XX_BENCH_MPU_EMUL 3 diff --git a/trunk/arch/arm/plat-omap/include/mach/mcbsp.h b/trunk/arch/arm/plat-omap/include/mach/mcbsp.h index 6a0d1a0a24a7..8fdb95e26fcd 100644 --- a/trunk/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/trunk/arch/arm/plat-omap/include/mach/mcbsp.h @@ -43,15 +43,9 @@ #define OMAP24XX_MCBSP1_BASE 0x48074000 #define OMAP24XX_MCBSP2_BASE 0x48076000 -#define OMAP2430_MCBSP3_BASE 0x4808c000 -#define OMAP2430_MCBSP4_BASE 0x4808e000 -#define OMAP2430_MCBSP5_BASE 0x48096000 #define OMAP34XX_MCBSP1_BASE 0x48074000 #define OMAP34XX_MCBSP2_BASE 0x49022000 -#define OMAP34XX_MCBSP3_BASE 0x49024000 -#define OMAP34XX_MCBSP4_BASE 0x49026000 -#define OMAP34XX_MCBSP5_BASE 0x48096000 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) @@ -87,6 +81,9 @@ #define OMAP_MCBSP_REG_XCERG 0x3A #define OMAP_MCBSP_REG_XCERH 0x3C +#define OMAP_MAX_MCBSP_COUNT 3 +#define MAX_MCBSP_CLOCKS 3 + #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) @@ -94,14 +91,12 @@ #define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX #define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX -#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#elif defined(CONFIG_ARCH_OMAP24XX) #define OMAP_MCBSP_REG_DRR2 0x00 #define OMAP_MCBSP_REG_DRR1 0x04 #define OMAP_MCBSP_REG_DXR2 0x08 #define OMAP_MCBSP_REG_DXR1 0x0C -#define OMAP_MCBSP_REG_DRR 0x00 -#define OMAP_MCBSP_REG_DXR 0x08 #define OMAP_MCBSP_REG_SPCR2 0x10 #define OMAP_MCBSP_REG_SPCR1 0x14 #define OMAP_MCBSP_REG_RCR2 0x18 @@ -129,9 +124,9 @@ #define OMAP_MCBSP_REG_RCERH 0x70 #define OMAP_MCBSP_REG_XCERG 0x74 #define OMAP_MCBSP_REG_XCERH 0x78 -#define OMAP_MCBSP_REG_SYSCON 0x8C -#define OMAP_MCBSP_REG_XCCR 0xAC -#define OMAP_MCBSP_REG_RCCR 0xB0 + +#define OMAP_MAX_MCBSP_COUNT 2 +#define MAX_MCBSP_CLOCKS 2 #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1) @@ -142,6 +137,10 @@ #endif +#define OMAP_MCBSP_READ(base, reg) __raw_readw((base) + OMAP_MCBSP_REG_##reg) +#define OMAP_MCBSP_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg) + + /************************** McBSP SPCR1 bit definitions ***********************/ #define RRST 0x0001 #define RRDY 0x0002 @@ -152,7 +151,6 @@ #define DXENA 0x0080 #define CLKSTP(value) ((value)<<11) /* bits 11:12 */ #define RJUST(value) ((value)<<13) /* bits 13:14 */ -#define ALB 0x8000 #define DLB 0x8000 /************************** McBSP SPCR2 bit definitions ***********************/ @@ -230,17 +228,6 @@ #define XPABLK(value) ((value)<<5) /* Bits 5:6 */ #define XPBBLK(value) ((value)<<7) /* Bits 7:8 */ -/*********************** McBSP XCCR bit definitions *************************/ -#define DILB 0x0020 -#define XDMAEN 0x0008 -#define XDISABLE 0x0001 - -/********************** McBSP RCCR bit definitions *************************/ -#define RDMAEN 0x0008 -#define RDISABLE 0x0001 - -/********************** McBSP SYSCONFIG bit definitions ********************/ -#define SOFTRST 0x0002 /* we don't do multichannel for now */ struct omap_mcbsp_reg_cfg { @@ -273,8 +260,6 @@ typedef enum { OMAP_MCBSP1 = 0, OMAP_MCBSP2, OMAP_MCBSP3, - OMAP_MCBSP4, - OMAP_MCBSP5 } omap_mcbsp_id; typedef int __bitwise omap_mcbsp_io_type_t; @@ -326,10 +311,12 @@ struct omap_mcbsp_spi_cfg { struct omap_mcbsp_ops { void (*request)(unsigned int); void (*free)(unsigned int); + int (*check)(unsigned int); }; struct omap_mcbsp_platform_data { unsigned long phys_base; + u32 virt_base; u8 dma_rx_sync, dma_tx_sync; u16 rx_irq, tx_irq; struct omap_mcbsp_ops *ops; @@ -339,7 +326,7 @@ struct omap_mcbsp_platform_data { struct omap_mcbsp { struct device *dev; unsigned long phys_base; - void __iomem *io_base; + u32 io_base; u8 id; u8 free; omap_mcbsp_word_length rx_word_length; @@ -367,8 +354,6 @@ struct omap_mcbsp { struct omap_mcbsp_platform_data *pdata; struct clk *clk; }; -extern struct omap_mcbsp **mcbsp_ptr; -extern int omap_mcbsp_count; int omap_mcbsp_init(void); void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, @@ -393,6 +378,5 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * /* Polled read/write functions */ int omap_mcbsp_pollread(unsigned int id, u16 * buf); int omap_mcbsp_pollwrite(unsigned int id, u16 buf); -int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type); #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/memory.h b/trunk/arch/arm/plat-omap/include/mach/memory.h index d40cac60b959..a325caf80d04 100644 --- a/trunk/arch/arm/plat-omap/include/mach/memory.h +++ b/trunk/arch/arm/plat-omap/include/mach/memory.h @@ -38,7 +38,7 @@ */ #if defined(CONFIG_ARCH_OMAP1) #define PHYS_OFFSET UL(0x10000000) -#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) +#elif defined(CONFIG_ARCH_OMAP2) #define PHYS_OFFSET UL(0x80000000) #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/mux.h b/trunk/arch/arm/plat-omap/include/mach/mux.h index 6bbf1789bed5..614b2c1327c7 100644 --- a/trunk/arch/arm/plat-omap/include/mach/mux.h +++ b/trunk/arch/arm/plat-omap/include/mach/mux.h @@ -125,64 +125,20 @@ .pu_pd_val = pull_mode, \ }, -/* 24xx/34xx mux bit defines */ -#define OMAP2_PULL_ENA (1 << 3) -#define OMAP2_PULL_UP (1 << 4) -#define OMAP2_ALTELECTRICALSEL (1 << 5) - -/* 34xx specific mux bit defines */ -#define OMAP3_INPUT_EN (1 << 8) -#define OMAP3_OFF_EN (1 << 9) -#define OMAP3_OFFOUT_EN (1 << 10) -#define OMAP3_OFFOUT_VAL (1 << 11) -#define OMAP3_OFF_PULL_EN (1 << 12) -#define OMAP3_OFF_PULL_UP (1 << 13) -#define OMAP3_WAKEUP_EN (1 << 14) - -/* 34xx mux mode options for each pin. See TRM for options */ -#define OMAP34XX_MUX_MODE0 0 -#define OMAP34XX_MUX_MODE1 1 -#define OMAP34XX_MUX_MODE2 2 -#define OMAP34XX_MUX_MODE3 3 -#define OMAP34XX_MUX_MODE4 4 -#define OMAP34XX_MUX_MODE5 5 -#define OMAP34XX_MUX_MODE6 6 -#define OMAP34XX_MUX_MODE7 7 - -/* 34xx active pin states */ -#define OMAP34XX_PIN_OUTPUT 0 -#define OMAP34XX_PIN_INPUT OMAP3_INPUT_EN -#define OMAP34XX_PIN_INPUT_PULLUP (OMAP2_PULL_ENA | OMAP3_INPUT_EN \ - | OMAP2_PULL_UP) -#define OMAP34XX_PIN_INPUT_PULLDOWN (OMAP2_PULL_ENA | OMAP3_INPUT_EN) - -/* 34xx off mode states */ -#define OMAP34XX_PIN_OFF_NONE 0 -#define OMAP34XX_PIN_OFF_OUTPUT_HIGH (OMAP3_OFF_EN | OMAP3_OFFOUT_EN \ - | OMAP3_OFFOUT_VAL) -#define OMAP34XX_PIN_OFF_OUTPUT_LOW (OMAP3_OFF_EN | OMAP3_OFFOUT_EN) -#define OMAP34XX_PIN_OFF_INPUT_PULLUP (OMAP3_OFF_EN | OMAP3_OFF_PULL_EN \ - | OMAP3_OFF_PULL_UP) -#define OMAP34XX_PIN_OFF_INPUT_PULLDOWN (OMAP3_OFF_EN | OMAP3_OFF_PULL_EN) -#define OMAP34XX_PIN_OFF_WAKEUPENABLE OMAP3_WAKEUP_EN - -#define MUX_CFG_34XX(desc, reg_offset, mux_value) { \ - .name = desc, \ - .debug = 0, \ - .mux_reg = reg_offset, \ - .mux_val = mux_value \ -}, -struct pin_config { - char *name; - const unsigned int mux_reg; - unsigned char debug; +#define PULL_DISABLED 0 +#define PULL_ENABLED 1 -#if defined(CONFIG_ARCH_OMAP34XX) - u16 mux_val; /* Wake-up, off mode, pull, mux mode */ -#endif +#define PULL_DOWN 0 +#define PULL_UP 1 + +struct pin_config { + char *name; + unsigned char busy; + unsigned char debug; -#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX) + const char *mux_reg_name; + const unsigned int mux_reg; const unsigned char mask_offset; const unsigned char mask; @@ -194,12 +150,6 @@ struct pin_config { const char *pu_pd_name; const unsigned int pu_pd_reg; const unsigned char pu_pd_val; -#endif - -#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) - const char *mux_reg_name; -#endif - }; enum omap730_index { @@ -643,114 +593,6 @@ enum omap24xx_index { }; -enum omap34xx_index { - /* 34xx I2C */ - K21_34XX_I2C1_SCL, - J21_34XX_I2C1_SDA, - AF15_34XX_I2C2_SCL, - AE15_34XX_I2C2_SDA, - AF14_34XX_I2C3_SCL, - AG14_34XX_I2C3_SDA, - AD26_34XX_I2C4_SCL, - AE26_34XX_I2C4_SDA, - - /* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/ - Y8_3430_USB1HS_PHY_CLK, - Y9_3430_USB1HS_PHY_STP, - AA14_3430_USB1HS_PHY_DIR, - AA11_3430_USB1HS_PHY_NXT, - W13_3430_USB1HS_PHY_DATA0, - W12_3430_USB1HS_PHY_DATA1, - W11_3430_USB1HS_PHY_DATA2, - Y11_3430_USB1HS_PHY_DATA3, - W9_3430_USB1HS_PHY_DATA4, - Y12_3430_USB1HS_PHY_DATA5, - W8_3430_USB1HS_PHY_DATA6, - Y13_3430_USB1HS_PHY_DATA7, - - /* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/ - AA8_3430_USB2HS_PHY_CLK, - AA10_3430_USB2HS_PHY_STP, - AA9_3430_USB2HS_PHY_DIR, - AB11_3430_USB2HS_PHY_NXT, - AB10_3430_USB2HS_PHY_DATA0, - AB9_3430_USB2HS_PHY_DATA1, - W3_3430_USB2HS_PHY_DATA2, - T4_3430_USB2HS_PHY_DATA3, - T3_3430_USB2HS_PHY_DATA4, - R3_3430_USB2HS_PHY_DATA5, - R4_3430_USB2HS_PHY_DATA6, - T2_3430_USB2HS_PHY_DATA7, - - - /* TLL - HSUSB: 12-pin TLL Port 1*/ - Y8_3430_USB1HS_TLL_CLK, - Y9_3430_USB1HS_TLL_STP, - AA14_3430_USB1HS_TLL_DIR, - AA11_3430_USB1HS_TLL_NXT, - W13_3430_USB1HS_TLL_DATA0, - W12_3430_USB1HS_TLL_DATA1, - W11_3430_USB1HS_TLL_DATA2, - Y11_3430_USB1HS_TLL_DATA3, - W9_3430_USB1HS_TLL_DATA4, - Y12_3430_USB1HS_TLL_DATA5, - W8_3430_USB1HS_TLL_DATA6, - Y13_3430_USB1HS_TLL_DATA7, - - /* TLL - HSUSB: 12-pin TLL Port 2*/ - AA8_3430_USB2HS_TLL_CLK, - AA10_3430_USB2HS_TLL_STP, - AA9_3430_USB2HS_TLL_DIR, - AB11_3430_USB2HS_TLL_NXT, - AB10_3430_USB2HS_TLL_DATA0, - AB9_3430_USB2HS_TLL_DATA1, - W3_3430_USB2HS_TLL_DATA2, - T4_3430_USB2HS_TLL_DATA3, - T3_3430_USB2HS_TLL_DATA4, - R3_3430_USB2HS_TLL_DATA5, - R4_3430_USB2HS_TLL_DATA6, - T2_3430_USB2HS_TLL_DATA7, - - /* TLL - HSUSB: 12-pin TLL Port 3*/ - AA6_3430_USB3HS_TLL_CLK, - AB3_3430_USB3HS_TLL_STP, - AA3_3430_USB3HS_TLL_DIR, - Y3_3430_USB3HS_TLL_NXT, - AA5_3430_USB3HS_TLL_DATA0, - Y4_3430_USB3HS_TLL_DATA1, - Y5_3430_USB3HS_TLL_DATA2, - W5_3430_USB3HS_TLL_DATA3, - AB12_3430_USB3HS_TLL_DATA4, - AB13_3430_USB3HS_TLL_DATA5, - AA13_3430_USB3HS_TLL_DATA6, - AA12_3430_USB3HS_TLL_DATA7, - - /* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */ - AF10_3430_USB1FS_PHY_MM1_RXDP, - AG9_3430_USB1FS_PHY_MM1_RXDM, - W13_3430_USB1FS_PHY_MM1_RXRCV, - W12_3430_USB1FS_PHY_MM1_TXSE0, - W11_3430_USB1FS_PHY_MM1_TXDAT, - Y11_3430_USB1FS_PHY_MM1_TXEN_N, - - /* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */ - AF7_3430_USB2FS_PHY_MM2_RXDP, - AH7_3430_USB2FS_PHY_MM2_RXDM, - AB10_3430_USB2FS_PHY_MM2_RXRCV, - AB9_3430_USB2FS_PHY_MM2_TXSE0, - W3_3430_USB2FS_PHY_MM2_TXDAT, - T4_3430_USB2FS_PHY_MM2_TXEN_N, - - /* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */ - AH3_3430_USB3FS_PHY_MM3_RXDP, - AE3_3430_USB3FS_PHY_MM3_RXDM, - AD1_3430_USB3FS_PHY_MM3_RXRCV, - AE1_3430_USB3FS_PHY_MM3_TXSE0, - AD2_3430_USB3FS_PHY_MM3_TXDAT, - AC1_3430_USB3FS_PHY_MM3_TXEN_N, - -}; - struct omap_mux_cfg { struct pin_config *pins; unsigned long size; diff --git a/trunk/arch/arm/plat-omap/include/mach/omap1510.h b/trunk/arch/arm/plat-omap/include/mach/omap1510.h index d24004668138..505a38af8b22 100644 --- a/trunk/arch/arm/plat-omap/include/mach/omap1510.h +++ b/trunk/arch/arm/plat-omap/include/mach/omap1510.h @@ -44,7 +44,5 @@ #define OMAP1510_DSPREG_SIZE SZ_128K #define OMAP1510_DSPREG_START 0xE1000000 -#define OMAP1510_DSP_MMU_BASE (0xfffed200) - #endif /* __ASM_ARCH_OMAP15XX_H */ diff --git a/trunk/arch/arm/plat-omap/include/mach/omap16xx.h b/trunk/arch/arm/plat-omap/include/mach/omap16xx.h index 0e69b504c25f..c6c93afb2788 100644 --- a/trunk/arch/arm/plat-omap/include/mach/omap16xx.h +++ b/trunk/arch/arm/plat-omap/include/mach/omap16xx.h @@ -44,11 +44,6 @@ #define OMAP16XX_DSPREG_SIZE SZ_128K #define OMAP16XX_DSPREG_START 0xE1000000 -#define OMAP16XX_SEC_BASE 0xFFFE4000 -#define OMAP16XX_SEC_DES (OMAP16XX_SEC_BASE + 0x0000) -#define OMAP16XX_SEC_SHA1MD5 (OMAP16XX_SEC_BASE + 0x0800) -#define OMAP16XX_SEC_RNG (OMAP16XX_SEC_BASE + 0x1000) - /* * --------------------------------------------------------------------------- * Interrupts @@ -195,7 +190,7 @@ #define WSPR_DISABLE_0 (0x0000aaaa) #define WSPR_DISABLE_1 (0x00005555) -#define OMAP16XX_DSP_MMU_BASE (0xfffed200) +/* Mailbox */ #define OMAP16XX_MAILBOX_BASE (0xfffcf000) #endif /* __ASM_ARCH_OMAP16XX_H */ diff --git a/trunk/arch/arm/plat-omap/include/mach/omap24xx.h b/trunk/arch/arm/plat-omap/include/mach/omap24xx.h index 24335d4932f5..bb8319d66e9f 100644 --- a/trunk/arch/arm/plat-omap/include/mach/omap24xx.h +++ b/trunk/arch/arm/plat-omap/include/mach/omap24xx.h @@ -39,6 +39,7 @@ /* interrupt controller */ #define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000) #define OMAP24XX_IVA_INTC_BASE 0x40000000 +#define IRQ_SIR_IRQ 0x0040 #define OMAP2420_CTRL_BASE L4_24XX_BASE #define OMAP2420_32KSYNCT_BASE (L4_24XX_BASE + 0x4000) @@ -47,7 +48,6 @@ #define OMAP2420_PRM_BASE OMAP2420_CM_BASE #define OMAP2420_SDRC_BASE (L3_24XX_BASE + 0x9000) #define OMAP2420_SMS_BASE 0x68008000 -#define OMAP2420_GPMC_BASE 0x6800a000 #define OMAP2430_32KSYNCT_BASE (L4_WK_243X_BASE + 0x20000) #define OMAP2430_PRCM_BASE (L4_WK_243X_BASE + 0x6000) diff --git a/trunk/arch/arm/plat-omap/include/mach/omapfb.h b/trunk/arch/arm/plat-omap/include/mach/omapfb.h index ec67fb428607..cae037d13079 100644 --- a/trunk/arch/arm/plat-omap/include/mach/omapfb.h +++ b/trunk/arch/arm/plat-omap/include/mach/omapfb.h @@ -62,7 +62,6 @@ #define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000 #define OMAPFB_CAPS_WINDOW_SCALE 0x00020000 #define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000 -#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000 #define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000 /* Values from DSP must map to lower 16-bits */ @@ -306,7 +305,6 @@ struct lcd_ctrl { int screen_width, int pos_x, int pos_y, int width, int height, int color_mode); - int (*set_rotate) (int angle); int (*setup_mem) (int plane, size_t size, int mem_type, unsigned long *paddr); int (*mmap) (struct fb_info *info, @@ -376,7 +374,6 @@ extern struct lcd_ctrl omap1_lcd_ctrl; extern struct lcd_ctrl omap2_disp_ctrl; #endif -extern void omapfb_reserve_sdram(void); extern void omapfb_register_panel(struct lcd_panel *panel); extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval); extern void omapfb_notify_clients(struct omapfb_device *fbdev, diff --git a/trunk/arch/arm/plat-omap/include/mach/pm.h b/trunk/arch/arm/plat-omap/include/mach/pm.h index 768eb6e7abcf..bfa09325a5ff 100644 --- a/trunk/arch/arm/plat-omap/include/mach/pm.h +++ b/trunk/arch/arm/plat-omap/include/mach/pm.h @@ -39,11 +39,11 @@ * Register and offset definitions to be used in PM assembler code * ---------------------------------------------------------------------------- */ -#define CLKGEN_REG_ASM_BASE IO_ADDRESS(0xfffece00) +#define CLKGEN_REG_ASM_BASE io_p2v(0xfffece00) #define ARM_IDLECT1_ASM_OFFSET 0x04 #define ARM_IDLECT2_ASM_OFFSET 0x08 -#define TCMIF_ASM_BASE IO_ADDRESS(0xfffecc00) +#define TCMIF_ASM_BASE io_p2v(0xfffecc00) #define EMIFS_CONFIG_ASM_OFFSET 0x0c #define EMIFF_SDRAM_CONFIG_ASM_OFFSET 0x20 @@ -135,8 +135,7 @@ extern void omap_pm_suspend(void); extern void omap730_cpu_suspend(unsigned short, unsigned short); extern void omap1510_cpu_suspend(unsigned short, unsigned short); extern void omap1610_cpu_suspend(unsigned short, unsigned short); -extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, - void __iomem *sdrc_power); +extern void omap24xx_cpu_suspend(u32 dll_ctrl, u32 cpu_revision); extern void omap730_idle_loop_suspend(void); extern void omap1510_idle_loop_suspend(void); extern void omap1610_idle_loop_suspend(void); diff --git a/trunk/arch/arm/plat-omap/include/mach/powerdomain.h b/trunk/arch/arm/plat-omap/include/mach/powerdomain.h deleted file mode 100644 index 2806a9c8e4d7..000000000000 --- a/trunk/arch/arm/plat-omap/include/mach/powerdomain.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * OMAP2/3 powerdomain control - * - * Copyright (C) 2007-8 Texas Instruments, Inc. - * Copyright (C) 2007-8 Nokia Corporation - * - * Written by Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN -#define ASM_ARM_ARCH_OMAP_POWERDOMAIN - -#include -#include - -#include - -#include - - -/* Powerdomain basic power states */ -#define PWRDM_POWER_OFF 0x0 -#define PWRDM_POWER_RET 0x1 -#define PWRDM_POWER_INACTIVE 0x2 -#define PWRDM_POWER_ON 0x3 - -/* Powerdomain allowable state bitfields */ -#define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \ - (1 << PWRDM_POWER_ON)) - -#define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \ - (1 << PWRDM_POWER_RET)) - -#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON)) - - -/* Powerdomain flags */ -#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */ - - -/* - * Number of memory banks that are power-controllable. On OMAP3430, the - * maximum is 4. - */ -#define PWRDM_MAX_MEM_BANKS 4 - -/* - * Maximum number of clockdomains that can be associated with a powerdomain. - * CORE powerdomain is probably the worst case. - */ -#define PWRDM_MAX_CLKDMS 3 - -/* XXX A completely arbitrary number. What is reasonable here? */ -#define PWRDM_TRANSITION_BAILOUT 100000 - -struct clockdomain; -struct powerdomain; - -/* Encodes dependencies between powerdomains - statically defined */ -struct pwrdm_dep { - - /* Powerdomain name */ - const char *pwrdm_name; - - /* Powerdomain pointer - resolved by the powerdomain code */ - struct powerdomain *pwrdm; - - /* Flags to mark OMAP chip restrictions, etc. */ - const struct omap_chip_id omap_chip; - -}; - -struct powerdomain { - - /* Powerdomain name */ - const char *name; - - /* the address offset from CM_BASE/PRM_BASE */ - const s16 prcm_offs; - - /* Used to represent the OMAP chip types containing this pwrdm */ - const struct omap_chip_id omap_chip; - - /* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */ - const u8 dep_bit; - - /* Powerdomains that can be told to wake this powerdomain up */ - struct pwrdm_dep *wkdep_srcs; - - /* Powerdomains that can be told to keep this pwrdm from inactivity */ - struct pwrdm_dep *sleepdep_srcs; - - /* Possible powerdomain power states */ - const u8 pwrsts; - - /* Possible logic power states when pwrdm in RETENTION */ - const u8 pwrsts_logic_ret; - - /* Powerdomain flags */ - const u8 flags; - - /* Number of software-controllable memory banks in this powerdomain */ - const u8 banks; - - /* Possible memory bank pwrstates when pwrdm in RETENTION */ - const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS]; - - /* Possible memory bank pwrstates when pwrdm is ON */ - const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS]; - - /* Clockdomains in this powerdomain */ - struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS]; - - struct list_head node; - -}; - - -void pwrdm_init(struct powerdomain **pwrdm_list); - -int pwrdm_register(struct powerdomain *pwrdm); -int pwrdm_unregister(struct powerdomain *pwrdm); -struct powerdomain *pwrdm_lookup(const char *name); - -int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)); - -int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); -int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); -int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, - int (*fn)(struct powerdomain *pwrdm, - struct clockdomain *clkdm)); - -int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); -int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); -int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); -int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); -int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); -int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2); - -int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm); - -int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); -int pwrdm_read_next_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm); -int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm); - -int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); -int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); -int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); - -int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank); -int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank); - -int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm); -int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); -bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); - -int pwrdm_wait_transition(struct powerdomain *pwrdm); - -#endif diff --git a/trunk/arch/arm/plat-omap/include/mach/sdrc.h b/trunk/arch/arm/plat-omap/include/mach/sdrc.h index a98c6c3beb2c..787b7acec546 100644 --- a/trunk/arch/arm/plat-omap/include/mach/sdrc.h +++ b/trunk/arch/arm/plat-omap/include/mach/sdrc.h @@ -25,8 +25,6 @@ #define SDRC_DLLB_STATUS 0x06C #define SDRC_POWER 0x070 #define SDRC_MR_0 0x084 -#define SDRC_ACTIM_CTRL_A_0 0x09c -#define SDRC_ACTIM_CTRL_B_0 0x0a0 #define SDRC_RFR_CTRL_0 0x0a4 /* @@ -65,9 +63,9 @@ */ -#define OMAP242X_SMS_REGADDR(reg) IO_ADDRESS(OMAP2420_SMS_BASE + reg) -#define OMAP243X_SMS_REGADDR(reg) IO_ADDRESS(OMAP243X_SMS_BASE + reg) -#define OMAP343X_SMS_REGADDR(reg) IO_ADDRESS(OMAP343X_SMS_BASE + reg) +#define OMAP242X_SMS_REGADDR(reg) (void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg) +#define OMAP243X_SMS_REGADDR(reg) (void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg) +#define OMAP343X_SMS_REGADDR(reg) (void __iomem *)IO_ADDRESS(OMAP343X_SMS_BASE + reg) /* SMS register offsets - read/write with sms_{read,write}_reg() */ diff --git a/trunk/arch/arm/plat-omap/include/mach/serial.h b/trunk/arch/arm/plat-omap/include/mach/serial.h index 8a676a04be48..cc6bfa51ccb5 100644 --- a/trunk/arch/arm/plat-omap/include/mach/serial.h +++ b/trunk/arch/arm/plat-omap/include/mach/serial.h @@ -20,24 +20,18 @@ #define OMAP_UART1_BASE 0x4806a000 #define OMAP_UART2_BASE 0x4806c000 #define OMAP_UART3_BASE 0x4806e000 -#elif defined(CONFIG_ARCH_OMAP3) -/* OMAP3 serial ports */ -#define OMAP_UART1_BASE 0x4806a000 -#define OMAP_UART2_BASE 0x4806c000 -#define OMAP_UART3_BASE 0x49020000 #endif #define OMAP_MAX_NR_PORTS 3 #define OMAP1510_BASE_BAUD (12000000/16) #define OMAP16XX_BASE_BAUD (48000000/16) -#define OMAP24XX_BASE_BAUD (48000000/16) -#define is_omap_port(pt) ({int __ret = 0; \ - if ((pt)->port.mapbase == OMAP_UART1_BASE || \ - (pt)->port.mapbase == OMAP_UART2_BASE || \ - (pt)->port.mapbase == OMAP_UART3_BASE) \ - __ret = 1; \ - __ret; \ +#define is_omap_port(p) ({int __ret = 0; \ + if (p == IO_ADDRESS(OMAP_UART1_BASE) || \ + p == IO_ADDRESS(OMAP_UART2_BASE) || \ + p == IO_ADDRESS(OMAP_UART3_BASE)) \ + __ret = 1; \ + __ret; \ }) #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/sram.h b/trunk/arch/arm/plat-omap/include/mach/sram.h index ab35d622dcf5..e09323449981 100644 --- a/trunk/arch/arm/plat-omap/include/mach/sram.h +++ b/trunk/arch/arm/plat-omap/include/mach/sram.h @@ -21,10 +21,6 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type); extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); -extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, - u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, u32 m2); - /* Do not use these */ extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); extern unsigned long omap1_sram_reprogram_clock_sz; @@ -57,10 +53,4 @@ extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type); extern unsigned long omap243x_sram_reprogram_sdrc_sz; - -extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl, - u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, u32 m2); -extern unsigned long omap3_sram_configure_core_dpll_sz; - #endif diff --git a/trunk/arch/arm/plat-omap/include/mach/system.h b/trunk/arch/arm/plat-omap/include/mach/system.h index 06923f261545..06a28c7b98de 100644 --- a/trunk/arch/arm/plat-omap/include/mach/system.h +++ b/trunk/arch/arm/plat-omap/include/mach/system.h @@ -40,7 +40,7 @@ static inline void omap1_arch_reset(char mode) static inline void arch_reset(char mode) { - if (!cpu_class_is_omap2()) + if (!cpu_is_omap24xx()) omap1_arch_reset(mode); else omap_prcm_arch_reset(mode); diff --git a/trunk/arch/arm/plat-omap/io.c b/trunk/arch/arm/plat-omap/io.c deleted file mode 100644 index af326efc1ad3..000000000000 --- a/trunk/arch/arm/plat-omap/io.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include - -#define BETWEEN(p,st,sz) ((p) >= (st) && (p) < ((st) + (sz))) -#define XLATE(p,pst,vst) ((void __iomem *)((p) - (pst) + (vst))) - -/* - * Intercept ioremap() requests for addresses in our fixed mapping regions. - */ -void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type) -{ -#ifdef CONFIG_ARCH_OMAP1 - if (cpu_class_is_omap1()) { - if (BETWEEN(p, IO_PHYS, IO_SIZE)) - return XLATE(p, IO_PHYS, IO_VIRT); - } - if (cpu_is_omap730()) { - if (BETWEEN(p, OMAP730_DSP_BASE, OMAP730_DSP_SIZE)) - return XLATE(p, OMAP730_DSP_BASE, OMAP730_DSP_START); - - if (BETWEEN(p, OMAP730_DSPREG_BASE, OMAP730_DSPREG_SIZE)) - return XLATE(p, OMAP730_DSPREG_BASE, - OMAP730_DSPREG_START); - } - if (cpu_is_omap15xx()) { - if (BETWEEN(p, OMAP1510_DSP_BASE, OMAP1510_DSP_SIZE)) - return XLATE(p, OMAP1510_DSP_BASE, OMAP1510_DSP_START); - - if (BETWEEN(p, OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_SIZE)) - return XLATE(p, OMAP1510_DSPREG_BASE, - OMAP1510_DSPREG_START); - } - if (cpu_is_omap16xx()) { - if (BETWEEN(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_SIZE)) - return XLATE(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_START); - - if (BETWEEN(p, OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_SIZE)) - return XLATE(p, OMAP16XX_DSPREG_BASE, - OMAP16XX_DSPREG_START); - } -#endif -#ifdef CONFIG_ARCH_OMAP2 - if (cpu_is_omap24xx()) { - if (BETWEEN(p, L3_24XX_PHYS, L3_24XX_SIZE)) - return XLATE(p, L3_24XX_PHYS, L3_24XX_VIRT); - if (BETWEEN(p, L4_24XX_PHYS, L4_24XX_SIZE)) - return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT); - } - if (cpu_is_omap2420()) { - if (BETWEEN(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_SIZE)) - return XLATE(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_VIRT); - if (BETWEEN(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE)) - return XLATE(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE); - if (BETWEEN(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_SIZE)) - return XLATE(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_VIRT); - } - if (cpu_is_omap2430()) { - if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE)) - return XLATE(p, L4_WK_243X_PHYS, L4_WK_243X_VIRT); - if (BETWEEN(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_SIZE)) - return XLATE(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_VIRT); - if (BETWEEN(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_SIZE)) - return XLATE(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_VIRT); - if (BETWEEN(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_SIZE)) - return XLATE(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_VIRT); - } -#endif -#ifdef CONFIG_ARCH_OMAP3 - if (cpu_is_omap34xx()) { - if (BETWEEN(p, L3_34XX_PHYS, L3_34XX_SIZE)) - return XLATE(p, L3_34XX_PHYS, L3_34XX_VIRT); - if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE)) - return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT); - if (BETWEEN(p, L4_WK_34XX_PHYS, L4_WK_34XX_SIZE)) - return XLATE(p, L4_WK_34XX_PHYS, L4_WK_34XX_VIRT); - if (BETWEEN(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_SIZE)) - return XLATE(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_VIRT); - if (BETWEEN(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_SIZE)) - return XLATE(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_VIRT); - if (BETWEEN(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_SIZE)) - return XLATE(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_VIRT); - if (BETWEEN(p, L4_PER_34XX_PHYS, L4_PER_34XX_SIZE)) - return XLATE(p, L4_PER_34XX_PHYS, L4_PER_34XX_VIRT); - if (BETWEEN(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_SIZE)) - return XLATE(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_VIRT); - } -#endif - - return __arm_ioremap(p, size, type); -} -EXPORT_SYMBOL(omap_ioremap); - -void omap_iounmap(volatile void __iomem *addr) -{ - unsigned long virt = (unsigned long)addr; - - if (virt >= VMALLOC_START && virt < VMALLOC_END) - __iounmap(addr); -} -EXPORT_SYMBOL(omap_iounmap); diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index af33fc713e1a..014d26574bb6 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -27,65 +27,43 @@ #include #include -struct omap_mcbsp **mcbsp_ptr; -int omap_mcbsp_count; +static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; -void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val) -{ - if (cpu_class_is_omap1() || cpu_is_omap2420()) - __raw_writew((u16)val, io_base + reg); - else - __raw_writel(val, io_base + reg); -} - -int omap_mcbsp_read(void __iomem *io_base, u16 reg) -{ - if (cpu_class_is_omap1() || cpu_is_omap2420()) - return __raw_readw(io_base + reg); - else - return __raw_readl(io_base + reg); -} - -#define OMAP_MCBSP_READ(base, reg) \ - omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg) -#define OMAP_MCBSP_WRITE(base, reg, val) \ - omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val) - -#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count) -#define id_to_mcbsp_ptr(id) mcbsp_ptr[id]; +#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ + mcbsp[id].pdata->ops && \ + mcbsp[id].pdata->ops->check && \ + (mcbsp[id].pdata->ops->check(id) == 0)) static void omap_mcbsp_dump_reg(u8 id) { - struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id); - - dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id); - dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, DRR2)); - dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, DRR1)); - dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, DXR2)); - dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, DXR1)); - dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, SPCR2)); - dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, SPCR1)); - dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, RCR2)); - dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, RCR1)); - dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, XCR2)); - dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, XCR1)); - dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, SRGR2)); - dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, SRGR1)); - dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp->io_base, PCR0)); - dev_dbg(mcbsp->dev, "***********************\n"); + dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); + dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); + dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); + dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); + dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); + dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); + dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); + dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); + dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); + dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); + dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); + dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); + dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); + dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); + dev_dbg(mcbsp[id].dev, "***********************\n"); } static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) @@ -148,18 +126,16 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) */ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) { - struct omap_mcbsp *mcbsp; - void __iomem *io_base; + u32 io_base; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; } - mcbsp = id_to_mcbsp_ptr(id); - io_base = mcbsp->io_base; - dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n", - mcbsp->id, mcbsp->phys_base); + io_base = mcbsp[id].io_base; + dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n", + mcbsp[id].id, io_base); /* We write the given config */ OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); @@ -182,26 +158,23 @@ EXPORT_SYMBOL(omap_mcbsp_config); */ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) { - struct omap_mcbsp *mcbsp; - if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - spin_lock(&mcbsp->lock); + spin_lock(&mcbsp[id].lock); - if (!mcbsp->free) { - dev_err(mcbsp->dev, "McBSP%d is currently in use\n", - mcbsp->id); - spin_unlock(&mcbsp->lock); + if (!mcbsp[id].free) { + dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", + mcbsp[id].id); + spin_unlock(&mcbsp[id].lock); return -EINVAL; } - mcbsp->io_type = io_type; + mcbsp[id].io_type = io_type; - spin_unlock(&mcbsp->lock); + spin_unlock(&mcbsp[id].lock); return 0; } @@ -209,60 +182,53 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type); int omap_mcbsp_request(unsigned int id) { - struct omap_mcbsp *mcbsp; int err; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) - mcbsp->pdata->ops->request(id); + if (mcbsp[id].pdata->ops->request) + mcbsp[id].pdata->ops->request(id); - clk_enable(mcbsp->clk); + clk_enable(mcbsp[id].clk); - spin_lock(&mcbsp->lock); - if (!mcbsp->free) { - dev_err(mcbsp->dev, "McBSP%d is currently in use\n", - mcbsp->id); - spin_unlock(&mcbsp->lock); + spin_lock(&mcbsp[id].lock); + if (!mcbsp[id].free) { + dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", + mcbsp[id].id); + spin_unlock(&mcbsp[id].lock); return -1; } - mcbsp->free = 0; - spin_unlock(&mcbsp->lock); - - /* - * Make sure that transmitter, receiver and sample-rate generator are - * not running before activating IRQs. - */ - OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0); - OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0); + mcbsp[id].free = 0; + spin_unlock(&mcbsp[id].lock); - if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { + if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { /* We need to get IRQs here */ - init_completion(&mcbsp->tx_irq_completion); - err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler, - 0, "McBSP", (void *)mcbsp); + err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, + 0, "McBSP", (void *) (&mcbsp[id])); if (err != 0) { - dev_err(mcbsp->dev, "Unable to request TX IRQ %d " - "for McBSP%d\n", mcbsp->tx_irq, - mcbsp->id); + dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " + "for McBSP%d\n", mcbsp[id].tx_irq, + mcbsp[id].id); return err; } - init_completion(&mcbsp->rx_irq_completion); - err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, - 0, "McBSP", (void *)mcbsp); + init_completion(&(mcbsp[id].tx_irq_completion)); + + err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, + 0, "McBSP", (void *) (&mcbsp[id])); if (err != 0) { - dev_err(mcbsp->dev, "Unable to request RX IRQ %d " - "for McBSP%d\n", mcbsp->rx_irq, - mcbsp->id); - free_irq(mcbsp->tx_irq, (void *)mcbsp); + dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " + "for McBSP%d\n", mcbsp[id].rx_irq, + mcbsp[id].id); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); return err; } + + init_completion(&(mcbsp[id].rx_irq_completion)); } return 0; @@ -271,34 +237,31 @@ EXPORT_SYMBOL(omap_mcbsp_request); void omap_mcbsp_free(unsigned int id) { - struct omap_mcbsp *mcbsp; - if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; } - mcbsp = id_to_mcbsp_ptr(id); - if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) - mcbsp->pdata->ops->free(id); + if (mcbsp[id].pdata->ops->free) + mcbsp[id].pdata->ops->free(id); - clk_disable(mcbsp->clk); + clk_disable(mcbsp[id].clk); - spin_lock(&mcbsp->lock); - if (mcbsp->free) { - dev_err(mcbsp->dev, "McBSP%d was not reserved\n", - mcbsp->id); - spin_unlock(&mcbsp->lock); + spin_lock(&mcbsp[id].lock); + if (mcbsp[id].free) { + dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", + mcbsp[id].id); + spin_unlock(&mcbsp[id].lock); return; } - mcbsp->free = 1; - spin_unlock(&mcbsp->lock); + mcbsp[id].free = 1; + spin_unlock(&mcbsp[id].lock); - if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { + if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { /* Free IRQs */ - free_irq(mcbsp->rx_irq, (void *)mcbsp); - free_irq(mcbsp->tx_irq, (void *)mcbsp); + free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); } } EXPORT_SYMBOL(omap_mcbsp_free); @@ -310,19 +273,18 @@ EXPORT_SYMBOL(omap_mcbsp_free); */ void omap_mcbsp_start(unsigned int id) { - struct omap_mcbsp *mcbsp; - void __iomem *io_base; + u32 io_base; u16 w; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; } - mcbsp = id_to_mcbsp_ptr(id); - io_base = mcbsp->io_base; - mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; - mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; + io_base = mcbsp[id].io_base; + + mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; + mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; /* Start the sample generator */ w = OMAP_MCBSP_READ(io_base, SPCR2); @@ -348,8 +310,7 @@ EXPORT_SYMBOL(omap_mcbsp_start); void omap_mcbsp_stop(unsigned int id) { - struct omap_mcbsp *mcbsp; - void __iomem *io_base; + u32 io_base; u16 w; if (!omap_mcbsp_check_valid_id(id)) { @@ -357,8 +318,7 @@ void omap_mcbsp_stop(unsigned int id) return; } - mcbsp = id_to_mcbsp_ptr(id); - io_base = mcbsp->io_base; + io_base = mcbsp[id].io_base; /* Reset transmitter */ w = OMAP_MCBSP_READ(io_base, SPCR2); @@ -377,17 +337,14 @@ EXPORT_SYMBOL(omap_mcbsp_stop); /* polled mcbsp i/o operations */ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) { - struct omap_mcbsp *mcbsp; - void __iomem *base; + u32 base; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - base = mcbsp->io_base; - + base = mcbsp[id].io_base; writew(buf, base + OMAP_MCBSP_REG_DXR1); /* if frame sync error - clear the error */ if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { @@ -409,8 +366,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) (XRST), base + OMAP_MCBSP_REG_SPCR2); udelay(10); - dev_err(mcbsp->dev, "Could not write to" - " McBSP%d Register\n", mcbsp->id); + dev_err(mcbsp[id].dev, "Could not write to" + " McBSP%d Register\n", mcbsp[id].id); return -2; } } @@ -422,16 +379,14 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite); int omap_mcbsp_pollread(unsigned int id, u16 *buf) { - struct omap_mcbsp *mcbsp; - void __iomem *base; + u32 base; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - base = mcbsp->io_base; + base = mcbsp[id].io_base; /* if frame sync error - clear the error */ if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { /* clear error */ @@ -452,8 +407,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) (RRST), base + OMAP_MCBSP_REG_SPCR1); udelay(10); - dev_err(mcbsp->dev, "Could not read from" - " McBSP%d Register\n", mcbsp->id); + dev_err(mcbsp[id].dev, "Could not read from" + " McBSP%d Register\n", mcbsp[id].id); return -2; } } @@ -469,8 +424,7 @@ EXPORT_SYMBOL(omap_mcbsp_pollread); */ void omap_mcbsp_xmit_word(unsigned int id, u32 word) { - struct omap_mcbsp *mcbsp; - void __iomem *io_base; + u32 io_base; omap_mcbsp_word_length word_length; if (!omap_mcbsp_check_valid_id(id)) { @@ -478,11 +432,10 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word) return; } - mcbsp = id_to_mcbsp_ptr(id); - io_base = mcbsp->io_base; - word_length = mcbsp->tx_word_length; + io_base = mcbsp[id].io_base; + word_length = mcbsp[id].tx_word_length; - wait_for_completion(&mcbsp->tx_irq_completion); + wait_for_completion(&(mcbsp[id].tx_irq_completion)); if (word_length > OMAP_MCBSP_WORD_16) OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); @@ -492,8 +445,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word); u32 omap_mcbsp_recv_word(unsigned int id) { - struct omap_mcbsp *mcbsp; - void __iomem *io_base; + u32 io_base; u16 word_lsb, word_msb = 0; omap_mcbsp_word_length word_length; @@ -501,12 +453,11 @@ u32 omap_mcbsp_recv_word(unsigned int id) printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - word_length = mcbsp->rx_word_length; - io_base = mcbsp->io_base; + word_length = mcbsp[id].rx_word_length; + io_base = mcbsp[id].io_base; - wait_for_completion(&mcbsp->rx_irq_completion); + wait_for_completion(&(mcbsp[id].rx_irq_completion)); if (word_length > OMAP_MCBSP_WORD_16) word_msb = OMAP_MCBSP_READ(io_base, DRR2); @@ -518,8 +469,7 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word); int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) { - struct omap_mcbsp *mcbsp; - void __iomem *io_base; + u32 io_base; omap_mcbsp_word_length tx_word_length; omap_mcbsp_word_length rx_word_length; u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; @@ -528,10 +478,10 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - io_base = mcbsp->io_base; - tx_word_length = mcbsp->tx_word_length; - rx_word_length = mcbsp->rx_word_length; + + io_base = mcbsp[id].io_base; + tx_word_length = mcbsp[id].tx_word_length; + rx_word_length = mcbsp[id].rx_word_length; if (tx_word_length != rx_word_length) return -EINVAL; @@ -546,8 +496,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); udelay(10); - dev_err(mcbsp->dev, "McBSP%d transmitter not " - "ready\n", mcbsp->id); + dev_err(mcbsp[id].dev, "McBSP%d transmitter not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -567,8 +517,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); udelay(10); - dev_err(mcbsp->dev, "McBSP%d receiver not " - "ready\n", mcbsp->id); + dev_err(mcbsp[id].dev, "McBSP%d receiver not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -584,9 +534,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) { - struct omap_mcbsp *mcbsp; - u32 clock_word = 0; - void __iomem *io_base; + u32 io_base, clock_word = 0; omap_mcbsp_word_length tx_word_length; omap_mcbsp_word_length rx_word_length; u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; @@ -596,11 +544,9 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - io_base = mcbsp->io_base; - - tx_word_length = mcbsp->tx_word_length; - rx_word_length = mcbsp->rx_word_length; + io_base = mcbsp[id].io_base; + tx_word_length = mcbsp[id].tx_word_length; + rx_word_length = mcbsp[id].rx_word_length; if (tx_word_length != rx_word_length) return -EINVAL; @@ -615,8 +561,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); udelay(10); - dev_err(mcbsp->dev, "McBSP%d transmitter not " - "ready\n", mcbsp->id); + dev_err(mcbsp[id].dev, "McBSP%d transmitter not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -636,8 +582,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); udelay(10); - dev_err(mcbsp->dev, "McBSP%d receiver not " - "ready\n", mcbsp->id); + dev_err(mcbsp[id].dev, "McBSP%d receiver not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -663,7 +609,6 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { - struct omap_mcbsp *mcbsp; int dma_tx_ch; int src_port = 0; int dest_port = 0; @@ -673,51 +618,50 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX", + if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback, - mcbsp, + &mcbsp[id], &dma_tx_ch)) { - dev_err(mcbsp->dev, " Unable to request DMA channel for " + dev_err(mcbsp[id].dev, " Unable to request DMA channel for " "McBSP%d TX. Trying IRQ based TX\n", - mcbsp->id); + mcbsp[id].id); return -EAGAIN; } - mcbsp->dma_tx_lch = dma_tx_ch; + mcbsp[id].dma_tx_lch = dma_tx_ch; - dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id, + dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, dma_tx_ch); - init_completion(&mcbsp->tx_dma_completion); + init_completion(&(mcbsp[id].tx_dma_completion)); if (cpu_class_is_omap1()) { src_port = OMAP_DMA_PORT_TIPB; dest_port = OMAP_DMA_PORT_EMIFF; } if (cpu_class_is_omap2()) - sync_dev = mcbsp->dma_tx_sync; + sync_dev = mcbsp[id].dma_tx_sync; - omap_set_dma_transfer_params(mcbsp->dma_tx_lch, + omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, OMAP_DMA_DATA_TYPE_S16, length >> 1, 1, OMAP_DMA_SYNC_ELEMENT, sync_dev, 0); - omap_set_dma_dest_params(mcbsp->dma_tx_lch, + omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, src_port, OMAP_DMA_AMODE_CONSTANT, - mcbsp->phys_base + OMAP_MCBSP_REG_DXR1, + mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1, 0, 0); - omap_set_dma_src_params(mcbsp->dma_tx_lch, + omap_set_dma_src_params(mcbsp[id].dma_tx_lch, dest_port, OMAP_DMA_AMODE_POST_INC, buffer, 0, 0); - omap_start_dma(mcbsp->dma_tx_lch); - wait_for_completion(&mcbsp->tx_dma_completion); + omap_start_dma(mcbsp[id].dma_tx_lch); + wait_for_completion(&(mcbsp[id].tx_dma_completion)); return 0; } @@ -726,7 +670,6 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { - struct omap_mcbsp *mcbsp; int dma_rx_ch; int src_port = 0; int dest_port = 0; @@ -736,51 +679,50 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } - mcbsp = id_to_mcbsp_ptr(id); - if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX", + if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback, - mcbsp, + &mcbsp[id], &dma_rx_ch)) { - dev_err(mcbsp->dev, "Unable to request DMA channel for " + dev_err(mcbsp[id].dev, "Unable to request DMA channel for " "McBSP%d RX. Trying IRQ based RX\n", - mcbsp->id); + mcbsp[id].id); return -EAGAIN; } - mcbsp->dma_rx_lch = dma_rx_ch; + mcbsp[id].dma_rx_lch = dma_rx_ch; - dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id, + dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, dma_rx_ch); - init_completion(&mcbsp->rx_dma_completion); + init_completion(&(mcbsp[id].rx_dma_completion)); if (cpu_class_is_omap1()) { src_port = OMAP_DMA_PORT_TIPB; dest_port = OMAP_DMA_PORT_EMIFF; } if (cpu_class_is_omap2()) - sync_dev = mcbsp->dma_rx_sync; + sync_dev = mcbsp[id].dma_rx_sync; - omap_set_dma_transfer_params(mcbsp->dma_rx_lch, + omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, OMAP_DMA_DATA_TYPE_S16, length >> 1, 1, OMAP_DMA_SYNC_ELEMENT, sync_dev, 0); - omap_set_dma_src_params(mcbsp->dma_rx_lch, + omap_set_dma_src_params(mcbsp[id].dma_rx_lch, src_port, OMAP_DMA_AMODE_CONSTANT, - mcbsp->phys_base + OMAP_MCBSP_REG_DRR1, + mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1, 0, 0); - omap_set_dma_dest_params(mcbsp->dma_rx_lch, + omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, dest_port, OMAP_DMA_AMODE_POST_INC, buffer, 0, 0); - omap_start_dma(mcbsp->dma_rx_lch); - wait_for_completion(&mcbsp->rx_dma_completion); + omap_start_dma(mcbsp[id].dma_rx_lch); + wait_for_completion(&(mcbsp[id].rx_dma_completion)); return 0; } @@ -795,14 +737,12 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer); void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg *spi_cfg) { - struct omap_mcbsp *mcbsp; struct omap_mcbsp_reg_cfg mcbsp_cfg; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; } - mcbsp = id_to_mcbsp_ptr(id); memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); @@ -863,10 +803,9 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. * 730 has only 2 McBSP, and both of them are MPU peripherals. */ -static int __devinit omap_mcbsp_probe(struct platform_device *pdev) +static int __init omap_mcbsp_probe(struct platform_device *pdev) { struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; - struct omap_mcbsp *mcbsp; int id = pdev->id - 1; int ret = 0; @@ -879,63 +818,47 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); - if (id >= omap_mcbsp_count) { + if (id >= OMAP_MAX_MCBSP_COUNT) { dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); ret = -EINVAL; goto exit; } - mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL); - if (!mcbsp) { - ret = -ENOMEM; - goto exit; - } - mcbsp_ptr[id] = mcbsp; - - spin_lock_init(&mcbsp->lock); - mcbsp->id = id + 1; - mcbsp->free = 1; - mcbsp->dma_tx_lch = -1; - mcbsp->dma_rx_lch = -1; - - mcbsp->phys_base = pdata->phys_base; - mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K); - if (!mcbsp->io_base) { - ret = -ENOMEM; - goto err_ioremap; - } + spin_lock_init(&mcbsp[id].lock); + mcbsp[id].id = id + 1; + mcbsp[id].free = 1; + mcbsp[id].dma_tx_lch = -1; + mcbsp[id].dma_rx_lch = -1; + mcbsp[id].phys_base = pdata->phys_base; + mcbsp[id].io_base = pdata->virt_base; /* Default I/O is IRQ based */ - mcbsp->io_type = OMAP_MCBSP_IRQ_IO; - mcbsp->tx_irq = pdata->tx_irq; - mcbsp->rx_irq = pdata->rx_irq; - mcbsp->dma_rx_sync = pdata->dma_rx_sync; - mcbsp->dma_tx_sync = pdata->dma_tx_sync; + mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; + mcbsp[id].tx_irq = pdata->tx_irq; + mcbsp[id].rx_irq = pdata->rx_irq; + mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; + mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; if (pdata->clk_name) - mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name); - if (IS_ERR(mcbsp->clk)) { + mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); + if (IS_ERR(mcbsp[id].clk)) { + mcbsp[id].free = 0; dev_err(&pdev->dev, "Invalid clock configuration for McBSP%d.\n", - mcbsp->id); - ret = PTR_ERR(mcbsp->clk); - goto err_clk; + mcbsp[id].id); + ret = -EINVAL; + goto exit; } - mcbsp->pdata = pdata; - mcbsp->dev = &pdev->dev; - platform_set_drvdata(pdev, mcbsp); - return 0; + mcbsp[id].pdata = pdata; + mcbsp[id].dev = &pdev->dev; + platform_set_drvdata(pdev, &mcbsp[id]); -err_clk: - iounmap(mcbsp->io_base); -err_ioremap: - mcbsp->free = 0; exit: return ret; } -static int __devexit omap_mcbsp_remove(struct platform_device *pdev) +static int omap_mcbsp_remove(struct platform_device *pdev) { struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); @@ -949,8 +872,6 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) clk_disable(mcbsp->clk); clk_put(mcbsp->clk); - iounmap(mcbsp->io_base); - mcbsp->clk = NULL; mcbsp->free = 0; mcbsp->dev = NULL; @@ -961,7 +882,7 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) static struct platform_driver omap_mcbsp_driver = { .probe = omap_mcbsp_probe, - .remove = __devexit_p(omap_mcbsp_remove), + .remove = omap_mcbsp_remove, .driver = { .name = "omap-mcbsp", }, diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index 9f9a921829c0..e0003e0746e7 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -271,7 +271,7 @@ int __init omap1_sram_init(void) #define omap1_sram_init() do {} while (0) #endif -#if defined(CONFIG_ARCH_OMAP2) +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, u32 base_cs, u32 force_unlock); @@ -352,19 +352,23 @@ static inline int omap243x_sram_init(void) #ifdef CONFIG_ARCH_OMAP3 -static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl, - u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, - u32 m2); -u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, u32 m2) +static u32 (*_omap2_sram_reprogram_gpmc)(u32 perf_level); +u32 omap2_sram_reprogram_gpmc(u32 perf_level) +{ + if (!_omap2_sram_reprogram_gpmc) + omap_sram_error(); + + return _omap2_sram_reprogram_gpmc(perf_level); +} + +static u32 (*_omap2_sram_configure_core_dpll)(u32 m, u32 n, + u32 freqsel, u32 m2); +u32 omap2_sram_configure_core_dpll(u32 m, u32 n, u32 freqsel, u32 m2) { - if (!_omap3_sram_configure_core_dpll) + if (!_omap2_sram_configure_core_dpll) omap_sram_error(); - return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl, - sdrc_actim_ctrla, - sdrc_actim_ctrlb, m2); + return _omap2_sram_configure_core_dpll(m, n, freqsel, m2); } /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ @@ -372,16 +376,31 @@ void restore_sram_functions(void) { omap_sram_ceil = omap_sram_base + omap_sram_size; - _omap3_sram_configure_core_dpll = - omap_sram_push(omap3_sram_configure_core_dpll, - omap3_sram_configure_core_dpll_sz); + _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc, + omap34xx_sram_reprogram_gpmc_sz); + + _omap2_sram_configure_core_dpll = + omap_sram_push(omap34xx_sram_configure_core_dpll, + omap34xx_sram_configure_core_dpll_sz); } int __init omap34xx_sram_init(void) { - _omap3_sram_configure_core_dpll = - omap_sram_push(omap3_sram_configure_core_dpll, - omap3_sram_configure_core_dpll_sz); + _omap2_sram_ddr_init = omap_sram_push(omap34xx_sram_ddr_init, + omap34xx_sram_ddr_init_sz); + + _omap2_sram_reprogram_sdrc = omap_sram_push(omap34xx_sram_reprogram_sdrc, + omap34xx_sram_reprogram_sdrc_sz); + + _omap2_set_prcm = omap_sram_push(omap34xx_sram_set_prcm, + omap34xx_sram_set_prcm_sz); + + _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc, + omap34xx_sram_reprogram_gpmc_sz); + + _omap2_sram_configure_core_dpll = + omap_sram_push(omap34xx_sram_configure_core_dpll, + omap34xx_sram_configure_core_dpll_sz); return 0; } diff --git a/trunk/arch/arm/plat-s3c/Makefile b/trunk/arch/arm/plat-s3c/Makefile deleted file mode 100644 index f03d7b35ba37..000000000000 --- a/trunk/arch/arm/plat-s3c/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# dummy makefile, currently just including asm/arm/plat-s3c/include/plat - -obj-n := dummy.o diff --git a/trunk/arch/arm/plat-s3c24xx/clock.c b/trunk/arch/arm/plat-s3c24xx/clock.c index a005ddbd9ef3..400541359bfb 100644 --- a/trunk/arch/arm/plat-s3c24xx/clock.c +++ b/trunk/arch/arm/plat-s3c24xx/clock.c @@ -47,8 +47,8 @@ #include #include -#include -#include +#include +#include /* clock information */ diff --git a/trunk/arch/arm/plat-s3c24xx/common-smdk.c b/trunk/arch/arm/plat-s3c24xx/common-smdk.c index 3098736c65d9..d528f460f6bc 100644 --- a/trunk/arch/arm/plat-s3c24xx/common-smdk.c +++ b/trunk/arch/arm/plat-s3c24xx/common-smdk.c @@ -40,9 +40,9 @@ #include -#include -#include -#include +#include +#include +#include /* LED devices */ diff --git a/trunk/arch/arm/plat-s3c24xx/cpu.c b/trunk/arch/arm/plat-s3c24xx/cpu.c index 22a329513c0f..9c607bbc9343 100644 --- a/trunk/arch/arm/plat-s3c24xx/cpu.c +++ b/trunk/arch/arm/plat-s3c24xx/cpu.c @@ -42,18 +42,18 @@ #include #include -#include - -#include -#include -#include -#include -#include -#include +#include + +#include +#include +#include +#include +#include +#include #include "s3c244x.h" -#include -#include -#include +#include +#include +#include struct cpu_table { unsigned long idcode; diff --git a/trunk/arch/arm/plat-s3c24xx/devs.c b/trunk/arch/arm/plat-s3c24xx/devs.c index e93f8bf6d338..6b13b5455dfc 100644 --- a/trunk/arch/arm/plat-s3c24xx/devs.c +++ b/trunk/arch/arm/plat-s3c24xx/devs.c @@ -28,11 +28,11 @@ #include #include -#include +#include #include -#include -#include +#include +#include #include /* Serial port registrations */ diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c index 1baf941d1930..d6344461a83b 100644 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ b/trunk/arch/arm/plat-s3c24xx/dma.c @@ -36,7 +36,7 @@ #include #include -#include +#include /* io map for dma */ static void __iomem *dma_base; diff --git a/trunk/arch/arm/plat-s3c24xx/irq.c b/trunk/arch/arm/plat-s3c24xx/irq.c index 963f7a4f26f2..590fc5a3ab06 100644 --- a/trunk/arch/arm/plat-s3c24xx/irq.c +++ b/trunk/arch/arm/plat-s3c24xx/irq.c @@ -65,9 +65,9 @@ #include #include -#include -#include -#include +#include +#include +#include /* wakeup irq control */ diff --git a/trunk/arch/arm/plat-s3c24xx/pm-simtec.c b/trunk/arch/arm/plat-s3c24xx/pm-simtec.c index 21dfa74773d1..0a074d35890a 100644 --- a/trunk/arch/arm/plat-s3c24xx/pm-simtec.c +++ b/trunk/arch/arm/plat-s3c24xx/pm-simtec.c @@ -33,7 +33,7 @@ #include -#include +#include #define COPYRIGHT ", (c) 2005 Simtec Electronics" diff --git a/trunk/arch/arm/plat-s3c24xx/pm.c b/trunk/arch/arm/plat-s3c24xx/pm.c index 8efb57ad5019..d3934b1119a9 100644 --- a/trunk/arch/arm/plat-s3c24xx/pm.c +++ b/trunk/arch/arm/plat-s3c24xx/pm.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include #include @@ -48,7 +48,7 @@ #include -#include +#include /* for external use */ diff --git a/trunk/arch/arm/plat-s3c24xx/pwm-clock.c b/trunk/arch/arm/plat-s3c24xx/pwm-clock.c index b8e854f1b1d5..306cc9c6f9ef 100644 --- a/trunk/arch/arm/plat-s3c24xx/pwm-clock.c +++ b/trunk/arch/arm/plat-s3c24xx/pwm-clock.c @@ -24,10 +24,10 @@ #include #include -#include -#include +#include +#include -#include +#include /* Each of the timers 0 through 5 go through the following * clock tree, with the inputs depending on the timers. diff --git a/trunk/arch/arm/plat-s3c24xx/pwm.c b/trunk/arch/arm/plat-s3c24xx/pwm.c index feb770f2e84e..7a92c938542a 100644 --- a/trunk/arch/arm/plat-s3c24xx/pwm.c +++ b/trunk/arch/arm/plat-s3c24xx/pwm.c @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include struct pwm_device { struct list_head list; diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x-clock.c b/trunk/arch/arm/plat-s3c24xx/s3c244x-clock.c index 7c09773ff9fc..119647a5eaa6 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x-clock.c +++ b/trunk/arch/arm/plat-s3c24xx/s3c244x-clock.c @@ -41,8 +41,8 @@ #include -#include -#include +#include +#include static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent) { diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c b/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c index 0902afd227ca..0601c5f3230b 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c +++ b/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c @@ -34,9 +34,9 @@ #include #include -#include -#include -#include +#include +#include +#include /* camera irq */ diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x.c b/trunk/arch/arm/plat-s3c24xx/s3c244x.c index c0344fac4a94..146863a69aeb 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x.c +++ b/trunk/arch/arm/plat-s3c24xx/s3c244x.c @@ -30,18 +30,18 @@ #include #include -#include +#include #include #include #include -#include -#include +#include +#include #include "s3c244x.h" -#include -#include -#include -#include +#include +#include +#include +#include static struct map_desc s3c244x_iodesc[] __initdata = { IODESC_ENT(CLKPWR), diff --git a/trunk/arch/arm/plat-s3c24xx/sleep.S b/trunk/arch/arm/plat-s3c24xx/sleep.S index 76594b212802..4981a08b6ebb 100644 --- a/trunk/arch/arm/plat-s3c24xx/sleep.S +++ b/trunk/arch/arm/plat-s3c24xx/sleep.S @@ -32,7 +32,7 @@ #include #include #include -#include +#include /* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not * reset the UART configuration, only enable if you really need this! diff --git a/trunk/arch/arm/plat-s3c24xx/time.c b/trunk/arch/arm/plat-s3c24xx/time.c index c51916236ac0..64bfa19ae951 100644 --- a/trunk/arch/arm/plat-s3c24xx/time.c +++ b/trunk/arch/arm/plat-s3c24xx/time.c @@ -33,12 +33,12 @@ #include #include -#include +#include #include #include -#include -#include +#include +#include static unsigned long timer_startval; static unsigned long timer_usec_ticks; diff --git a/trunk/arch/avr32/include/asm/a.out.h b/trunk/arch/avr32/include/asm/a.out.h new file mode 100644 index 000000000000..e46375a34a72 --- /dev/null +++ b/trunk/arch/avr32/include/asm/a.out.h @@ -0,0 +1,20 @@ +#ifndef __ASM_AVR32_A_OUT_H +#define __ASM_AVR32_A_OUT_H + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#endif /* __ASM_AVR32_A_OUT_H */ diff --git a/trunk/arch/avr32/include/asm/elf.h b/trunk/arch/avr32/include/asm/elf.h index d5d1d41c600a..64ce40ee1d58 100644 --- a/trunk/arch/avr32/include/asm/elf.h +++ b/trunk/arch/avr32/include/asm/elf.h @@ -103,6 +103,6 @@ typedef struct user_fpu_struct elf_fpregset_t; #define ELF_PLATFORM (NULL) -#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT) +#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) #endif /* __ASM_AVR32_ELF_H */ diff --git a/trunk/arch/avr32/mach-at32ap/cpufreq.c b/trunk/arch/avr32/mach-at32ap/cpufreq.c index d84efe4984ab..5dd8d25428bf 100644 --- a/trunk/arch/avr32/mach-at32ap/cpufreq.c +++ b/trunk/arch/avr32/mach-at32ap/cpufreq.c @@ -87,6 +87,7 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy) policy->cur = at32_get_speed(0); policy->min = policy->cpuinfo.min_freq; policy->max = policy->cpuinfo.max_freq; + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; printk("cpufreq: AT32AP CPU frequency driver\n"); diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index 8102c79aaa94..4154ff1101fa 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -162,28 +162,16 @@ config BF549 config BF561 bool "BF561" help - BF561 Processor Support. + Not Supported Yet - Work in progress - BF561 Processor Support. endchoice -config BF_REV_MIN - int - default 0 if (BF52x || BF54x) - default 2 if (BF537 || BF536 || BF534) - default 3 if (BF561 ||BF533 || BF532 || BF531) - -config BF_REV_MAX - int - default 2 if (BF52x || BF54x) - default 3 if (BF537 || BF536 || BF534) - default 5 if (BF561) - default 6 if (BF533 || BF532 || BF531) - choice prompt "Silicon Rev" - default BF_REV_0_1 if (BF52x || BF54x) - default BF_REV_0_2 if (BF534 || BF536 || BF537) - default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF561) + default BF_REV_0_1 if BF527 + default BF_REV_0_2 if BF537 + default BF_REV_0_3 if BF533 + default BF_REV_0_0 if BF549 config BF_REV_0_0 bool "0.0" @@ -195,7 +183,7 @@ config BF_REV_0_1 config BF_REV_0_2 bool "0.2" - depends on (BF52x || BF537 || BF536 || BF534 || BF54x) + depends on (BF537 || BF536 || BF534) config BF_REV_0_3 bool "0.3" @@ -209,10 +197,6 @@ config BF_REV_0_5 bool "0.5" depends on (BF561 || BF533 || BF532 || BF531) -config BF_REV_0_6 - bool "0.6" - depends on (BF533 || BF532 || BF531) - config BF_REV_ANY bool "any" @@ -265,7 +249,7 @@ config MEM_MT48LC8M32B2B5_7 config MEM_MT48LC32M16A2TG_75 bool - depends on (BFIN527_EZKIT || BFIN532_IP0X || BLACKSTAMP || BFIN526_EZBRD) + depends on (BFIN527_EZKIT || BFIN532_IP0X || BLACKSTAMP) default y source "arch/blackfin/mach-bf527/Kconfig" @@ -302,20 +286,13 @@ config BOOT_LOAD memory region is used to capture NULL pointer references as well as some core kernel functions. -config ROM_BASE - hex "Kernel ROM Base" - default "0x20040000" - range 0x20000000 0x20400000 if !(BF54x || BF561) - range 0x20000000 0x30000000 if (BF54x || BF561) - help - comment "Clock/PLL Setup" config CLKIN_HZ int "Frequency of the crystal on the board in Hz" default "11059200" if BFIN533_STAMP default "27000000" if BFIN533_EZKIT - default "25000000" if (BFIN537_STAMP || BFIN527_EZKIT || H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD) + default "25000000" if (BFIN537_STAMP || BFIN527_EZKIT || H8606_HVSISTEMAS || BLACKSTAMP) default "30000000" if BFIN561_EZKIT default "24576000" if PNAV10 default "10000000" if BFIN532_IP0X @@ -355,7 +332,7 @@ config VCO_MULT default "22" if BFIN533_BLUETECHNIX_CM default "20" if (BFIN537_BLUETECHNIX_CM || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) default "20" if BFIN561_EZKIT - default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD) + default "16" if (H8606_HVSISTEMAS || BLACKSTAMP) help This controls the frequency of the on-chip PLL. This can be between 1 and 64. PLL Frequency = (Crystal Frequency) * (this setting) @@ -391,6 +368,14 @@ config SCLK_DIV This can be between 1 and 15 System Clock = (PLL frequency) / (this setting) +config MAX_MEM_SIZE + int "Max SDRAM Memory Size in MBytes" + depends on !MPU + default 512 + help + This is the max memory size that the kernel will create CPLB + tables for. Your system will not be able to handle any more. + choice prompt "DDR SDRAM Chip Type" depends on BFIN_KERNEL_CLOCK @@ -404,14 +389,6 @@ config MEM_MT46V32M16_5B bool "MT46V32M16_5B" endchoice -config MAX_MEM_SIZE - int "Max SDRAM Memory Size in MBytes" - depends on !MPU - default 512 - help - This is the max memory size that the kernel will create CPLB - tables for. Your system will not be able to handle any more. - # # Max & Min Speeds for various Chips # @@ -478,6 +455,8 @@ config CYCLES_CLOCKSOURCE source kernel/time/Kconfig +comment "Memory Setup" + comment "Misc" choice @@ -643,15 +622,6 @@ config CPLB_SWITCH_TAB_L1 If enabled, the CPLB Switch Tables are linked into L1 data memory. (less latency) -config APP_STACK_L1 - bool "Support locating application stack in L1 Scratch Memory" - default y - help - If enabled the application stack can be located in L1 - scratch memory (less latency). - - Currently only works with FLAT binaries. - comment "Speed Optimizations" config BFIN_INS_LOWOVERHEAD bool "ins[bwl] low overhead, higher interrupt latency" @@ -785,13 +755,6 @@ config BFIN_WT endchoice -config BFIN_L2_CACHEABLE - bool "Cache L2 SRAM" - depends on (BFIN_DCACHE || BFIN_ICACHE) && (BF54x || BF561) - default n - help - Select to make L2 SRAM cacheable in L1 data and instruction cache. - config MPU bool "Enable the memory protection unit (EXPERIMENTAL)" default n diff --git a/trunk/arch/blackfin/Kconfig.debug b/trunk/arch/blackfin/Kconfig.debug index 3ad25983ec97..c468624d55f0 100644 --- a/trunk/arch/blackfin/Kconfig.debug +++ b/trunk/arch/blackfin/Kconfig.debug @@ -2,22 +2,6 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config HAVE_ARCH_KGDB - def_bool y - -config DEBUG_VERBOSE - bool "Verbose fault messages" - default y - select PRINTK - help - When a program crashes due to an exception, or the kernel detects - an internal error, the kernel can print a not so brief message - explaining what the problem was. This debugging information is - useful to developers and kernel hackers when tracking down problems, - but mostly meaningless to other people. This is always helpful for - debugging but serves no purpose on a production system. - Most people should say N here. - config DEBUG_MMRS bool "Generate Blackfin MMR tree" select DEBUG_FS @@ -38,44 +22,6 @@ config DEBUG_HWERR hardware error interrupts and need to know where they are coming from. -config DEBUG_DOUBLEFAULT - bool "Debug Double Faults" - default n - help - If an exception is caused while executing code within the exception - handler, the NMI handler, the reset vector, or in emulator mode, - a double fault occurs. On the Blackfin, this is a unrecoverable - event. You have two options: - - RESET exactly when double fault occurs. The excepting - instruction address is stored in RETX, where the next kernel - boot will print it out. - - Print debug message. This is much more error prone, although - easier to handle. It is error prone since: - - The excepting instruction is not committed. - - All writebacks from the instruction are prevented. - - The generated exception is not taken. - - The EXCAUSE field is updated with an unrecoverable event - The only way to check this is to see if EXCAUSE contains the - unrecoverable event value at every exception return. By selecting - this option, you are skipping over the faulting instruction, and - hoping things stay together enough to print out a debug message. - - This does add a little kernel code, but is the only method to debug - double faults - if unsure say "Y" - -choice - prompt "Double Fault Failure Method" - default DEBUG_DOUBLEFAULT_PRINT - depends on DEBUG_DOUBLEFAULT - -config DEBUG_DOUBLEFAULT_PRINT - bool "Print" - -config DEBUG_DOUBLEFAULT_RESET - bool "Reset" - -endchoice - config DEBUG_ICACHE_CHECK bool "Check Instruction cache coherency" depends on DEBUG_KERNEL @@ -197,7 +143,6 @@ config DEBUG_BFIN_NO_KERN_HWTRACE config EARLY_PRINTK bool "Early printk" default n - select SERIAL_CORE_CONSOLE help This option enables special console drivers which allow the kernel to print messages very early in the bootup process. diff --git a/trunk/arch/blackfin/Makefile b/trunk/arch/blackfin/Makefile index 6bf50977850c..eac0533d6e4f 100644 --- a/trunk/arch/blackfin/Makefile +++ b/trunk/arch/blackfin/Makefile @@ -67,7 +67,6 @@ rev-$(CONFIG_BF_REV_0_2) := 0.2 rev-$(CONFIG_BF_REV_0_3) := 0.3 rev-$(CONFIG_BF_REV_0_4) := 0.4 rev-$(CONFIG_BF_REV_0_5) := 0.5 -rev-$(CONFIG_BF_REV_0_6) := 0.6 rev-$(CONFIG_BF_REV_NONE) := none rev-$(CONFIG_BF_REV_ANY) := any diff --git a/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig b/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig deleted file mode 100644 index 4443a47e516f..000000000000 --- a/trunk/arch/blackfin/configs/BF526-EZBRD_defconfig +++ /dev/null @@ -1,1427 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26.3 -# Thu Aug 28 16:49:53 2008 -# -# CONFIG_MMU is not set -# CONFIG_FPU is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BLACKFIN=y -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_GPIO=y -CONFIG_FORCE_MAX_ZONEORDER=14 -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -# CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -# CONFIG_HAVE_KRETPROBES is not set -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" -CONFIG_CLASSIC_RCU=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set - -# -# Blackfin Processor Options -# - -# -# Processor and Board Settings -# -# CONFIG_BF522 is not set -# CONFIG_BF523 is not set -# CONFIG_BF524 is not set -# CONFIG_BF525 is not set -CONFIG_BF526=y -# CONFIG_BF527 is not set -# CONFIG_BF531 is not set -# CONFIG_BF532 is not set -# CONFIG_BF533 is not set -# CONFIG_BF534 is not set -# CONFIG_BF536 is not set -# CONFIG_BF537 is not set -# CONFIG_BF542 is not set -# CONFIG_BF544 is not set -# CONFIG_BF547 is not set -# CONFIG_BF548 is not set -# CONFIG_BF549 is not set -# CONFIG_BF561 is not set -CONFIG_BF_REV_0_0=y -# CONFIG_BF_REV_0_1 is not set -# CONFIG_BF_REV_0_2 is not set -# CONFIG_BF_REV_0_3 is not set -# CONFIG_BF_REV_0_4 is not set -# CONFIG_BF_REV_0_5 is not set -# CONFIG_BF_REV_ANY is not set -# CONFIG_BF_REV_NONE is not set -CONFIG_BF52x=y -CONFIG_MEM_MT48LC32M16A2TG_75=y -# CONFIG_BFIN527_EZKIT is not set -# CONFIG_BFIN527_BLUETECHNIX_CM is not set -CONFIG_BFIN526_EZBRD=y - -# -# BF527 Specific Configuration -# - -# -# Alternative Multiplexing Scheme -# -# CONFIG_BF527_SPORT0_PORTF is not set -CONFIG_BF527_SPORT0_PORTG=y -CONFIG_BF527_SPORT0_TSCLK_PG10=y -# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set -CONFIG_BF527_UART1_PORTF=y -# CONFIG_BF527_UART1_PORTG is not set -# CONFIG_BF527_NAND_D_PORTF is not set -CONFIG_BF527_NAND_D_PORTH=y - -# -# Interrupt Priority Assignment -# - -# -# Priority -# -CONFIG_IRQ_PLL_WAKEUP=7 -CONFIG_IRQ_DMA0_ERROR=7 -CONFIG_IRQ_DMAR0_BLK=7 -CONFIG_IRQ_DMAR1_BLK=7 -CONFIG_IRQ_DMAR0_OVR=7 -CONFIG_IRQ_DMAR1_OVR=7 -CONFIG_IRQ_PPI_ERROR=7 -CONFIG_IRQ_MAC_ERROR=7 -CONFIG_IRQ_SPORT0_ERROR=7 -CONFIG_IRQ_SPORT1_ERROR=7 -CONFIG_IRQ_UART0_ERROR=7 -CONFIG_IRQ_UART1_ERROR=7 -CONFIG_IRQ_RTC=8 -CONFIG_IRQ_PPI=8 -CONFIG_IRQ_SPORT0_RX=9 -CONFIG_IRQ_SPORT0_TX=9 -CONFIG_IRQ_SPORT1_RX=9 -CONFIG_IRQ_SPORT1_TX=9 -CONFIG_IRQ_TWI=10 -CONFIG_IRQ_SPI=10 -CONFIG_IRQ_UART0_RX=10 -CONFIG_IRQ_UART0_TX=10 -CONFIG_IRQ_UART1_RX=10 -CONFIG_IRQ_UART1_TX=10 -CONFIG_IRQ_OPTSEC=11 -CONFIG_IRQ_CNT=11 -CONFIG_IRQ_MAC_RX=11 -CONFIG_IRQ_PORTH_INTA=11 -CONFIG_IRQ_MAC_TX=11 -CONFIG_IRQ_PORTH_INTB=11 -CONFIG_IRQ_TMR0=12 -CONFIG_IRQ_TMR1=12 -CONFIG_IRQ_TMR2=12 -CONFIG_IRQ_TMR3=12 -CONFIG_IRQ_TMR4=12 -CONFIG_IRQ_TMR5=12 -CONFIG_IRQ_TMR6=12 -CONFIG_IRQ_TMR7=12 -CONFIG_IRQ_PORTG_INTA=12 -CONFIG_IRQ_PORTG_INTB=12 -CONFIG_IRQ_MEM_DMA0=13 -CONFIG_IRQ_MEM_DMA1=13 -CONFIG_IRQ_WATCH=13 -CONFIG_IRQ_PORTF_INTA=13 -CONFIG_IRQ_PORTF_INTB=13 -CONFIG_IRQ_SPI_ERROR=7 -CONFIG_IRQ_NFC_ERROR=7 -CONFIG_IRQ_HDMA_ERROR=7 -CONFIG_IRQ_HDMA=7 -CONFIG_IRQ_USB_EINT=10 -CONFIG_IRQ_USB_INT0=11 -CONFIG_IRQ_USB_INT1=11 -CONFIG_IRQ_USB_INT2=11 -CONFIG_IRQ_USB_DMA=11 - -# -# Board customizations -# -# CONFIG_CMDLINE_BOOL is not set -CONFIG_BOOT_LOAD=0x1000 - -# -# Clock/PLL Setup -# -CONFIG_CLKIN_HZ=25000000 -# CONFIG_BFIN_KERNEL_CLOCK is not set -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MAX_VCO_HZ=400000000 -CONFIG_MIN_VCO_HZ=50000000 -CONFIG_MAX_SCLK_HZ=133333333 -CONFIG_MIN_SCLK_HZ=27000000 - -# -# Kernel Timer/Scheduler -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -# CONFIG_CYCLES_CLOCKSOURCE is not set -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y - -# -# Memory Setup -# - -# -# Misc -# -CONFIG_BFIN_SCRATCH_REG_RETN=y -# CONFIG_BFIN_SCRATCH_REG_RETE is not set -# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set - -# -# Blackfin Kernel Optimizations -# - -# -# Memory Optimizations -# -CONFIG_I_ENTRY_L1=y -CONFIG_EXCPT_IRQ_SYSC_L1=y -CONFIG_DO_IRQ_L1=y -CONFIG_CORE_TIMER_IRQ_L1=y -CONFIG_IDLE_L1=y -# CONFIG_SCHEDULE_L1 is not set -CONFIG_ARITHMETIC_OPS_L1=y -CONFIG_ACCESS_OK_L1=y -# CONFIG_MEMSET_L1 is not set -# CONFIG_MEMCPY_L1 is not set -# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set -# CONFIG_IP_CHECKSUM_L1 is not set -CONFIG_CACHELINE_ALIGNED_L1=y -# CONFIG_SYSCALL_TAB_L1 is not set -# CONFIG_CPLB_SWITCH_TAB_L1 is not set - -# -# Speed Optimizations -# -CONFIG_BFIN_INS_LOWOVERHEAD=y -CONFIG_RAMKERNEL=y -# CONFIG_ROMKERNEL is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y -CONFIG_BFIN_GPTIMERS=y -CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_4M is not set -# CONFIG_DMA_UNCACHED_2M is not set -CONFIG_DMA_UNCACHED_1M=y -# CONFIG_DMA_UNCACHED_NONE is not set - -# -# Cache Support -# -CONFIG_BFIN_ICACHE=y -CONFIG_BFIN_DCACHE=y -# CONFIG_BFIN_DCACHE_BANKA is not set -# CONFIG_BFIN_ICACHE_LOCK is not set -CONFIG_BFIN_WB=y -# CONFIG_BFIN_WT is not set -# CONFIG_MPU is not set - -# -# Asynchonous Memory Configuration -# - -# -# EBIU_AMGCTL Global Control -# -CONFIG_C_AMCKEN=y -CONFIG_C_CDPRIO=y -# CONFIG_C_AMBEN is not set -# CONFIG_C_AMBEN_B0 is not set -# CONFIG_C_AMBEN_B0_B1 is not set -# CONFIG_C_AMBEN_B0_B1_B2 is not set -CONFIG_C_AMBEN_ALL=y - -# -# EBIU_AMBCTL Control -# -CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 -CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC0 - -# -# Bus options (PCI, PCMCIA, EISA, MCA, ISA) -# -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF_FDPIC=y -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -# CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -# CONFIG_PM is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM_WAKEUP_BY_GPIO is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_RAM=y -CONFIG_MTD_ROM=m -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_GPIO_ADDR is not set -# CONFIG_MTD_UCLINUX is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND=m -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_BFIN=m -CONFIG_BFIN_NAND_BASE=0x20212000 -CONFIG_BFIN_NAND_CLE=2 -CONFIG_BFIN_NAND_ALE=1 -CONFIG_BFIN_NAND_READY=3 -CONFIG_MTD_NAND_IDS=m -# CONFIG_MTD_NAND_BF5XX is not set -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_ALAUDA is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_BFIN_MAC=y -CONFIG_BFIN_TX_DESC_NUM=10 -CONFIG_BFIN_RX_DESC_NUM=20 -CONFIG_BFIN_MAC_RMII=y -# CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set -# CONFIG_DM9000 is not set -# CONFIG_ENC28J60 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -CONFIG_NETDEV_1000=y -# CONFIG_E1000E_ENABLED is not set -# CONFIG_AX88180 is not set -CONFIG_NETDEV_10000=y - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_UINPUT is not set -# CONFIG_TWI_KEYPAD is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PPIFCD is not set -# CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set -# CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_BFIN=y -CONFIG_SERIAL_BFIN_CONSOLE=y -CONFIG_SERIAL_BFIN_DMA=y -# CONFIG_SERIAL_BFIN_PIO is not set -# CONFIG_SERIAL_BFIN_UART0 is not set -CONFIG_SERIAL_BFIN_UART1=y -# CONFIG_BFIN_UART1_CTSRTS is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_BFIN_SPORT is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_BFIN_OTP=y -# CONFIG_BFIN_OTP_WRITE_ENABLE is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# -CONFIG_I2C_BLACKFIN_TWI=y -CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_TINY_USB is not set -# CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_BFIN=y -# CONFIG_SPI_BITBANG is not set - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -# CONFIG_SND_SEQUENCER is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# SPI devices -# - -# -# ALSA Blackfin devices -# -# CONFIG_SND_BLACKFIN_AD1836 is not set -# CONFIG_SND_BFIN_AD73311 is not set -# CONFIG_SND_BFIN_AD73322 is not set - -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set - -# -# System on Chip audio support -# -CONFIG_SND_SOC=m -CONFIG_SND_BF5XX_I2S=m -CONFIG_SND_BF5XX_SOC_SSM2602=m -# CONFIG_SND_BF5XX_AC97 is not set -CONFIG_SND_BF5XX_SOC_SPORT=m -CONFIG_SND_BF5XX_SOC_I2S=m -CONFIG_SND_BF5XX_SPORT_NUM=0 - -# -# ALSA SoC audio for Freescale SOCs -# - -# -# SoC Audio for the Texas Instruments OMAP -# -CONFIG_SND_SOC_SSM2602=m - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -CONFIG_USB_OTG_BLACKLIST_HUB=y - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_MUSB_HDRC=y -CONFIG_USB_MUSB_SOC=y - -# -# Blackfin high speed USB support -# -CONFIG_USB_MUSB_HOST=y -# CONFIG_USB_MUSB_PERIPHERAL is not set -# CONFIG_USB_MUSB_OTG is not set -CONFIG_USB_MUSB_HDRC_HCD=y -CONFIG_MUSB_PIO_ONLY=y -CONFIG_USB_MUSB_LOGLEVEL=0 - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_BFIN=y -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_DNOTIFY is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y -CONFIG_JFFS2_FS=m -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set -CONFIG_DEBUG_MMRS=y -CONFIG_DEBUG_HUNT_FOR_ZERO=y -CONFIG_DEBUG_BFIN_HWTRACE_ON=y -CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y -# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set -# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set -CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 -# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set -# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -CONFIG_EARLY_PRINTK=y -CONFIG_CPLB_INFO=y -CONFIG_ACCESS_CHECK=y - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -# CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig index 4a2a660a6b35..66854a83c0de 100644 --- a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -772,7 +772,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set diff --git a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig index deeb5e45effb..6bc11db12690 100644 --- a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -674,7 +674,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -740,7 +740,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig index c23267ed880b..d77d991a1f61 100644 --- a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig @@ -681,7 +681,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set diff --git a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig index 63a0f854745c..5fd7c4b143df 100644 --- a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig @@ -731,7 +731,7 @@ CONFIG_CAN4LINUX=y # CONFIG_CAN_UNCTWINCAN is not set CONFIG_CAN_BLACKFIN=m # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -871,7 +871,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig index bf63660815b9..390669e8668e 100644 --- a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -855,7 +855,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -1001,7 +1001,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # CONFIG_USB_DABUSB is not set # diff --git a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig index 3c70d6230a12..976a4d7ba175 100644 --- a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -719,7 +719,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -785,7 +785,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/CM-BF527_defconfig b/trunk/arch/blackfin/configs/CM-BF527_defconfig index b6a14635fb91..0799aa9bba9d 100644 --- a/trunk/arch/blackfin/configs/CM-BF527_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF527_defconfig @@ -679,7 +679,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set diff --git a/trunk/arch/blackfin/configs/CM-BF533_defconfig b/trunk/arch/blackfin/configs/CM-BF533_defconfig index c3ba9066b935..09deea44480b 100644 --- a/trunk/arch/blackfin/configs/CM-BF533_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF533_defconfig @@ -672,7 +672,7 @@ CONFIG_HWMON=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/CM-BF537E_defconfig b/trunk/arch/blackfin/configs/CM-BF537E_defconfig index cdc6b7feb59e..219fc345a5f5 100644 --- a/trunk/arch/blackfin/configs/CM-BF537E_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF537E_defconfig @@ -703,7 +703,7 @@ CONFIG_HWMON=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/CM-BF537U_defconfig b/trunk/arch/blackfin/configs/CM-BF537U_defconfig index f074bdcd1ce5..9873d586fc77 100644 --- a/trunk/arch/blackfin/configs/CM-BF537U_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF537U_defconfig @@ -683,7 +683,7 @@ CONFIG_HWMON=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/CM-BF548_defconfig b/trunk/arch/blackfin/configs/CM-BF548_defconfig index 5c44fdb8e6e3..0e3605fdb7b0 100644 --- a/trunk/arch/blackfin/configs/CM-BF548_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF548_defconfig @@ -762,7 +762,7 @@ CONFIG_UNIX98_PTYS=y # # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -909,7 +909,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # CONFIG_USB_DABUSB is not set # diff --git a/trunk/arch/blackfin/configs/CM-BF561_defconfig b/trunk/arch/blackfin/configs/CM-BF561_defconfig index 086fe5dda495..59c7cdbee904 100644 --- a/trunk/arch/blackfin/configs/CM-BF561_defconfig +++ b/trunk/arch/blackfin/configs/CM-BF561_defconfig @@ -684,7 +684,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support diff --git a/trunk/arch/blackfin/configs/H8606_defconfig b/trunk/arch/blackfin/configs/H8606_defconfig index 1fc31f1b762b..ba0bee90b7e1 100644 --- a/trunk/arch/blackfin/configs/H8606_defconfig +++ b/trunk/arch/blackfin/configs/H8606_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.14 +# Linux kernel version: 2.6.22.12 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -192,7 +192,7 @@ CONFIG_CLKIN_HZ=25000000 # CONFIG_BFIN_KERNEL_CLOCK is not set CONFIG_MAX_VCO_HZ=400000000 CONFIG_MIN_VCO_HZ=50000000 -CONFIG_MAX_SCLK_HZ=133333333 +CONFIG_MAX_SCLK_HZ=133000000 CONFIG_MIN_SCLK_HZ=27000000 # @@ -516,7 +516,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # # CONFIG_MTD_DATAFLASH is not set CONFIG_MTD_M25P80=y -# CONFIG_M25PXX_USE_FAST_READ is not set +CONFIG_M25PXX_USE_FAST_READ=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -635,25 +635,25 @@ CONFIG_INPUT=y # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set # # Input Device Drivers # -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_BF53X_PFBUTTONS is not set # # Hardware I/O ports @@ -681,15 +681,7 @@ CONFIG_BFIN_TIMER_LATENCY=y # # Serial drivers # -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_CONSOLE is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support diff --git a/trunk/arch/blackfin/include/asm/a.out.h b/trunk/arch/blackfin/include/asm/a.out.h new file mode 100644 index 000000000000..6c3d652ebd33 --- /dev/null +++ b/trunk/arch/blackfin/include/asm/a.out.h @@ -0,0 +1,19 @@ +#ifndef __BFIN_A_OUT_H__ +#define __BFIN_A_OUT_H__ + +struct exec { + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#endif /* __BFIN_A_OUT_H__ */ diff --git a/trunk/arch/blackfin/include/asm/bfin-global.h b/trunk/arch/blackfin/include/asm/bfin-global.h index 56dcb0a2d244..7ba70de66f2b 100644 --- a/trunk/arch/blackfin/include/asm/bfin-global.h +++ b/trunk/arch/blackfin/include/asm/bfin-global.h @@ -63,6 +63,7 @@ extern void bfin_dcache_init(void); extern void init_exception_vectors(void); extern void program_IAR(void); +extern void bfin_reset(void); extern asmlinkage void lower_to_irq14(void); extern asmlinkage void bfin_return_from_exception(void); extern asmlinkage void evt14_softirq(void); @@ -91,8 +92,6 @@ extern int sram_free(const void*); extern void *sram_alloc_with_lsl(size_t, unsigned long); extern int sram_free_with_lsl(const void*); -extern void *isram_memcpy(void *dest, const void *src, size_t n); - extern const char bfin_board_name[]; extern unsigned long bfin_sic_iwr[]; @@ -105,7 +104,7 @@ extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], _ebss_l2[], _l2_lma_start[]; -/* only used when MTD_UCLINUX */ +/* only used when CONFIG_MTD_UCLINUX */ extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; #ifdef CONFIG_BFIN_ICACHE_LOCK diff --git a/trunk/arch/blackfin/include/asm/bfrom.h b/trunk/arch/blackfin/include/asm/bfrom.h deleted file mode 100644 index cfe8024c3b2f..000000000000 --- a/trunk/arch/blackfin/include/asm/bfrom.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Blackfin on-chip ROM API - * - * Copyright 2008 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __BFROM_H__ -#define __BFROM_H__ - -#include - -/* Possible syscontrol action flags */ -#define SYSCTRL_READ 0x00000000 /* read registers */ -#define SYSCTRL_WRITE 0x00000001 /* write registers */ -#define SYSCTRL_SYSRESET 0x00000002 /* perform system reset */ -#define SYSCTRL_CORERESET 0x00000004 /* perform core reset */ -#define SYSCTRL_SOFTRESET 0x00000006 /* perform core and system reset */ -#define SYSCTRL_VRCTL 0x00000010 /* read/write VR_CTL register */ -#define SYSCTRL_EXTVOLTAGE 0x00000020 /* VDDINT supplied externally */ -#define SYSCTRL_INTVOLTAGE 0x00000000 /* VDDINT generated by on-chip regulator */ -#define SYSCTRL_OTPVOLTAGE 0x00000040 /* For Factory Purposes Only */ -#define SYSCTRL_PLLCTL 0x00000100 /* read/write PLL_CTL register */ -#define SYSCTRL_PLLDIV 0x00000200 /* read/write PLL_DIV register */ -#define SYSCTRL_LOCKCNT 0x00000400 /* read/write PLL_LOCKCNT register */ -#define SYSCTRL_PLLSTAT 0x00000800 /* read/write PLL_STAT register */ - -typedef struct ADI_SYSCTRL_VALUES { - uint16_t uwVrCtl; - uint16_t uwPllCtl; - uint16_t uwPllDiv; - uint16_t uwPllLockCnt; - uint16_t uwPllStat; -} ADI_SYSCTRL_VALUES; - -static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)0xEF000038; - -/* We need a dedicated function since we need to screw with the stack pointer - * when resetting. The on-chip ROM will save/restore registers on the stack - * when doing a system reset, so the stack cannot be outside of the chip. - */ -__attribute__((__noreturn__)) -static inline void bfrom_SoftReset(void *new_stack) -{ - while (1) - __asm__ __volatile__( - "sp = %[stack];" - "jump (%[bfrom_syscontrol]);" - : : [bfrom_syscontrol] "p"(bfrom_SysControl), - "q0"(SYSCTRL_SOFTRESET), - "q1"(0), - "q2"(NULL), - [stack] "p"(new_stack) - ); -} - -/* OTP Functions */ -static uint32_t (* const bfrom_OtpCommand)(uint32_t command, uint32_t value) = (void *)0xEF000018; -static uint32_t (* const bfrom_OtpRead)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)0xEF00001A; -static uint32_t (* const bfrom_OtpWrite)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)0xEF00001C; - -/* otp command: defines for "command" */ -#define OTP_INIT 0x00000001 -#define OTP_CLOSE 0x00000002 - -/* otp read/write: defines for "flags" */ -#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */ -#define OTP_UPPER_HALF 0x00000001 -#define OTP_NO_ECC 0x00000010 /* do not use ECC */ -#define OTP_LOCK 0x00000020 /* sets page protection bit for page */ -#define OTP_CHECK_FOR_PREV_WRITE 0x00000080 - -/* Return values for all functions */ -#define OTP_SUCCESS 0x00000000 -#define OTP_MASTER_ERROR 0x001 -#define OTP_WRITE_ERROR 0x003 -#define OTP_READ_ERROR 0x005 -#define OTP_ACC_VIO_ERROR 0x009 -#define OTP_DATA_MULT_ERROR 0x011 -#define OTP_ECC_MULT_ERROR 0x021 -#define OTP_PREV_WR_ERROR 0x041 -#define OTP_DATA_SB_WARN 0x100 -#define OTP_ECC_SB_WARN 0x200 - -#endif diff --git a/trunk/arch/blackfin/include/asm/cacheflush.h b/trunk/arch/blackfin/include/asm/cacheflush.h index 4403415583fa..d81a77545a04 100644 --- a/trunk/arch/blackfin/include/asm/cacheflush.h +++ b/trunk/arch/blackfin/include/asm/cacheflush.h @@ -30,11 +30,13 @@ #ifndef _BLACKFIN_CACHEFLUSH_H #define _BLACKFIN_CACHEFLUSH_H -extern void blackfin_icache_dcache_flush_range(unsigned long start_address, unsigned long end_address); -extern void blackfin_icache_flush_range(unsigned long start_address, unsigned long end_address); -extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned long end_address); -extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address); -extern void blackfin_dflush_page(void *page); +#include + +extern void blackfin_icache_dcache_flush_range(unsigned int, unsigned int); +extern void blackfin_icache_flush_range(unsigned int, unsigned int); +extern void blackfin_dcache_flush_range(unsigned int, unsigned int); +extern void blackfin_dcache_invalidate_range(unsigned int, unsigned int); +extern void blackfin_dflush_page(void *); #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) @@ -85,21 +87,4 @@ do { memcpy(dst, src, len); \ # define flush_dcache_page(page) do { } while (0) #endif -extern unsigned long reserved_mem_dcache_on; -extern unsigned long reserved_mem_icache_on; - -static inline int bfin_addr_dcachable(unsigned long addr) -{ -#ifdef CONFIG_BFIN_DCACHE - if (addr < (_ramend - DMA_UNCACHED_REGION)) - return 1; -#endif - - if (reserved_mem_dcache_on && - addr >= _ramend && addr < physical_mem_end) - return 1; - - return 0; -} - #endif /* _BLACKFIN_ICACHEFLUSH_H */ diff --git a/trunk/arch/blackfin/include/asm/cplb.h b/trunk/arch/blackfin/include/asm/cplb.h index 9e8b4035fcec..05d6f05fb748 100644 --- a/trunk/arch/blackfin/include/asm/cplb.h +++ b/trunk/arch/blackfin/include/asm/cplb.h @@ -55,13 +55,7 @@ #endif #define L1_DMEMORY (CPLB_LOCK | CPLB_COMMON) -#ifdef CONFIG_BFIN_L2_CACHEABLE -#define L2_IMEMORY (SDRAM_IGENERIC) -#define L2_DMEMORY (SDRAM_DGENERIC) -#else -#define L2_IMEMORY (CPLB_COMMON) -#define L2_DMEMORY (CPLB_COMMON) -#endif +#define L2_MEMORY (CPLB_COMMON) #define SDRAM_DNON_CHBL (CPLB_COMMON) #define SDRAM_EBIU (CPLB_COMMON) #define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY) diff --git a/trunk/arch/blackfin/include/asm/cplbinit.h b/trunk/arch/blackfin/include/asm/cplbinit.h index f845b41147ba..0eb1c1b685a7 100644 --- a/trunk/arch/blackfin/include/asm/cplbinit.h +++ b/trunk/arch/blackfin/include/asm/cplbinit.h @@ -87,6 +87,9 @@ extern u_long dpdt_swapcount_table[]; #endif /* CONFIG_MPU */ -extern void generate_cplb_tables(void); +extern unsigned long reserved_mem_dcache_on; +extern unsigned long reserved_mem_icache_on; + +extern void generate_cpl_tables(void); #endif diff --git a/trunk/arch/blackfin/include/asm/cpumask.h b/trunk/arch/blackfin/include/asm/cpumask.h new file mode 100644 index 000000000000..b20a8e9012cb --- /dev/null +++ b/trunk/arch/blackfin/include/asm/cpumask.h @@ -0,0 +1,6 @@ +#ifndef _ASM_BLACKFIN_CPUMASK_H +#define _ASM_BLACKFIN_CPUMASK_H + +#include + +#endif /* _ASM_BLACKFIN_CPUMASK_H */ diff --git a/trunk/arch/blackfin/include/asm/dma-mapping.h b/trunk/arch/blackfin/include/asm/dma-mapping.h index ede748d67efd..1a13c2fc3667 100644 --- a/trunk/arch/blackfin/include/asm/dma-mapping.h +++ b/trunk/arch/blackfin/include/asm/dma-mapping.h @@ -80,15 +80,4 @@ extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, enum dma_data_direction direction); -static inline void dma_sync_single_for_cpu(struct device *dev, - dma_addr_t handle, size_t size, - enum dma_data_direction dir) -{ -} - -static inline void dma_sync_single_for_device(struct device *dev, - dma_addr_t handle, size_t size, - enum dma_data_direction dir) -{ -} #endif /* _BLACKFIN_DMA_MAPPING_H */ diff --git a/trunk/arch/blackfin/include/asm/elf.h b/trunk/arch/blackfin/include/asm/elf.h index cdbfcfc30f6a..67a03a8a353e 100644 --- a/trunk/arch/blackfin/include/asm/elf.h +++ b/trunk/arch/blackfin/include/asm/elf.h @@ -122,6 +122,6 @@ do { \ #define ELF_PLATFORM (NULL) -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) #endif diff --git a/trunk/arch/blackfin/include/asm/io.h b/trunk/arch/blackfin/include/asm/io.h index 7dc77a21fdf3..cbbf7ffdbbff 100644 --- a/trunk/arch/blackfin/include/asm/io.h +++ b/trunk/arch/blackfin/include/asm/io.h @@ -134,36 +134,6 @@ extern void dma_insb(unsigned long port, void *addr, unsigned short count); extern void dma_insw(unsigned long port, void *addr, unsigned short count); extern void dma_insl(unsigned long port, void *addr, unsigned short count); -static inline void readsl(const void __iomem *addr, void *buf, int len) -{ - insl((unsigned long)addr, buf, len); -} - -static inline void readsw(const void __iomem *addr, void *buf, int len) -{ - insw((unsigned long)addr, buf, len); -} - -static inline void readsb(const void __iomem *addr, void *buf, int len) -{ - insb((unsigned long)addr, buf, len); -} - -static inline void writesl(const void __iomem *addr, const void *buf, int len) -{ - outsl((unsigned long)addr, buf, len); -} - -static inline void writesw(const void __iomem *addr, const void *buf, int len) -{ - outsw((unsigned long)addr, buf, len); -} - -static inline void writesb(const void __iomem *addr, const void *buf, int len) -{ - outsb((unsigned long)addr, buf, len); -} - /* * Map some physical address range into the kernel address space. */ diff --git a/trunk/arch/blackfin/include/asm/kgdb.h b/trunk/arch/blackfin/include/asm/kgdb.h index 26ebac6646d8..0f73847fd6bc 100644 --- a/trunk/arch/blackfin/include/asm/kgdb.h +++ b/trunk/arch/blackfin/include/asm/kgdb.h @@ -124,16 +124,9 @@ enum regnames { /* Number of bytes of registers. */ #define NUMREGBYTES BFIN_NUM_REGS*4 -static inline void arch_kgdb_breakpoint(void) -{ - asm(" EXCPT 2;"); -} -#define BREAK_INSTR_SIZE 2 -#define CACHE_FLUSH_IS_SAFE 1 -#define HW_INST_WATCHPOINT_NUM 6 -#define HW_WATCHPOINT_NUM 8 -#define TYPE_INST_WATCHPOINT 0 -#define TYPE_DATA_WATCHPOINT 1 +#define BREAKPOINT() asm(" EXCPT 2;"); +#define BREAK_INSTR_SIZE 2 +#define HW_BREAKPOINT_NUM 6 /* Instruction watchpoint address control register bits mask */ #define WPPWR 0x1 @@ -170,11 +163,10 @@ static inline void arch_kgdb_breakpoint(void) #define WPDAEN1 0x8 #define WPDCNTEN0 0x10 #define WPDCNTEN1 0x20 - #define WPDSRC0 0xc0 -#define WPDACC0_OFFSET 8 +#define WPDACC0 0x300 #define WPDSRC1 0xc00 -#define WPDACC1_OFFSET 12 +#define WPDACC1 0x3000 /* Watchpoint status register bits mask */ #define STATIA0 0x1 @@ -186,4 +178,7 @@ static inline void arch_kgdb_breakpoint(void) #define STATDA0 0x40 #define STATDA1 0x80 +extern void kgdb_print(const char *fmt, ...); +extern void init_kgdb_uart(void); + #endif diff --git a/trunk/arch/blackfin/include/asm/mmu_context.h b/trunk/arch/blackfin/include/asm/mmu_context.h index 35593dda2a4d..8529552a981f 100644 --- a/trunk/arch/blackfin/include/asm/mmu_context.h +++ b/trunk/arch/blackfin/include/asm/mmu_context.h @@ -45,12 +45,49 @@ extern unsigned long l1_stack_len; extern int l1sram_free(const void*); extern void *l1sram_alloc_max(void*); +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +/* Called when creating a new context during fork() or execve(). */ +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ +#ifdef CONFIG_MPU + unsigned long p = __get_free_pages(GFP_KERNEL, page_mask_order); + mm->context.page_rwx_mask = (unsigned long *)p; + memset(mm->context.page_rwx_mask, 0, + page_mask_nelts * 3 * sizeof(long)); +#endif + return 0; +} + static inline void free_l1stack(void) { nr_l1stack_tasks--; if (nr_l1stack_tasks == 0) l1sram_free(l1_stack_base); } +static inline void destroy_context(struct mm_struct *mm) +{ + struct sram_list_struct *tmp; + + if (current_l1_stack_save == mm->context.l1_stack_save) + current_l1_stack_save = NULL; + if (mm->context.l1_stack_save) + free_l1stack(); + + while ((tmp = mm->context.sram_list)) { + mm->context.sram_list = tmp->next; + sram_free(tmp->addr); + kfree(tmp); + } +#ifdef CONFIG_MPU + if (current_rwx_mask == mm->context.page_rwx_mask) + current_rwx_mask = NULL; + free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order); +#endif +} static inline unsigned long alloc_l1stack(unsigned long length, unsigned long *stack_base) @@ -97,7 +134,6 @@ static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_m } #endif -#ifdef CONFIG_APP_STACK_L1 /* L1 stack switching. */ if (!next_mm->context.l1_stack_save) return; @@ -108,7 +144,6 @@ static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_m } current_l1_stack_save = next_mm->context.l1_stack_save; memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len); -#endif } #ifdef CONFIG_MPU @@ -145,44 +180,4 @@ static inline void update_protections(struct mm_struct *mm) } #endif -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -} - -/* Called when creating a new context during fork() or execve(). */ -static inline int -init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ -#ifdef CONFIG_MPU - unsigned long p = __get_free_pages(GFP_KERNEL, page_mask_order); - mm->context.page_rwx_mask = (unsigned long *)p; - memset(mm->context.page_rwx_mask, 0, - page_mask_nelts * 3 * sizeof(long)); -#endif - return 0; -} - -static inline void destroy_context(struct mm_struct *mm) -{ - struct sram_list_struct *tmp; - -#ifdef CONFIG_APP_STACK_L1 - if (current_l1_stack_save == mm->context.l1_stack_save) - current_l1_stack_save = 0; - if (mm->context.l1_stack_save) - free_l1stack(); -#endif - - while ((tmp = mm->context.sram_list)) { - mm->context.sram_list = tmp->next; - sram_free(tmp->addr); - kfree(tmp); - } -#ifdef CONFIG_MPU - if (current_rwx_mask == mm->context.page_rwx_mask) - current_rwx_mask = NULL; - free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order); -#endif -} - #endif diff --git a/trunk/arch/blackfin/include/asm/processor.h b/trunk/arch/blackfin/include/asm/processor.h index e3e9b41fa8db..6f3995b119d8 100644 --- a/trunk/arch/blackfin/include/asm/processor.h +++ b/trunk/arch/blackfin/include/asm/processor.h @@ -134,12 +134,6 @@ static inline uint32_t __pure bfin_revid(void) return revid; } -static inline uint16_t __pure bfin_cpuid(void) -{ - return (bfin_read_CHIPID() & CHIPID_FAMILY) >> 12; - -} - static inline uint32_t __pure bfin_compiled_revid(void) { #if defined(CONFIG_BF_REV_0_0) diff --git a/trunk/arch/blackfin/include/asm/ptrace.h b/trunk/arch/blackfin/include/asm/ptrace.h index e3f086dc7268..a45a80e54adc 100644 --- a/trunk/arch/blackfin/include/asm/ptrace.h +++ b/trunk/arch/blackfin/include/asm/ptrace.h @@ -158,8 +158,6 @@ extern void show_regs(struct pt_regs *); #define PT_SEQSTAT 8 #define PT_IPEND 4 -#define PT_ORIG_R0 208 -#define PT_ORIG_P0 212 #define PT_SYSCFG 216 #define PT_TEXT_ADDR 220 #define PT_TEXT_END_ADDR 224 diff --git a/trunk/arch/blackfin/include/asm/timex.h b/trunk/arch/blackfin/include/asm/timex.h index 248aeb066805..22b0806161bb 100644 --- a/trunk/arch/blackfin/include/asm/timex.h +++ b/trunk/arch/blackfin/include/asm/timex.h @@ -16,7 +16,7 @@ typedef unsigned long long cycles_t; static inline cycles_t get_cycles(void) { unsigned long tmp, tmp2; - __asm__ __volatile__("%0 = cycles; %1 = cycles2;" : "=d"(tmp), "=d"(tmp2)); + __asm__("%0 = cycles; %1 = cycles2;" : "=d"(tmp), "=d"(tmp2)); return tmp | ((cycles_t)tmp2 << 32); } diff --git a/trunk/arch/blackfin/include/asm/traps.h b/trunk/arch/blackfin/include/asm/traps.h index 34f7295fb070..f0e5f940d9ca 100644 --- a/trunk/arch/blackfin/include/asm/traps.h +++ b/trunk/arch/blackfin/include/asm/traps.h @@ -59,9 +59,6 @@ level " or a 16-bit register is accessed with a 32-bit instruction.\n" #define HWC_x3(level) \ "External Memory Addressing Error\n" -#define EXC_0x04(level) \ - "Unimplmented exception occured\n" \ - level " - Maybe you forgot to install a custom exception handler?\n" #define HWC_x12(level) \ "Performance Monitor Overflow\n" #define HWC_x18(level) \ @@ -87,7 +84,7 @@ level " a particular processor implementation.\n" #define EXC_0x22(level) \ "Illegal instruction combination\n" \ - level " - See section for multi-issue rules in the Blackfin\n" \ + level " - See section for multi-issue rules in the ADSP-BF53x Blackfin\n" \ level " Processor Instruction Set Reference.\n" #define EXC_0x23(level) \ "Data access CPLB protection violation\n" \ diff --git a/trunk/arch/blackfin/kernel/asm-offsets.c b/trunk/arch/blackfin/kernel/asm-offsets.c index 9bb85dd5ccb3..881afe9082c7 100644 --- a/trunk/arch/blackfin/kernel/asm-offsets.c +++ b/trunk/arch/blackfin/kernel/asm-offsets.c @@ -60,7 +60,6 @@ int main(void) DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE); /* offsets into the pt_regs */ - DEFINE(PT_ORIG_R0, offsetof(struct pt_regs, orig_r0)); DEFINE(PT_ORIG_P0, offsetof(struct pt_regs, orig_p0)); DEFINE(PT_ORIG_PC, offsetof(struct pt_regs, orig_pc)); DEFINE(PT_R0, offsetof(struct pt_regs, r0)); diff --git a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c index 339293d677cc..93229b3d6e3e 100644 --- a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c @@ -117,14 +117,15 @@ int request_dma(unsigned int channel, char *device_id) #ifdef CONFIG_BF54x if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { - unsigned int per_map; - per_map = dma_ch[channel].regs->peripheral_map & 0xFFF; - if (strncmp(device_id, "BFIN_UART", 9) == 0) - dma_ch[channel].regs->peripheral_map = per_map | + if (strncmp(device_id, "BFIN_UART", 9) == 0) { + dma_ch[channel].regs->peripheral_map &= 0x0FFF; + dma_ch[channel].regs->peripheral_map |= ((channel - CH_UART2_RX + 0xC)<<12); - else - dma_ch[channel].regs->peripheral_map = per_map | + } else { + dma_ch[channel].regs->peripheral_map &= 0x0FFF; + dma_ch[channel].regs->peripheral_map |= ((channel - CH_UART2_RX + 0x6)<<12); + } } #endif diff --git a/trunk/arch/blackfin/kernel/bfin_gpio.c b/trunk/arch/blackfin/kernel/bfin_gpio.c index 6e08f425bb44..ecbd141e0ef2 100644 --- a/trunk/arch/blackfin/kernel/bfin_gpio.c +++ b/trunk/arch/blackfin/kernel/bfin_gpio.c @@ -231,14 +231,14 @@ inline int check_gpio(unsigned gpio) } #endif -static void gpio_error(unsigned gpio) +void gpio_error(unsigned gpio) { printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio); } static void set_label(unsigned short ident, const char *label) { - if (label) { + if (label && str_ident) { strncpy(str_ident[ident].name, label, RESOURCE_LABEL_SIZE); str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0; @@ -247,6 +247,9 @@ static void set_label(unsigned short ident, const char *label) static char *get_label(unsigned short ident) { + if (!str_ident) + return "UNKNOWN"; + return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN"); } @@ -257,7 +260,7 @@ static int cmp_label(unsigned short ident, const char *label) printk(KERN_ERR "Please provide none-null label\n"); } - if (label) + if (label && str_ident) return strncmp(str_ident[ident].name, label, strlen(label)); else diff --git a/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c index 55af729f8495..48060105346a 100644 --- a/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/trunk/arch/blackfin/kernel/cplb-mpu/cplbinit.c @@ -36,7 +36,7 @@ struct cplb_entry dcplb_tbl[MAX_CPLBS]; int first_switched_icplb, first_switched_dcplb; int first_mask_dcplb; -void __init generate_cplb_tables(void) +void __init generate_cpl_tables(void) { int i_d, i_i; unsigned long addr; @@ -83,18 +83,8 @@ void __init generate_cplb_tables(void) dcplb_tbl[i_d].addr = L1_DATA_A_START; dcplb_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; #endif -#if L1_CODE_LENGTH > 0 icplb_tbl[i_i].addr = L1_CODE_START; icplb_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; -#endif - - /* Cover L2 memory */ -#if L2_LENGTH > 0 - dcplb_tbl[i_d].addr = L2_START; - dcplb_tbl[i_d++].data = L2_DMEMORY | PAGE_SIZE_1MB; - icplb_tbl[i_i].addr = L2_START; - icplb_tbl[i_i++].data = L2_IMEMORY | PAGE_SIZE_1MB; -#endif first_mask_dcplb = i_d; first_switched_dcplb = i_d + (1 << page_mask_order); diff --git a/trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index baa52e261f0d..99f2831e2964 100644 --- a/trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/trunk/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -145,7 +144,9 @@ static noinline int dcplb_miss(void) d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; #ifdef CONFIG_BFIN_DCACHE - if (bfin_addr_dcachable(addr)) { + if (addr < _ramend - DMA_UNCACHED_REGION || + (reserved_mem_dcache_on && addr >= _ramend && + addr < physical_mem_end)) { d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; #ifdef CONFIG_BFIN_WT d_data |= CPLB_L1_AOW | CPLB_WT; @@ -321,11 +322,9 @@ int cplb_hdr(int seqstat, struct pt_regs *regs) void flush_switched_cplbs(void) { int i; - unsigned long flags; nr_cplb_flush++; - local_irq_save(flags); disable_icplb(); for (i = first_switched_icplb; i < MAX_CPLBS; i++) { icplb_tbl[i].data = 0; @@ -339,8 +338,6 @@ void flush_switched_cplbs(void) bfin_write32(DCPLB_DATA0 + i * 4, 0); } enable_dcplb(); - local_irq_restore(flags); - } void set_mask_dcplbs(unsigned long *masks) @@ -348,15 +345,10 @@ void set_mask_dcplbs(unsigned long *masks) int i; unsigned long addr = (unsigned long)masks; unsigned long d_data; - unsigned long flags; + current_rwx_mask = masks; - if (!masks) { - current_rwx_mask = masks; + if (!masks) return; - } - - local_irq_save(flags); - current_rwx_mask = masks; d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; #ifdef CONFIG_BFIN_DCACHE @@ -375,5 +367,4 @@ void set_mask_dcplbs(unsigned long *masks) addr += PAGE_SIZE; } enable_dcplb(); - local_irq_restore(flags); } diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 512f8c92ead5..728f708d3981 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -169,8 +168,8 @@ static struct cplb_desc cplb_data[] = { .end = L2_START + L2_LENGTH, .psize = SIZE_1M, .attr = SWITCH_T | I_CPLB | D_CPLB, - .i_conf = L2_IMEMORY, - .d_conf = L2_DMEMORY, + .i_conf = L2_MEMORY, + .d_conf = L2_MEMORY, .valid = (L2_LENGTH > 0), .name = "L2 Memory", }, @@ -309,7 +308,7 @@ __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) } } -void __init generate_cplb_tables(void) +void __init generate_cpl_tables(void) { u16 i, j, process; diff --git a/trunk/arch/blackfin/kernel/early_printk.c b/trunk/arch/blackfin/kernel/early_printk.c index 1f4e3d2e0901..60f67f90fe35 100644 --- a/trunk/arch/blackfin/kernel/early_printk.c +++ b/trunk/arch/blackfin/kernel/early_printk.c @@ -35,9 +35,6 @@ extern struct console *bfin_earlyserial_init(unsigned int port, unsigned int cflag); #endif -#ifdef CONFIG_BFIN_JTAG_COMM -extern struct console *bfin_jc_early_init(void); -#endif static struct console *early_console; @@ -145,15 +142,6 @@ int __init setup_early_printk(char *buf) early_console = earlyserial_init(buf); } #endif - -#ifdef CONFIG_BFIN_JTAG_COMM - /* Check for Blackfin JTAG */ - if (!strncmp(buf, "jtag", 4)) { - buf += 4; - early_console = bfin_jc_early_init(); - } -#endif - #ifdef CONFIG_FB /* TODO: add framebuffer console support */ #endif diff --git a/trunk/arch/blackfin/kernel/kgdb.c b/trunk/arch/blackfin/kernel/kgdb.c index b795a207742c..a1f9641a6425 100644 --- a/trunk/arch/blackfin/kernel/kgdb.c +++ b/trunk/arch/blackfin/kernel/kgdb.c @@ -1,9 +1,32 @@ /* - * arch/blackfin/kernel/kgdb.c - Blackfin kgdb pieces + * File: arch/blackfin/kernel/kgdb.c + * Based on: + * Author: Sonic Zhang * - * Copyright 2005-2008 Analog Devices Inc. + * Created: + * Description: * - * Licensed under the GPL-2 or later. + * Rev: $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $ + * + * Modified: + * Copyright 2005-2006 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -16,29 +39,24 @@ #include #include #include +#include #include #include -#include #include #include #include -#include /* Put the error code here just in case the user cares. */ -int gdb_bfin_errcode; +int gdb_bf533errcode; /* Likewise, the vector number here (since GDB only gets the signal number through the usual means, and that's not very specific). */ -int gdb_bfin_vector = -1; +int gdb_bf533vector = -1; #if KGDB_MAX_NO_CPUS != 8 #error change the definition of slavecpulocks #endif -#ifdef CONFIG_BFIN_WDT -# error "Please unselect blackfin watchdog driver before build KGDB." -#endif - -void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) +void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { gdb_regs[BFIN_R0] = regs->r0; gdb_regs[BFIN_R1] = regs->r1; @@ -115,7 +133,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat; } -void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) +void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs) { regs->r0 = gdb_regs[BFIN_R0]; regs->r1 = gdb_regs[BFIN_R1]; @@ -181,208 +199,171 @@ struct hw_breakpoint { unsigned int dataacc:2; unsigned short count; unsigned int addr; -} breakinfo[HW_WATCHPOINT_NUM]; +} breakinfo[HW_BREAKPOINT_NUM]; -int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type) +int kgdb_arch_init(void) { - int breakno; - int bfin_type; - int dataacc = 0; - - switch (type) { - case BP_HARDWARE_BREAKPOINT: - bfin_type = TYPE_INST_WATCHPOINT; - break; - case BP_WRITE_WATCHPOINT: - dataacc = 1; - bfin_type = TYPE_DATA_WATCHPOINT; - break; - case BP_READ_WATCHPOINT: - dataacc = 2; - bfin_type = TYPE_DATA_WATCHPOINT; - break; - case BP_ACCESS_WATCHPOINT: - dataacc = 3; - bfin_type = TYPE_DATA_WATCHPOINT; - break; - default: - return -ENOSPC; - } + debugger_step = 0; - /* Becasue hardware data watchpoint impelemented in current - * Blackfin can not trigger an exception event as the hardware - * instrction watchpoint does, we ignaore all data watch point here. - * They can be turned on easily after future blackfin design - * supports this feature. - */ - for (breakno = 0; breakno < HW_INST_WATCHPOINT_NUM; breakno++) - if (bfin_type == breakinfo[breakno].type - && !breakinfo[breakno].occupied) { + kgdb_remove_all_hw_break(); + return 0; +} + +int kgdb_set_hw_break(unsigned long addr) +{ + int breakno; + for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) + if (!breakinfo[breakno].occupied) { breakinfo[breakno].occupied = 1; breakinfo[breakno].enabled = 1; + breakinfo[breakno].type = 1; breakinfo[breakno].addr = addr; - breakinfo[breakno].dataacc = dataacc; - breakinfo[breakno].count = 0; return 0; } return -ENOSPC; } -int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type) +int kgdb_remove_hw_break(unsigned long addr) { int breakno; - int bfin_type; - - switch (type) { - case BP_HARDWARE_BREAKPOINT: - bfin_type = TYPE_INST_WATCHPOINT; - break; - case BP_WRITE_WATCHPOINT: - case BP_READ_WATCHPOINT: - case BP_ACCESS_WATCHPOINT: - bfin_type = TYPE_DATA_WATCHPOINT; - break; - default: - return 0; - } - for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++) - if (bfin_type == breakinfo[breakno].type - && breakinfo[breakno].occupied - && breakinfo[breakno].addr == addr) { - breakinfo[breakno].occupied = 0; - breakinfo[breakno].enabled = 0; - } + for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) + if (breakinfo[breakno].addr == addr) + memset(&(breakinfo[breakno]), 0, sizeof(struct hw_breakpoint)); return 0; } -void bfin_remove_all_hw_break(void) +void kgdb_remove_all_hw_break(void) { - int breakno; - - memset(breakinfo, 0, sizeof(struct hw_breakpoint)*HW_WATCHPOINT_NUM); + memset(breakinfo, 0, sizeof(struct hw_breakpoint)*8); +} - for (breakno = 0; breakno < HW_INST_WATCHPOINT_NUM; breakno++) - breakinfo[breakno].type = TYPE_INST_WATCHPOINT; - for (; breakno < HW_WATCHPOINT_NUM; breakno++) - breakinfo[breakno].type = TYPE_DATA_WATCHPOINT; +/* +void kgdb_show_info(void) +{ + printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n", + bfin_read_WPIA0(), bfin_read_WPIACNT0(), + bfin_read_WPIACTL(), bfin_read_WPSTAT()); } +*/ -void bfin_correct_hw_break(void) +void kgdb_correct_hw_break(void) { int breakno; - unsigned int wpiactl = 0; - unsigned int wpdactl = 0; - int enable_wp = 0; - - for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++) - if (breakinfo[breakno].enabled) { - enable_wp = 1; + int correctit; + uint32_t wpdactl = bfin_read_WPDACTL(); + correctit = 0; + for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) { + if (breakinfo[breakno].type == 1) { switch (breakno) { case 0: - wpiactl |= WPIAEN0|WPICNTEN0; - bfin_write_WPIA0(breakinfo[breakno].addr); - bfin_write_WPIACNT0(breakinfo[breakno].count - + breakinfo->skip); + if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN0)) { + correctit = 1; + wpdactl &= ~(WPIREN01|EMUSW0); + wpdactl |= WPIAEN0|WPICNTEN0; + bfin_write_WPIA0(breakinfo[breakno].addr); + bfin_write_WPIACNT0(breakinfo[breakno].skip); + } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN0)) { + correctit = 1; + wpdactl &= ~WPIAEN0; + } break; + case 1: - wpiactl |= WPIAEN1|WPICNTEN1; - bfin_write_WPIA1(breakinfo[breakno].addr); - bfin_write_WPIACNT1(breakinfo[breakno].count - + breakinfo->skip); + if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN1)) { + correctit = 1; + wpdactl &= ~(WPIREN01|EMUSW1); + wpdactl |= WPIAEN1|WPICNTEN1; + bfin_write_WPIA1(breakinfo[breakno].addr); + bfin_write_WPIACNT1(breakinfo[breakno].skip); + } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN1)) { + correctit = 1; + wpdactl &= ~WPIAEN1; + } break; + case 2: - wpiactl |= WPIAEN2|WPICNTEN2; - bfin_write_WPIA2(breakinfo[breakno].addr); - bfin_write_WPIACNT2(breakinfo[breakno].count - + breakinfo->skip); + if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN2)) { + correctit = 1; + wpdactl &= ~(WPIREN23|EMUSW2); + wpdactl |= WPIAEN2|WPICNTEN2; + bfin_write_WPIA2(breakinfo[breakno].addr); + bfin_write_WPIACNT2(breakinfo[breakno].skip); + } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN2)) { + correctit = 1; + wpdactl &= ~WPIAEN2; + } break; + case 3: - wpiactl |= WPIAEN3|WPICNTEN3; - bfin_write_WPIA3(breakinfo[breakno].addr); - bfin_write_WPIACNT3(breakinfo[breakno].count - + breakinfo->skip); + if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN3)) { + correctit = 1; + wpdactl &= ~(WPIREN23|EMUSW3); + wpdactl |= WPIAEN3|WPICNTEN3; + bfin_write_WPIA3(breakinfo[breakno].addr); + bfin_write_WPIACNT3(breakinfo[breakno].skip); + } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN3)) { + correctit = 1; + wpdactl &= ~WPIAEN3; + } break; case 4: - wpiactl |= WPIAEN4|WPICNTEN4; - bfin_write_WPIA4(breakinfo[breakno].addr); - bfin_write_WPIACNT4(breakinfo[breakno].count - + breakinfo->skip); + if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN4)) { + correctit = 1; + wpdactl &= ~(WPIREN45|EMUSW4); + wpdactl |= WPIAEN4|WPICNTEN4; + bfin_write_WPIA4(breakinfo[breakno].addr); + bfin_write_WPIACNT4(breakinfo[breakno].skip); + } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN4)) { + correctit = 1; + wpdactl &= ~WPIAEN4; + } break; case 5: - wpiactl |= WPIAEN5|WPICNTEN5; - bfin_write_WPIA5(breakinfo[breakno].addr); - bfin_write_WPIACNT5(breakinfo[breakno].count - + breakinfo->skip); - break; - case 6: - wpdactl |= WPDAEN0|WPDCNTEN0|WPDSRC0; - wpdactl |= breakinfo[breakno].dataacc - << WPDACC0_OFFSET; - bfin_write_WPDA0(breakinfo[breakno].addr); - bfin_write_WPDACNT0(breakinfo[breakno].count - + breakinfo->skip); - break; - case 7: - wpdactl |= WPDAEN1|WPDCNTEN1|WPDSRC1; - wpdactl |= breakinfo[breakno].dataacc - << WPDACC1_OFFSET; - bfin_write_WPDA1(breakinfo[breakno].addr); - bfin_write_WPDACNT1(breakinfo[breakno].count - + breakinfo->skip); + if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN5)) { + correctit = 1; + wpdactl &= ~(WPIREN45|EMUSW5); + wpdactl |= WPIAEN5|WPICNTEN5; + bfin_write_WPIA5(breakinfo[breakno].addr); + bfin_write_WPIACNT5(breakinfo[breakno].skip); + } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN5)) { + correctit = 1; + wpdactl &= ~WPIAEN5; + } break; } } - - /* Should enable WPPWR bit first before set any other - * WPIACTL and WPDACTL bits */ - if (enable_wp) { - bfin_write_WPIACTL(WPPWR); - CSYNC(); - bfin_write_WPIACTL(wpiactl|WPPWR); + } + if (correctit) { + wpdactl &= ~WPAND; + wpdactl |= WPPWR; + /*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/ bfin_write_WPDACTL(wpdactl); CSYNC(); + /*kgdb_show_info();*/ } } void kgdb_disable_hw_debug(struct pt_regs *regs) { /* Disable hardware debugging while we are in kgdb */ - bfin_write_WPIACTL(0); - bfin_write_WPDACTL(0); + bfin_write_WPIACTL(bfin_read_WPIACTL() & ~0x1); CSYNC(); } -#ifdef CONFIG_SMP -void kgdb_passive_cpu_callback(void *info) -{ - kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); -} - -void kgdb_roundup_cpus(unsigned long flags) -{ - smp_call_function(kgdb_passive_cpu_callback, NULL, 0, 0); -} - -void kgdb_roundup_cpu(int cpu, unsigned long flags) -{ - smp_call_function_single(cpu, kgdb_passive_cpu_callback, NULL, 0, 0); -} -#endif - -void kgdb_post_primary_code(struct pt_regs *regs, int eVector, int err_code) +void kgdb_post_master_code(struct pt_regs *regs, int eVector, int err_code) { /* Master processor is completely in the debugger */ - gdb_bfin_vector = eVector; - gdb_bfin_errcode = err_code; + gdb_bf533vector = eVector; + gdb_bf533errcode = err_code; } -int kgdb_arch_handle_exception(int vector, int signo, +int kgdb_arch_handle_exception(int exceptionVector, int signo, int err_code, char *remcom_in_buffer, char *remcom_out_buffer, - struct pt_regs *regs) + struct pt_regs *linux_regs) { long addr; long breakno; @@ -404,40 +385,44 @@ int kgdb_arch_handle_exception(int vector, int signo, /* try to read optional parameter, pc unchanged if no parm */ ptr = &remcom_in_buffer[1]; if (kgdb_hex2long(&ptr, &addr)) { - regs->retx = addr; + linux_regs->retx = addr; } - newPC = regs->retx; + newPC = linux_regs->retx; /* clear the trace bit */ - regs->syscfg &= 0xfffffffe; + linux_regs->syscfg &= 0xfffffffe; /* set the trace bit if we're stepping */ if (remcom_in_buffer[0] == 's') { - regs->syscfg |= 0x1; - kgdb_single_step = regs->ipend; - kgdb_single_step >>= 6; - for (i = 10; i > 0; i--, kgdb_single_step >>= 1) - if (kgdb_single_step & 1) + linux_regs->syscfg |= 0x1; + debugger_step = linux_regs->ipend; + debugger_step >>= 6; + for (i = 10; i > 0; i--, debugger_step >>= 1) + if (debugger_step & 1) break; /* i indicate event priority of current stopped instruction * user space instruction is 0, IVG15 is 1, IVTMR is 10. - * kgdb_single_step > 0 means in single step mode + * debugger_step > 0 means in single step mode */ - kgdb_single_step = i + 1; + debugger_step = i + 1; + } else { + debugger_step = 0; } - if (vector == VEC_WATCH) { - wp_status = bfin_read_WPSTAT(); - for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++) { + wp_status = bfin_read_WPSTAT(); + CSYNC(); + + if (exceptionVector == VEC_WATCH) { + for (breakno = 0; breakno < 6; ++breakno) { if (wp_status & (1 << breakno)) { breakinfo->skip = 1; break; } } - bfin_write_WPSTAT(0); } + kgdb_correct_hw_break(); - bfin_correct_hw_break(); + bfin_write_WPSTAT(0); return 0; } /* switch */ @@ -446,385 +431,5 @@ int kgdb_arch_handle_exception(int vector, int signo, struct kgdb_arch arch_kgdb_ops = { .gdb_bpt_instr = {0xa1}, -#ifdef CONFIG_SMP - .flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP, -#else .flags = KGDB_HW_BREAKPOINT, -#endif - .set_hw_breakpoint = bfin_set_hw_break, - .remove_hw_breakpoint = bfin_remove_hw_break, - .remove_all_hw_break = bfin_remove_all_hw_break, - .correct_hw_break = bfin_correct_hw_break, }; - -static int hex(char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) - return ch - 'a' + 10; - if ((ch >= '0') && (ch <= '9')) - return ch - '0'; - if ((ch >= 'A') && (ch <= 'F')) - return ch - 'A' + 10; - return -1; -} - -static int validate_memory_access_address(unsigned long addr, int size) -{ - int cpu = raw_smp_processor_id(); - - if (size < 0) - return EFAULT; - if (addr >= 0x1000 && (addr + size) <= physical_mem_end) - return 0; - if (addr >= SYSMMR_BASE) - return 0; - if (addr >= ASYNC_BANK0_BASE - && addr + size <= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) - return 0; - if (cpu == 0) { - if (addr >= L1_SCRATCH_START - && (addr + size <= L1_SCRATCH_START + L1_SCRATCH_LENGTH)) - return 0; -#if L1_CODE_LENGTH != 0 - if (addr >= L1_CODE_START - && (addr + size <= L1_CODE_START + L1_CODE_LENGTH)) - return 0; -#endif -#if L1_DATA_A_LENGTH != 0 - if (addr >= L1_DATA_A_START - && (addr + size <= L1_DATA_A_START + L1_DATA_A_LENGTH)) - return 0; -#endif -#if L1_DATA_B_LENGTH != 0 - if (addr >= L1_DATA_B_START - && (addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH)) - return 0; -#endif -#ifdef CONFIG_SMP - } else if (cpu == 1) { - if (addr >= COREB_L1_SCRATCH_START - && (addr + size <= COREB_L1_SCRATCH_START - + L1_SCRATCH_LENGTH)) - return 0; -# if L1_CODE_LENGTH != 0 - if (addr >= COREB_L1_CODE_START - && (addr + size <= COREB_L1_CODE_START + L1_CODE_LENGTH)) - return 0; -# endif -# if L1_DATA_A_LENGTH != 0 - if (addr >= COREB_L1_DATA_A_START - && (addr + size <= COREB_L1_DATA_A_START + L1_DATA_A_LENGTH)) - return 0; -# endif -# if L1_DATA_B_LENGTH != 0 - if (addr >= COREB_L1_DATA_B_START - && (addr + size <= COREB_L1_DATA_B_START + L1_DATA_B_LENGTH)) - return 0; -# endif -#endif - } - -#if L2_LENGTH != 0 - if (addr >= L2_START - && addr + size <= L2_START + L2_LENGTH) - return 0; -#endif - - return EFAULT; -} - -/* - * Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null). May return an error. - */ -int kgdb_mem2hex(char *mem, char *buf, int count) -{ - char *tmp; - int err = 0; - unsigned char *pch; - unsigned short mmr16; - unsigned long mmr32; - int cpu = raw_smp_processor_id(); - - if (validate_memory_access_address((unsigned long)mem, count)) - return EFAULT; - - /* - * We use the upper half of buf as an intermediate buffer for the - * raw memory copy. Hex conversion will work against this one. - */ - tmp = buf + count; - - if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ - switch (count) { - case 2: - if ((unsigned int)mem % 2 == 0) { - mmr16 = *(unsigned short *)mem; - pch = (unsigned char *)&mmr16; - *tmp++ = *pch++; - *tmp++ = *pch++; - tmp -= 2; - } else - err = EFAULT; - break; - case 4: - if ((unsigned int)mem % 4 == 0) { - mmr32 = *(unsigned long *)mem; - pch = (unsigned char *)&mmr32; - *tmp++ = *pch++; - *tmp++ = *pch++; - *tmp++ = *pch++; - *tmp++ = *pch++; - tmp -= 4; - } else - err = EFAULT; - break; - default: - err = EFAULT; - } - } else if (cpu == 0 && (unsigned int)mem >= L1_CODE_START && - (unsigned int)(mem + count) <= L1_CODE_START + L1_CODE_LENGTH -#ifdef CONFIG_SMP - || cpu == 1 && (unsigned int)mem >= COREB_L1_CODE_START && - (unsigned int)(mem + count) <= - COREB_L1_CODE_START + L1_CODE_LENGTH -#endif - ) { - /* access L1 instruction SRAM*/ - if (dma_memcpy(tmp, mem, count) == NULL) - err = EFAULT; - } else - err = probe_kernel_read(tmp, mem, count); - - if (!err) { - while (count > 0) { - buf = pack_hex_byte(buf, *tmp); - tmp++; - count--; - } - - *buf = 0; - } - - return err; -} - -/* - * Copy the binary array pointed to by buf into mem. Fix $, #, and - * 0x7d escaped with 0x7d. Return a pointer to the character after - * the last byte written. - */ -int kgdb_ebin2mem(char *buf, char *mem, int count) -{ - char *tmp_old; - char *tmp_new; - unsigned short *mmr16; - unsigned long *mmr32; - int err = 0; - int size = 0; - int cpu = raw_smp_processor_id(); - - tmp_old = tmp_new = buf; - - while (count-- > 0) { - if (*tmp_old == 0x7d) - *tmp_new = *(++tmp_old) ^ 0x20; - else - *tmp_new = *tmp_old; - tmp_new++; - tmp_old++; - size++; - } - - if (validate_memory_access_address((unsigned long)mem, size)) - return EFAULT; - - if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ - switch (size) { - case 2: - if ((unsigned int)mem % 2 == 0) { - mmr16 = (unsigned short *)buf; - *(unsigned short *)mem = *mmr16; - } else - return EFAULT; - break; - case 4: - if ((unsigned int)mem % 4 == 0) { - mmr32 = (unsigned long *)buf; - *(unsigned long *)mem = *mmr32; - } else - return EFAULT; - break; - default: - return EFAULT; - } - } else if (cpu == 0 && (unsigned int)mem >= L1_CODE_START && - (unsigned int)(mem + count) < L1_CODE_START + L1_CODE_LENGTH -#ifdef CONFIG_SMP - || cpu == 1 && (unsigned int)mem >= COREB_L1_CODE_START && - (unsigned int)(mem + count) <= - COREB_L1_CODE_START + L1_CODE_LENGTH -#endif - ) { - /* access L1 instruction SRAM */ - if (dma_memcpy(mem, buf, size) == NULL) - err = EFAULT; - } else - err = probe_kernel_write(mem, buf, size); - - return err; -} - -/* - * Convert the hex array pointed to by buf into binary to be placed in mem. - * Return a pointer to the character AFTER the last byte written. - * May return an error. - */ -int kgdb_hex2mem(char *buf, char *mem, int count) -{ - char *tmp_raw; - char *tmp_hex; - unsigned short *mmr16; - unsigned long *mmr32; - int cpu = raw_smp_processor_id(); - - if (validate_memory_access_address((unsigned long)mem, count)) - return EFAULT; - - /* - * We use the upper half of buf as an intermediate buffer for the - * raw memory that is converted from hex. - */ - tmp_raw = buf + count * 2; - - tmp_hex = tmp_raw - 1; - while (tmp_hex >= buf) { - tmp_raw--; - *tmp_raw = hex(*tmp_hex--); - *tmp_raw |= hex(*tmp_hex--) << 4; - } - - if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ - switch (count) { - case 2: - if ((unsigned int)mem % 2 == 0) { - mmr16 = (unsigned short *)tmp_raw; - *(unsigned short *)mem = *mmr16; - } else - return EFAULT; - break; - case 4: - if ((unsigned int)mem % 4 == 0) { - mmr32 = (unsigned long *)tmp_raw; - *(unsigned long *)mem = *mmr32; - } else - return EFAULT; - break; - default: - return EFAULT; - } - } else if (cpu == 0 && (unsigned int)mem >= L1_CODE_START && - (unsigned int)(mem + count) <= L1_CODE_START + L1_CODE_LENGTH -#ifdef CONFIG_SMP - || cpu == 1 && (unsigned int)mem >= COREB_L1_CODE_START && - (unsigned int)(mem + count) <= - COREB_L1_CODE_START + L1_CODE_LENGTH -#endif - ) { - /* access L1 instruction SRAM */ - if (dma_memcpy(mem, tmp_raw, count) == NULL) - return EFAULT; - } else - return probe_kernel_write(mem, tmp_raw, count); - return 0; -} - -int kgdb_validate_break_address(unsigned long addr) -{ - int cpu = raw_smp_processor_id(); - - if (addr >= 0x1000 && (addr + BREAK_INSTR_SIZE) <= physical_mem_end) - return 0; - if (addr >= ASYNC_BANK0_BASE - && addr + BREAK_INSTR_SIZE <= ASYNC_BANK3_BASE + ASYNC_BANK3_BASE) - return 0; -#if L1_CODE_LENGTH != 0 - if (cpu == 0 && addr >= L1_CODE_START - && addr + BREAK_INSTR_SIZE <= L1_CODE_START + L1_CODE_LENGTH) - return 0; -# ifdef CONFIG_SMP - else if (cpu == 1 && addr >= COREB_L1_CODE_START - && addr + BREAK_INSTR_SIZE <= COREB_L1_CODE_START + L1_CODE_LENGTH) - return 0; -# endif -#endif -#if L2_LENGTH != 0 - if (addr >= L2_START - && addr + BREAK_INSTR_SIZE <= L2_START + L2_LENGTH) - return 0; -#endif - - return EFAULT; -} - -int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) -{ - int err; - int cpu = raw_smp_processor_id(); - - if ((cpu == 0 && (unsigned int)addr >= L1_CODE_START - && (unsigned int)(addr + BREAK_INSTR_SIZE) - < L1_CODE_START + L1_CODE_LENGTH) -#ifdef CONFIG_SMP - || (cpu == 1 && (unsigned int)addr >= COREB_L1_CODE_START - && (unsigned int)(addr + BREAK_INSTR_SIZE) - < COREB_L1_CODE_START + L1_CODE_LENGTH) -#endif - ) { - /* access L1 instruction SRAM */ - if (dma_memcpy(saved_instr, (void *)addr, BREAK_INSTR_SIZE) - == NULL) - return -EFAULT; - - if (dma_memcpy((void *)addr, arch_kgdb_ops.gdb_bpt_instr, - BREAK_INSTR_SIZE) == NULL) - return -EFAULT; - - return 0; - } else { - err = probe_kernel_read(saved_instr, (char *)addr, - BREAK_INSTR_SIZE); - if (err) - return err; - - return probe_kernel_write((char *)addr, - arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); - } -} - -int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) -{ - if ((unsigned int)addr >= L1_CODE_START && - (unsigned int)(addr + BREAK_INSTR_SIZE) < - L1_CODE_START + L1_CODE_LENGTH) { - /* access L1 instruction SRAM */ - if (dma_memcpy((void *)addr, bundle, BREAK_INSTR_SIZE) == NULL) - return -EFAULT; - - return 0; - } else - return probe_kernel_write((char *)addr, - (char *)bundle, BREAK_INSTR_SIZE); -} - -int kgdb_arch_init(void) -{ - kgdb_single_step = 0; - - bfin_remove_all_hw_break(); - return 0; -} - -void kgdb_arch_exit(void) -{ -} diff --git a/trunk/arch/blackfin/kernel/ptrace.c b/trunk/arch/blackfin/kernel/ptrace.c index 140bf00e9974..bf1a51d8e608 100644 --- a/trunk/arch/blackfin/kernel/ptrace.c +++ b/trunk/arch/blackfin/kernel/ptrace.c @@ -46,6 +46,7 @@ #include #include +#define MAX_SHARED_LIBS 3 #define TEXT_OFFSET 0 /* * does not yet catch signals sent when the child dies. @@ -160,32 +161,21 @@ static inline int is_user_addr_valid(struct task_struct *child, struct vm_list_struct *vml; struct sram_list_struct *sraml; - /* overflow */ - if (start + len < start) - return -EIO; - for (vml = child->mm->context.vmlist; vml; vml = vml->next) - if (start >= vml->vma->vm_start && start + len < vml->vma->vm_end) + if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end) return 0; for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next) if (start >= (unsigned long)sraml->addr - && start + len < (unsigned long)sraml->addr + sraml->length) + && start + len <= (unsigned long)sraml->addr + sraml->length) return 0; - if (start >= FIXED_CODE_START && start + len < FIXED_CODE_END) + if (start >= FIXED_CODE_START && start + len <= FIXED_CODE_END) return 0; return -EIO; } -void ptrace_enable(struct task_struct *child) -{ - unsigned long tmp; - tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); - put_reg(child, PT_SYSCFG, tmp); -} - /* * Called by kernel/ptrace.c when detaching.. * @@ -202,12 +192,14 @@ void ptrace_disable(struct task_struct *child) long arch_ptrace(struct task_struct *child, long request, long addr, long data) { int ret; + int add = 0; unsigned long __user *datap = (unsigned long __user *)data; switch (request) { /* when I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKDATA: pr_debug("ptrace: PEEKDATA\n"); + add = MAX_SHARED_LIBS * 4; /* space between text and data */ /* fall through */ case PTRACE_PEEKTEXT: /* read word at location addr. */ { @@ -215,35 +207,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int copied; ret = -EIO; - pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %ld\n", addr, sizeof(data)); - if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) + pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + add %d %ld\n", addr, add, + sizeof(data)); + if (is_user_addr_valid(child, addr + add, sizeof(tmp)) < 0) break; pr_debug("ptrace: user address is valid\n"); - if (L1_CODE_LENGTH != 0 && addr >= L1_CODE_START - && addr + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { - safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp)); +#if L1_CODE_LENGTH != 0 + if (addr + add >= L1_CODE_START + && addr + add + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { + safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp)); copied = sizeof(tmp); - - } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START - && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { - memcpy(&tmp, (const void *)(addr), sizeof(tmp)); + } else +#endif +#if L1_DATA_A_LENGTH != 0 + if (addr + add >= L1_DATA_A_START + && addr + add + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { + memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); copied = sizeof(tmp); - - } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START - && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { - memcpy(&tmp, (const void *)(addr), sizeof(tmp)); + } else +#endif +#if L1_DATA_B_LENGTH != 0 + if (addr + add >= L1_DATA_B_START + && addr + add + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { + memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); copied = sizeof(tmp); - - } else if (addr >= FIXED_CODE_START - && addr + sizeof(tmp) <= FIXED_CODE_END) { - memcpy(&tmp, (const void *)(addr), sizeof(tmp)); + } else +#endif + if (addr + add >= FIXED_CODE_START + && addr + add + sizeof(tmp) <= FIXED_CODE_END) { + memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); copied = sizeof(tmp); - } else - copied = access_process_vm(child, addr, &tmp, + copied = access_process_vm(child, addr + add, &tmp, sizeof(tmp), 0); - pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); if (copied != sizeof(tmp)) break; @@ -287,43 +284,47 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* when I and D space are separate, this will have to be fixed. */ case PTRACE_POKEDATA: - pr_debug("ptrace: PTRACE_PEEKDATA\n"); + printk(KERN_NOTICE "ptrace: PTRACE_PEEKDATA\n"); /* fall through */ case PTRACE_POKETEXT: /* write the word at location addr. */ { int copied; ret = -EIO; - pr_debug("ptrace: POKETEXT at addr 0x%08lx + %ld bytes %lx\n", - addr, sizeof(data), data); - if (is_user_addr_valid(child, addr, sizeof(data)) < 0) + pr_debug("ptrace: POKETEXT at addr 0x%08lx + add %d %ld bytes %lx\n", + addr, add, sizeof(data), data); + if (is_user_addr_valid(child, addr + add, sizeof(data)) < 0) break; pr_debug("ptrace: user address is valid\n"); - if (L1_CODE_LENGTH != 0 && addr >= L1_CODE_START - && addr + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { - safe_dma_memcpy ((void *)(addr), &data, sizeof(data)); +#if L1_CODE_LENGTH != 0 + if (addr + add >= L1_CODE_START + && addr + add + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { + safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data)); copied = sizeof(data); - - } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START - && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { - memcpy((void *)(addr), &data, sizeof(data)); + } else +#endif +#if L1_DATA_A_LENGTH != 0 + if (addr + add >= L1_DATA_A_START + && addr + add + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { + memcpy((void *)(addr + add), &data, sizeof(data)); copied = sizeof(data); - - } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START - && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { - memcpy((void *)(addr), &data, sizeof(data)); + } else +#endif +#if L1_DATA_B_LENGTH != 0 + if (addr + add >= L1_DATA_B_START + && addr + add + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { + memcpy((void *)(addr + add), &data, sizeof(data)); copied = sizeof(data); - - } else if (addr >= FIXED_CODE_START - && addr + sizeof(data) <= FIXED_CODE_END) { - memcpy((void *)(addr), &data, sizeof(data)); + } else +#endif + if (addr + add >= FIXED_CODE_START + && addr + add + sizeof(data) <= FIXED_CODE_END) { + memcpy((void *)(addr + add), &data, sizeof(data)); copied = sizeof(data); - } else - copied = access_process_vm(child, addr, &data, + copied = access_process_vm(child, addr + add, &data, sizeof(data), 1); - pr_debug("ptrace: copied size %d\n", copied); if (copied != sizeof(data)) break; @@ -350,22 +351,29 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: /* restart after signal. */ - pr_debug("ptrace: syscall/cont\n"); + case PTRACE_CONT: + { /* restart after signal. */ + long tmp; - ret = -EIO; - if (!valid_signal(data)) + pr_debug("ptrace_cont\n"); + + ret = -EIO; + if (!valid_signal(data)) + break; + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + else + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + + child->exit_code = data; + /* make sure the single step bit is not set. */ + tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); + put_reg(child, PT_SYSCFG, tmp); + pr_debug("before wake_up_process\n"); + wake_up_process(child); + ret = 0; break; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; - ptrace_disable(child); - pr_debug("ptrace: before wake_up_process\n"); - wake_up_process(child); - ret = 0; - break; + } /* * make the child exit. Best I can do is send it a sigkill. @@ -373,37 +381,55 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * exit. */ case PTRACE_KILL: - ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ + { + long tmp; + ret = 0; + if (child->exit_state == EXIT_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + /* make sure the single step bit is not set. */ + tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); + put_reg(child, PT_SYSCFG, tmp); + wake_up_process(child); break; - child->exit_code = SIGKILL; - ptrace_disable(child); - wake_up_process(child); - break; + } - case PTRACE_SINGLESTEP: /* set the trap flag. */ - pr_debug("ptrace: single step\n"); - ret = -EIO; - if (!valid_signal(data)) + case PTRACE_SINGLESTEP: + { /* set the trap flag. */ + long tmp; + + pr_debug("single step\n"); + ret = -EIO; + if (!valid_signal(data)) + break; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + + tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); + put_reg(child, PT_SYSCFG, tmp); + + child->exit_code = data; + /* give it a chance to run. */ + wake_up_process(child); + ret = 0; break; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - ptrace_enable(child); - child->exit_code = data; - wake_up_process(child); - ret = 0; - break; + } case PTRACE_GETREGS: - /* Get all gp regs from the child. */ - ret = ptrace_getregs(child, datap); - break; + { - case PTRACE_SETREGS: - printk(KERN_WARNING "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n"); - /* Set all gp regs in the child. */ - ret = 0; - break; + /* Get all gp regs from the child. */ + ret = ptrace_getregs(child, datap); + break; + } + case PTRACE_SETREGS: + { + printk(KERN_NOTICE + "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n"); + /* Set all gp regs in the child. */ + ret = 0; + break; + } default: ret = ptrace_request(child, request, addr, data); break; @@ -414,6 +440,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) asmlinkage void syscall_trace(void) { + if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; diff --git a/trunk/arch/blackfin/kernel/reboot.c b/trunk/arch/blackfin/kernel/reboot.c index ae97ca407b0d..367e2dc09881 100644 --- a/trunk/arch/blackfin/kernel/reboot.c +++ b/trunk/arch/blackfin/kernel/reboot.c @@ -10,7 +10,6 @@ #include #include #include -#include /* A system soft reset makes external memory unusable so force * this function into L1. We use the compiler ssync here rather @@ -21,7 +20,7 @@ * the core reset. */ __attribute__((l1_text)) -static void bfin_reset(void) +void bfin_reset(void) { /* Wait for completion of "system" events such as cache line * line fills so that we avoid infinite stalls later on as @@ -35,15 +34,15 @@ static void bfin_reset(void) bfin_write_SWRST(0x7); /* Due to the way reset is handled in the hardware, we need - * to delay for 10 SCLKS. The only reliable way to do this is - * to calculate the CCLK/SCLK ratio and multiply 10. For now, + * to delay for 7 SCLKS. The only reliable way to do this is + * to calculate the CCLK/SCLK ratio and multiply 7. For now, * we'll assume worse case which is a 1:15 ratio. */ asm( "LSETUP (1f, 1f) LC0 = %0\n" "1: nop;" : - : "a" (15 * 10) + : "a" (15 * 7) : "LC0", "LB0", "LT0" ); @@ -75,14 +74,7 @@ void machine_restart(char *cmd) { native_machine_restart(cmd); local_irq_disable(); - if (ANOMALY_05000353 || ANOMALY_05000386) - bfin_reset(); - else - /* the bootrom checks to see how it was reset and will - * automatically perform a software reset for us when - * it starts executing boot - */ - asm("raise 1;"); + bfin_reset(); } __attribute__((weak)) diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c index 7f35d1046cd8..7a82d10b4ebf 100644 --- a/trunk/arch/blackfin/kernel/setup.c +++ b/trunk/arch/blackfin/kernel/setup.c @@ -42,7 +42,6 @@ EXPORT_SYMBOL(memory_start); EXPORT_SYMBOL(memory_end); EXPORT_SYMBOL(physical_mem_end); EXPORT_SYMBOL(_ramend); -EXPORT_SYMBOL(reserved_mem_dcache_on); #ifdef CONFIG_MTD_UCLINUX unsigned long memory_mtd_end, memory_mtd_start, mtd_size; @@ -53,8 +52,7 @@ EXPORT_SYMBOL(mtd_size); #endif char __initdata command_line[COMMAND_LINE_SIZE]; -void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, - *init_saved_icplb_fault_addr, *init_saved_dcplb_fault_addr; +unsigned int __initdata *__retx; /* boot memmap, for parsing "memmap=" */ #define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ @@ -79,10 +77,10 @@ static struct change_member *change_point[2*BFIN_MEMMAP_MAX] __initdata; static struct bfin_memmap_entry *overlap_list[BFIN_MEMMAP_MAX] __initdata; static struct bfin_memmap_entry new_map[BFIN_MEMMAP_MAX] __initdata; -void __init bfin_cache_init(void) +void __init bf53x_cache_init(void) { #if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE) - generate_cplb_tables(); + generate_cpl_tables(); #endif #ifdef CONFIG_BFIN_ICACHE @@ -102,7 +100,7 @@ void __init bfin_cache_init(void) #endif } -void __init bfin_relocate_l1_mem(void) +void __init bf53x_relocate_l1_mem(void) { unsigned long l1_code_length; unsigned long l1_data_a_length; @@ -412,7 +410,7 @@ static __init void parse_cmdline_early(char *cmdline_p) * [_rambase, _ramstart]: kernel image * [memory_start, memory_end]: dynamic memory managed by kernel * [memory_end, _ramend]: reserved memory - * [memory_mtd_start(memory_end), + * [meory_mtd_start(memory_end), * memory_mtd_start + mtd_size]: rootfs (if any) * [_ramend - DMA_UNCACHED_REGION, * _ramend]: uncached DMA region @@ -784,25 +782,16 @@ void __init setup_arch(char **cmdline_p) _bfin_swrst = bfin_read_SWRST(); -#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT - bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); -#endif -#ifdef CONFIG_DEBUG_DOUBLEFAULT_RESET - bfin_write_SWRST(_bfin_swrst | DOUBLE_FAULT); -#endif + /* If we double fault, reset the system - otherwise we hang forever */ + bfin_write_SWRST(DOUBLE_FAULT); - if (_bfin_swrst & RESET_DOUBLE) { - printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n"); -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* We assume the crashing kernel, and the current symbol table match */ - printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n", - (int)init_saved_seqstat & SEQSTAT_EXCAUSE, init_saved_retx); - printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr); - printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr); -#endif - printk(KERN_NOTICE " The instruction at %pF caused a double exception\n", - init_retx); - } else if (_bfin_swrst & RESET_WDOG) + if (_bfin_swrst & RESET_DOUBLE) + /* + * don't decode the address, since you don't know if this + * kernel's symbol map is the same as the crashing kernel + */ + printk(KERN_INFO "Recovering from Double Fault event at %pF\n", __retx); + else if (_bfin_swrst & RESET_WDOG) printk(KERN_INFO "Recovering from Watchdog event\n"); else if (_bfin_swrst & RESET_SOFTWARE) printk(KERN_NOTICE "Reset caused by Software reset\n"); @@ -814,24 +803,17 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU); else printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); - - if (unlikely(CPUID != bfin_cpuid())) - printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n", - CPU, bfin_cpuid(), bfin_revid()); - else { - if (bfin_revid() != bfin_compiled_revid()) { - if (bfin_compiled_revid() == -1) - printk(KERN_ERR "Warning: Compiled for Rev none, but running on Rev %d\n", - bfin_revid()); - else if (bfin_compiled_revid() != 0xffff) - printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", - bfin_compiled_revid(), bfin_revid()); - } - if (bfin_revid() <= CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX) - printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", - CPU, bfin_revid()); + if (bfin_revid() != bfin_compiled_revid()) { + if (bfin_compiled_revid() == -1) + printk(KERN_ERR "Warning: Compiled for Rev none, but running on Rev %d\n", + bfin_revid()); + else if (bfin_compiled_revid() != 0xffff) + printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", + bfin_compiled_revid(), bfin_revid()); } - + if (bfin_revid() < SUPPORTED_REVID) + printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", + CPU, bfin_revid()); printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", @@ -868,7 +850,7 @@ void __init setup_arch(char **cmdline_p) != SAFE_USER_INSTRUCTION - FIXED_CODE_START); init_exception_vectors(); - bfin_cache_init(); + bf53x_cache_init(); } static int __init topology_init(void) @@ -1004,18 +986,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) } seq_printf(m, "processor\t: %d\n" - "vendor_id\t: %s\n", - *(unsigned int *)v, - vendor); - - if (CPUID == bfin_cpuid()) - seq_printf(m, "cpu family\t: 0x%04x\n", CPUID); - else - seq_printf(m, "cpu family\t: Compiled for:0x%04x, running on:0x%04x\n", - CPUID, bfin_cpuid()); - - seq_printf(m, "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n" + "vendor_id\t: %s\n" + "cpu family\t: 0x%x\n" + "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n" "stepping\t: %d\n", + 0, + vendor, + (bfin_read_CHIPID() & CHIPID_FAMILY), cpu, cclk/1000000, sclk/1000000, #ifdef CONFIG_MPU "mpu on", @@ -1061,7 +1038,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if ((bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE)) != (ENDCPLB | DMC_ENABLE)) dcache_size = 0; - if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) != (IMC | ENICPLB)) + if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) == (IMC | ENICPLB)) icache_size = 0; seq_printf(m, "cache size\t: %d KB(L1 icache) " @@ -1150,18 +1127,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) static void *c_start(struct seq_file *m, loff_t *pos) { - if (*pos == 0) - *pos = first_cpu(cpu_online_map); - if (*pos >= num_online_cpus()) - return NULL; - - return pos; + return *pos < NR_CPUS ? ((void *)0x12345678) : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { - *pos = next_cpu(*pos, cpu_online_map); - + ++*pos; return c_start(m, pos); } diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c index 1aa2c788e228..9a9d5083acfd 100644 --- a/trunk/arch/blackfin/kernel/traps.c +++ b/trunk/arch/blackfin/kernel/traps.c @@ -34,19 +34,20 @@ #include #include #include -#include #include #include #include #include #include +#include #ifdef CONFIG_KGDB +# include # include # define CHK_DEBUGGER_TRAP() \ do { \ - kgdb_handle_exception(trapnr, sig, info.si_code, fp); \ + CHK_DEBUGGER(trapnr, sig, info.si_code, fp, ); \ } while (0) # define CHK_DEBUGGER_TRAP_MAYBE() \ do { \ @@ -58,15 +59,6 @@ # define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) #endif - -#ifdef CONFIG_VERBOSE_DEBUG -#define verbose_printk(fmt, arg...) \ - printk(fmt, ##arg) -#else -#define verbose_printk(fmt, arg...) \ - ({ if (0) printk(fmt, ##arg); 0; }) -#endif - /* Initiate the event table handler */ void __init trap_init(void) { @@ -75,19 +67,10 @@ void __init trap_init(void) CSYNC(); } -/* - * Used to save the RETX, SEQSTAT, I/D CPLB FAULT ADDR - * values across the transition from exception to IRQ5. - * We put these in L1, so they are going to be in a valid - * location during exception context - */ -__attribute__((l1_data)) -unsigned long saved_retx, saved_seqstat, - saved_icplb_fault_addr, saved_dcplb_fault_addr; +unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; static void decode_address(char *buf, unsigned long address) { -#ifdef CONFIG_DEBUG_VERBOSE struct vm_list_struct *vml; struct task_struct *p; struct mm_struct *mm; @@ -195,39 +178,16 @@ static void decode_address(char *buf, unsigned long address) done: write_unlock_irqrestore(&tasklist_lock, flags); -#else - sprintf(buf, " "); -#endif } asmlinkage void double_fault_c(struct pt_regs *fp) { console_verbose(); oops_in_progress = 1; -#ifdef CONFIG_DEBUG_VERBOSE printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); -#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT - if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { - char buf[150]; - decode_address(buf, saved_retx); - printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", - (int)saved_seqstat & SEQSTAT_EXCAUSE, buf); - decode_address(buf, saved_dcplb_fault_addr); - printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); - decode_address(buf, saved_icplb_fault_addr); - printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); - - decode_address(buf, fp->retx); - printk(KERN_NOTICE "The instruction at %s caused a double exception\n", - buf); - } else -#endif - { - dump_bfin_process(fp); - dump_bfin_mem(fp); - show_regs(fp); - } -#endif + dump_bfin_process(fp); + dump_bfin_mem(fp); + show_regs(fp); panic("Double Fault - unrecoverable event\n"); } @@ -299,42 +259,34 @@ asmlinkage void trap_c(struct pt_regs *fp) return; else break; - /* 0x03 - User Defined, userspace stack overflow */ - case VEC_EXCPT03: - info.si_code = SEGV_STACKFLOW; - sig = SIGSEGV; - verbose_printk(KERN_NOTICE EXC_0x03(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); - break; - /* 0x02 - KGDB initial connection and break signal trap */ - case VEC_EXCPT02: #ifdef CONFIG_KGDB + case VEC_EXCPT02 : /* gdb connection */ info.si_code = TRAP_ILLTRAP; sig = SIGTRAP; CHK_DEBUGGER_TRAP(); return; +#else + /* 0x02 - User Defined, Caught by default */ #endif - /* 0x04 - User Defined */ - /* 0x05 - User Defined */ - /* 0x06 - User Defined */ - /* 0x07 - User Defined */ - /* 0x08 - User Defined */ - /* 0x09 - User Defined */ - /* 0x0A - User Defined */ - /* 0x0B - User Defined */ - /* 0x0C - User Defined */ - /* 0x0D - User Defined */ - /* 0x0E - User Defined */ - /* 0x0F - User Defined */ - /* If we got here, it is most likely that someone was trying to use a - * custom exception handler, and it is not actually installed properly - */ - case VEC_EXCPT04 ... VEC_EXCPT15: - info.si_code = ILL_ILLPARAOP; - sig = SIGILL; - verbose_printk(KERN_NOTICE EXC_0x04(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + /* 0x03 - User Defined, userspace stack overflow */ + case VEC_EXCPT03: + info.si_code = SEGV_STACKFLOW; + sig = SIGSEGV; + printk(KERN_NOTICE EXC_0x03(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; + /* 0x04 - User Defined, Caught by default */ + /* 0x05 - User Defined, Caught by default */ + /* 0x06 - User Defined, Caught by default */ + /* 0x07 - User Defined, Caught by default */ + /* 0x08 - User Defined, Caught by default */ + /* 0x09 - User Defined, Caught by default */ + /* 0x0A - User Defined, Caught by default */ + /* 0x0B - User Defined, Caught by default */ + /* 0x0C - User Defined, Caught by default */ + /* 0x0D - User Defined, Caught by default */ + /* 0x0E - User Defined, Caught by default */ + /* 0x0F - User Defined, Caught by default */ /* 0x10 HW Single step, handled here */ case VEC_STEP: info.si_code = TRAP_STEP; @@ -349,8 +301,8 @@ asmlinkage void trap_c(struct pt_regs *fp) case VEC_OVFLOW: info.si_code = TRAP_TRACEFLOW; sig = SIGTRAP; - verbose_printk(KERN_NOTICE EXC_0x11(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x11(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x12 - Reserved, Caught by default */ /* 0x13 - Reserved, Caught by default */ @@ -371,43 +323,44 @@ asmlinkage void trap_c(struct pt_regs *fp) case VEC_UNDEF_I: info.si_code = ILL_ILLOPC; sig = SIGILL; - verbose_printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x22 - Illegal Instruction Combination, handled here */ case VEC_ILGAL_I: info.si_code = ILL_ILLPARAOP; sig = SIGILL; - verbose_printk(KERN_NOTICE EXC_0x22(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x22(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x23 - Data CPLB protection violation, handled here */ case VEC_CPLB_VL: info.si_code = ILL_CPLB_VI; sig = SIGBUS; - verbose_printk(KERN_NOTICE EXC_0x23(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x23(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x24 - Data access misaligned, handled here */ case VEC_MISALI_D: info.si_code = BUS_ADRALN; sig = SIGBUS; - verbose_printk(KERN_NOTICE EXC_0x24(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x24(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x25 - Unrecoverable Event, handled here */ case VEC_UNCOV: info.si_code = ILL_ILLEXCPT; sig = SIGILL; - verbose_printk(KERN_NOTICE EXC_0x25(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x25(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, error case is handled here */ case VEC_CPLB_M: info.si_code = BUS_ADRALN; sig = SIGBUS; - verbose_printk(KERN_NOTICE EXC_0x26(KERN_NOTICE)); + printk(KERN_NOTICE EXC_0x26(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ case VEC_CPLB_MHIT: @@ -415,11 +368,11 @@ asmlinkage void trap_c(struct pt_regs *fp) sig = SIGSEGV; #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO if (saved_dcplb_fault_addr < FIXED_CODE_START) - verbose_printk(KERN_NOTICE "NULL pointer access\n"); + printk(KERN_NOTICE "NULL pointer access\n"); else #endif - verbose_printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x28 - Emulation Watchpoint, handled here */ case VEC_WATCH: @@ -437,8 +390,8 @@ asmlinkage void trap_c(struct pt_regs *fp) case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ info.si_code = BUS_OPFETCH; sig = SIGBUS; - verbose_printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n"); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n"); + CHK_DEBUGGER_TRAP(); break; #else /* 0x29 - Reserved, Caught by default */ @@ -447,21 +400,22 @@ asmlinkage void trap_c(struct pt_regs *fp) case VEC_MISALI_I: info.si_code = BUS_ADRALN; sig = SIGBUS; - verbose_printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x2B - Instruction CPLB protection violation, handled here */ case VEC_CPLB_I_VL: info.si_code = ILL_CPLB_VI; sig = SIGBUS; - verbose_printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ case VEC_CPLB_I_M: info.si_code = ILL_CPLB_MISS; sig = SIGBUS; - verbose_printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE)); + printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x2D - Instruction CPLB Multiple Hits, handled here */ case VEC_CPLB_I_MHIT: @@ -469,18 +423,18 @@ asmlinkage void trap_c(struct pt_regs *fp) sig = SIGSEGV; #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO if (saved_icplb_fault_addr < FIXED_CODE_START) - verbose_printk(KERN_NOTICE "Jump to NULL address\n"); + printk(KERN_NOTICE "Jump to NULL address\n"); else #endif - verbose_printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x2E - Illegal use of Supervisor Resource, handled here */ case VEC_ILL_RES: info.si_code = ILL_PRVOPC; sig = SIGILL; - verbose_printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE)); - CHK_DEBUGGER_TRAP_MAYBE(); + printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE)); + CHK_DEBUGGER_TRAP(); break; /* 0x2F - Reserved, Caught by default */ /* 0x30 - Reserved, Caught by default */ @@ -507,17 +461,17 @@ asmlinkage void trap_c(struct pt_regs *fp) case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): info.si_code = BUS_ADRALN; sig = SIGBUS; - verbose_printk(KERN_NOTICE HWC_x2(KERN_NOTICE)); + printk(KERN_NOTICE HWC_x2(KERN_NOTICE)); break; /* External Memory Addressing Error */ case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): info.si_code = BUS_ADRERR; sig = SIGBUS; - verbose_printk(KERN_NOTICE HWC_x3(KERN_NOTICE)); + printk(KERN_NOTICE HWC_x3(KERN_NOTICE)); break; /* Performance Monitor Overflow */ case (SEQSTAT_HWERRCAUSE_PERF_FLOW): - verbose_printk(KERN_NOTICE HWC_x12(KERN_NOTICE)); + printk(KERN_NOTICE HWC_x12(KERN_NOTICE)); break; /* RAISE 5 instruction */ case (SEQSTAT_HWERRCAUSE_RAISE_5): @@ -527,25 +481,21 @@ asmlinkage void trap_c(struct pt_regs *fp) printk(KERN_NOTICE HWC_default(KERN_NOTICE)); break; } - CHK_DEBUGGER_TRAP_MAYBE(); + CHK_DEBUGGER_TRAP(); break; - /* - * We should be handling all known exception types above, - * if we get here we hit a reserved one, so panic - */ default: - oops_in_progress = 1; - info.si_code = ILL_ILLPARAOP; - sig = SIGILL; - verbose_printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", (fp->seqstat & SEQSTAT_EXCAUSE)); - CHK_DEBUGGER_TRAP_MAYBE(); + CHK_DEBUGGER_TRAP(); break; } BUG_ON(sig == 0); if (sig != SIGTRAP) { + unsigned long *stack; dump_bfin_process(fp); dump_bfin_mem(fp); show_regs(fp); @@ -553,7 +503,7 @@ asmlinkage void trap_c(struct pt_regs *fp) /* Print out the trace buffer if it makes sense */ #ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M) - verbose_printk(KERN_NOTICE "No trace since you do not have " + printk(KERN_NOTICE "No trace since you do not have " "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n" KERN_NOTICE "\n"); else @@ -562,22 +512,20 @@ asmlinkage void trap_c(struct pt_regs *fp) if (oops_in_progress) { /* Dump the current kernel stack */ - verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); + printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); show_stack(current, NULL); + print_modules(); #ifndef CONFIG_ACCESS_CHECK - verbose_printk(KERN_EMERG "Please turn on " + printk(KERN_EMERG "Please turn on " "CONFIG_ACCESS_CHECK\n"); #endif panic("Kernel exception"); } else { -#ifdef CONFIG_VERBOSE_DEBUG - unsigned long *stack; /* Dump the user space stack */ stack = (unsigned long *)rdusp(); - verbose_printk(KERN_NOTICE "Userspace Stack\n"); + printk(KERN_NOTICE "Userspace Stack\n"); show_stack(NULL, stack); -#endif } } @@ -598,7 +546,7 @@ asmlinkage void trap_c(struct pt_regs *fp) * Similar to get_user, do some address checking, then dereference * Return true on sucess, false on bad address */ -static bool get_instruction(unsigned short *val, unsigned short *address) +bool get_instruction(unsigned short *val, unsigned short *address) { unsigned long addr; @@ -644,7 +592,7 @@ static bool get_instruction(unsigned short *val, unsigned short *address) #if L1_CODE_LENGTH != 0 if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { - isram_memcpy(val, address, 2); + dma_memcpy(val, address, 2); return true; } #endif @@ -659,48 +607,45 @@ static bool get_instruction(unsigned short *val, unsigned short *address) * These are the normal instructions which cause change of flow, which * would be at the source of the trace buffer */ -#ifdef CONFIG_DEBUG_VERBOSE -static void decode_instruction(unsigned short *address) +void decode_instruction(unsigned short *address) { unsigned short opcode; if (get_instruction(&opcode, address)) { if (opcode == 0x0010) - verbose_printk("RTS"); + printk("RTS"); else if (opcode == 0x0011) - verbose_printk("RTI"); + printk("RTI"); else if (opcode == 0x0012) - verbose_printk("RTX"); + printk("RTX"); else if (opcode >= 0x0050 && opcode <= 0x0057) - verbose_printk("JUMP (P%i)", opcode & 7); + printk("JUMP (P%i)", opcode & 7); else if (opcode >= 0x0060 && opcode <= 0x0067) - verbose_printk("CALL (P%i)", opcode & 7); + printk("CALL (P%i)", opcode & 7); else if (opcode >= 0x0070 && opcode <= 0x0077) - verbose_printk("CALL (PC+P%i)", opcode & 7); + printk("CALL (PC+P%i)", opcode & 7); else if (opcode >= 0x0080 && opcode <= 0x0087) - verbose_printk("JUMP (PC+P%i)", opcode & 7); + printk("JUMP (PC+P%i)", opcode & 7); else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) - verbose_printk("IF !CC JUMP"); + printk("IF !CC JUMP"); else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) - verbose_printk("IF CC JUMP"); + printk("IF CC JUMP"); else if (opcode >= 0x2000 && opcode <= 0x2fff) - verbose_printk("JUMP.S"); + printk("JUMP.S"); else if (opcode >= 0xe080 && opcode <= 0xe0ff) - verbose_printk("LSETUP"); + printk("LSETUP"); else if (opcode >= 0xe200 && opcode <= 0xe2ff) - verbose_printk("JUMP.L"); + printk("JUMP.L"); else if (opcode >= 0xe300 && opcode <= 0xe3ff) - verbose_printk("CALL pcrel"); + printk("CALL pcrel"); else - verbose_printk("0x%04x", opcode); + printk("0x%04x", opcode); } } -#endif void dump_bfin_trace_buffer(void) { -#ifdef CONFIG_DEBUG_VERBOSE #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int tflags, i = 0; char buf[150]; @@ -756,7 +701,6 @@ void dump_bfin_trace_buffer(void) trace_buffer_restore(tflags); #endif -#endif } EXPORT_SYMBOL(dump_bfin_trace_buffer); @@ -764,7 +708,7 @@ EXPORT_SYMBOL(dump_bfin_trace_buffer); * Checks to see if the address pointed to is either a * 16-bit CALL instruction, or a 32-bit CALL instruction */ -static bool is_bfin_call(unsigned short *addr) +bool is_bfin_call(unsigned short *addr) { unsigned short opcode = 0, *ins_addr; ins_addr = (unsigned short *)addr; @@ -786,10 +730,8 @@ static bool is_bfin_call(unsigned short *addr) return false; } - void show_stack(struct task_struct *task, unsigned long *stack) { -#ifdef CONFIG_PRINTK unsigned int *addr, *endstack, *fp = 0, *frame; unsigned short *ins_addr; char buf[150]; @@ -814,10 +756,8 @@ void show_stack(struct task_struct *task, unsigned long *stack) } else endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); - printk(KERN_NOTICE "Stack info:\n"); decode_address(buf, (unsigned int)stack); - printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); - + printk(KERN_NOTICE "Stack info:\n" KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); addr = (unsigned int *)((unsigned int)stack & ~0x3F); /* First thing is to look for a frame pointer */ @@ -908,7 +848,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) if (!j) printk("\n"); } -#endif + } void dump_stack(void) @@ -926,39 +866,38 @@ EXPORT_SYMBOL(dump_stack); void dump_bfin_process(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE /* We should be able to look at fp->ipend, but we don't push it on the * stack all the time, so do this until we fix that */ unsigned int context = bfin_read_IPEND(); if (oops_in_progress) - verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); + printk(KERN_EMERG "Kernel OOPS in progress\n"); if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) - verbose_printk(KERN_NOTICE "HW Error context\n"); + printk(KERN_NOTICE "HW Error context\n"); else if (context & 0x0020) - verbose_printk(KERN_NOTICE "Deferred Exception context\n"); + printk(KERN_NOTICE "Deferred Exception context\n"); else if (context & 0x3FC0) - verbose_printk(KERN_NOTICE "Interrupt context\n"); + printk(KERN_NOTICE "Interrupt context\n"); else if (context & 0x4000) - verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); + printk(KERN_NOTICE "Deferred Interrupt context\n"); else if (context & 0x8000) - verbose_printk(KERN_NOTICE "Kernel process context\n"); + printk(KERN_NOTICE "Kernel process context\n"); /* Because we are crashing, and pointers could be bad, we check things * pretty closely before we use them */ if ((unsigned long)current >= FIXED_CODE_START && !((unsigned long)current & 0x3) && current->pid) { - verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); + printk(KERN_NOTICE "CURRENT PROCESS:\n"); if (current->comm >= (char *)FIXED_CODE_START) - verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", + printk(KERN_NOTICE "COMM=%s PID=%d\n", current->comm, current->pid); else - verbose_printk(KERN_NOTICE "COMM= invalid\n"); + printk(KERN_NOTICE "COMM= invalid\n"); if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) - verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" + printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n" KERN_NOTICE "\n", (void *)current->mm->start_code, @@ -969,40 +908,38 @@ void dump_bfin_process(struct pt_regs *fp) (void *)current->mm->brk, (void *)current->mm->start_stack); else - verbose_printk(KERN_NOTICE "invalid mm\n"); + printk(KERN_NOTICE "invalid mm\n"); } else - verbose_printk(KERN_NOTICE "\n" KERN_NOTICE + printk(KERN_NOTICE "\n" KERN_NOTICE "No Valid process in current context\n"); -#endif } void dump_bfin_mem(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE unsigned short *addr, *erraddr, val = 0, err = 0; char sti = 0, buf[6]; erraddr = (void *)fp->pc; - verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); + printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; addr++) { if (!((unsigned long)addr & 0xF)) - verbose_printk("\n" KERN_NOTICE "0x%p: ", addr); + printk("\n" KERN_NOTICE "0x%p: ", addr); - if (!get_instruction(&val, addr)) { + if (get_instruction(&val, addr)) { val = 0; sprintf(buf, "????"); } else sprintf(buf, "%04x", val); if (addr == erraddr) { - verbose_printk("[%s]", buf); + printk("[%s]", buf); err = val; } else - verbose_printk(" %s ", buf); + printk(" %s ", buf); /* Do any previous instructions turn on interrupts? */ if (addr <= erraddr && /* in the past */ @@ -1011,14 +948,14 @@ void dump_bfin_mem(struct pt_regs *fp) sti = 1; } - verbose_printk("\n"); + printk("\n"); /* Hardware error interrupts can be deferred */ if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && oops_in_progress)){ - verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); + printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); #ifndef CONFIG_DEBUG_HWERR - verbose_printk(KERN_NOTICE "The remaining message may be meaningless\n" + printk(KERN_NOTICE "The remaining message may be meaningless\n" KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a" " better idea where it came from\n"); #else @@ -1032,47 +969,34 @@ void dump_bfin_mem(struct pt_regs *fp) /* And the last RETI points to the current userspace context */ if ((fp + 1)->pc >= current->mm->start_code && (fp + 1)->pc <= current->mm->end_code) { - verbose_printk(KERN_NOTICE "It might be better to look around here : \n"); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + printk(KERN_NOTICE "It might be better to look around here : \n"); + printk(KERN_NOTICE "-------------------------------------------\n"); show_regs(fp + 1); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + printk(KERN_NOTICE "-------------------------------------------\n"); } } #endif } -#endif } void show_regs(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE char buf [150]; struct irqaction *action; unsigned int i; unsigned long flags; - verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); - verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", + printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); + printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", (long)fp->seqstat, fp->ipend, fp->syscfg); - if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { - verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", - (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); -#ifdef EBIU_ERRMST - /* If the error was from the EBIU, print it out */ - if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { - verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", - bfin_read_EBIU_ERRMST()); - verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", - bfin_read_EBIU_ERRADD()); - } -#endif - } - verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", + printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", + (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); + printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", fp->seqstat & SEQSTAT_EXCAUSE); for (i = 6; i <= 15 ; i++) { if (fp->ipend & (1 << i)) { decode_address(buf, bfin_read32(EVT0 + 4*i)); - verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); } } @@ -1085,65 +1009,64 @@ void show_regs(struct pt_regs *fp) goto unlock; decode_address(buf, (unsigned int)action->handler); - verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); + printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); for (action = action->next; action; action = action->next) { decode_address(buf, (unsigned int)action->handler); - verbose_printk(", %s", buf); + printk(", %s", buf); } - verbose_printk("\n"); + printk("\n"); unlock: spin_unlock_irqrestore(&irq_desc[i].lock, flags); } } decode_address(buf, fp->rete); - verbose_printk(KERN_NOTICE " RETE: %s\n", buf); + printk(KERN_NOTICE " RETE: %s\n", buf); decode_address(buf, fp->retn); - verbose_printk(KERN_NOTICE " RETN: %s\n", buf); + printk(KERN_NOTICE " RETN: %s\n", buf); decode_address(buf, fp->retx); - verbose_printk(KERN_NOTICE " RETX: %s\n", buf); + printk(KERN_NOTICE " RETX: %s\n", buf); decode_address(buf, fp->rets); - verbose_printk(KERN_NOTICE " RETS: %s\n", buf); + printk(KERN_NOTICE " RETS: %s\n", buf); decode_address(buf, fp->pc); - verbose_printk(KERN_NOTICE " PC : %s\n", buf); + printk(KERN_NOTICE " PC : %s\n", buf); if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { decode_address(buf, saved_dcplb_fault_addr); - verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); + printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); decode_address(buf, saved_icplb_fault_addr); - verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); + printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); } - verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n"); - verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", + printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n"); + printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", fp->r0, fp->r1, fp->r2, fp->r3); - verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", + printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", fp->r4, fp->r5, fp->r6, fp->r7); - verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", + printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", fp->p0, fp->p1, fp->p2, fp->p3); - verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", + printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", fp->p4, fp->p5, fp->fp, (long)fp); - verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", + printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, fp->lc0); - verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", + printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, fp->lc1); - verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", + printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", fp->b0, fp->l0, fp->m0, fp->i0); - verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", + printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", fp->b1, fp->l1, fp->m1, fp->i1); - verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", + printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", fp->b2, fp->l2, fp->m2, fp->i2); - verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", + printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", fp->b3, fp->l3, fp->m3, fp->i3); - verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", fp->a0w, fp->a0x, fp->a1w, fp->a1x); - verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", + printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", rdusp(), fp->astat); - verbose_printk(KERN_NOTICE "\n"); -#endif + printk(KERN_NOTICE "\n"); } #ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 diff --git a/trunk/arch/blackfin/mach-bf527/boards/Kconfig b/trunk/arch/blackfin/mach-bf527/boards/Kconfig index df224d04e167..8bf9e58f0148 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/Kconfig +++ b/trunk/arch/blackfin/mach-bf527/boards/Kconfig @@ -14,9 +14,4 @@ config BFIN527_BLUETECHNIX_CM help CM-BF527 support for EVAL- and DEV-Board. -config BFIN526_EZBRD - bool "BF526-EZBRD" - help - BF526-EZBRD/EZKIT Lite board support. - endchoice diff --git a/trunk/arch/blackfin/mach-bf527/boards/Makefile b/trunk/arch/blackfin/mach-bf527/boards/Makefile index eb6ed3362f9f..7ba7d256bbb8 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/Makefile +++ b/trunk/arch/blackfin/mach-bf527/boards/Makefile @@ -4,4 +4,3 @@ obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o obj-$(CONFIG_BFIN527_BLUETECHNIX_CM) += cm_bf527.o -obj-$(CONFIG_BFIN526_EZBRD) += ezbrd.o diff --git a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c index 9ea440bbb13d..d22bc7773717 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -43,7 +43,10 @@ #include #include #include +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) #include +#endif +#include #include #include #include @@ -127,16 +130,6 @@ static struct resource musb_resources[] = { }, }; -static struct musb_hdrc_config musb_config = { - .multipoint = 0, - .dyn_fifo = 0, - .soft_con = 1, - .dma = 1, - .num_eps = 7, - .dma_channels = 7, - .gpio_vrsel = GPIO_PF11, -}; - static struct musb_hdrc_platform_data musb_plat = { #if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, @@ -145,7 +138,7 @@ static struct musb_hdrc_platform_data musb_plat = { #elif defined(CONFIG_USB_GADGET_MUSB_HDRC) .mode = MUSB_PERIPHERAL, #endif - .config = &musb_config, + .multipoint = 0, }; static u64 musb_dmamask = ~(u32)0; @@ -208,7 +201,7 @@ static struct mtd_partition partition_info[] = { { .name = "linux kernel(nand)", .offset = 0, - .size = 4 * 1024 * 1024, + .size = 4 * SIZE_1M, }, { .name = "file system(nand)", diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c b/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c deleted file mode 100644 index 36c87b6fbdec..000000000000 --- a/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c +++ /dev/null @@ -1,734 +0,0 @@ -/* - * File: arch/blackfin/mach-bf527/boards/ezbrd.c - * Based on: arch/blackfin/mach-bf537/boards/stamp.c - * Author: Aidan Williams - * - * Created: - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2008 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -const char bfin_board_name[] = "BF526-EZBRD"; - -/* - * Driver needs to know address, irq and flag pin. - */ - -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) -static struct resource musb_resources[] = { - [0] = { - .start = 0xffc03800, - .end = 0xffc03cff, - .flags = IORESOURCE_MEM, - }, - [1] = { /* general IRQ */ - .start = IRQ_USB_INT0, - .end = IRQ_USB_INT0, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, - [2] = { /* DMA IRQ */ - .start = IRQ_USB_DMA, - .end = IRQ_USB_DMA, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct musb_hdrc_config musb_config = { - .multipoint = 0, - .dyn_fifo = 0, - .soft_con = 1, - .dma = 1, - .num_eps = 7, - .dma_channels = 7, - .gpio_vrsel = GPIO_PG13, -}; - -static struct musb_hdrc_platform_data musb_plat = { -#if defined(CONFIG_USB_MUSB_OTG) - .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_HDRC_HCD) - .mode = MUSB_HOST, -#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) - .mode = MUSB_PERIPHERAL, -#endif - .config = &musb_config, -}; - -static u64 musb_dmamask = ~(u32)0; - -static struct platform_device musb_device = { - .name = "musb_hdrc", - .id = 0, - .dev = { - .dma_mask = &musb_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &musb_plat, - }, - .num_resources = ARRAY_SIZE(musb_resources), - .resource = musb_resources, -}; -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) -static struct mtd_partition ezbrd_partitions[] = { - { - .name = "bootloader(nor)", - .size = 0x40000, - .offset = 0, - }, { - .name = "linux kernel(nor)", - .size = 0x1C0000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "file system(nor)", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct physmap_flash_data ezbrd_flash_data = { - .width = 2, - .parts = ezbrd_partitions, - .nr_parts = ARRAY_SIZE(ezbrd_partitions), -}; - -static struct resource ezbrd_flash_resource = { - .start = 0x20000000, - .end = 0x203fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ezbrd_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ezbrd_flash_data, - }, - .num_resources = 1, - .resource = &ezbrd_flash_resource, -}; -#endif - -#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) -static struct mtd_partition partition_info[] = { - { - .name = "linux kernel(nand)", - .offset = 0, - .size = 4 * 1024 * 1024, - }, - { - .name = "file system(nand)", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct bf5xx_nand_platform bf5xx_nand_platform = { - .page_size = NFC_PG_SIZE_256, - .data_width = NFC_NWIDTH_8, - .partitions = partition_info, - .nr_partitions = ARRAY_SIZE(partition_info), - .rd_dly = 3, - .wr_dly = 3, -}; - -static struct resource bf5xx_nand_resources[] = { - { - .start = NFC_CTL, - .end = NFC_DATA_RD + 2, - .flags = IORESOURCE_MEM, - }, - { - .start = CH_NFC, - .end = CH_NFC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bf5xx_nand_device = { - .name = "bf5xx-nand", - .id = 0, - .num_resources = ARRAY_SIZE(bf5xx_nand_resources), - .resource = bf5xx_nand_resources, - .dev = { - .platform_data = &bf5xx_nand_platform, - }, -}; -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mac_device = { - .name = "bfin_mac", -}; -#endif - -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader(spi)", - .size = 0x00040000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - }, { - .name = "linux kernel(spi)", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p16", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) -static struct bfin5xx_spi_chip spi_mmc_chip_info = { - .enable_dma = 1, - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -static struct bfin5xx_spi_chip spi_ad7877_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; - -static const struct ad7877_platform_data bfin_ad7877_ts_info = { - .model = 7877, - .vref_delay_usecs = 50, /* internal, no capacitor */ - .x_plate_ohms = 419, - .y_plate_ohms = 486, - .pressure_max = 1000, - .pressure_min = 0, - .stopacq_polarity = 1, - .first_conversion_delay = 3, - .acquisition_time = 1, - .averaging = 1, - .pen_down_acc_interval = 1, -}; -#endif - -#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ - && defined(CONFIG_SND_SOC_WM8731_SPI) -static struct bfin5xx_spi_chip spi_wm8731_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) -static struct bfin5xx_spi_chip spidev_chip_info = { - .enable_dma = 0, - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) -static struct bfin5xx_spi_chip lq035q1_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 8, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) - { - .modalias = "spi_mmc_dummy", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 0, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "spi_mmc", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = CONFIG_SPI_MMC_CS_CHAN, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J11_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 8 - CONFIG_J19_JUMPER, - .controller_data = &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) - { - .modalias = "ad7877", - .platform_data = &bfin_ad7877_ts_info, - .irq = IRQ_PF8, - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .controller_data = &spi_ad7877_chip_info, - }, -#endif -#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ - && defined(CONFIG_SND_SOC_WM8731_SPI) - { - .modalias = "wm8731", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 5, - .controller_data = &spi_wm8731_chip_info, - .mode = SPI_MODE_0, - }, -#endif -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) - { - .modalias = "spidev", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &spidev_chip_info, - }, -#endif -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) - { - .modalias = "bfin-lq035q1-spi", - .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &lq035q1_spi_chip_info, - .mode = SPI_CPHA | SPI_CPOL, - }, -#endif -}; - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* SPI controller data */ -static struct bfin5xx_spi_master bfin_spi0_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ - .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, -}; - -/* SPI (0) */ -static struct resource bfin_spi0_resource[] = { - [0] = { - .start = SPI0_REGBASE, - .end = SPI0_REGBASE + 0xFF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = CH_SPI, - .end = CH_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_spi0_device = { - .name = "bfin-spi", - .id = 0, /* Bus number */ - .num_resources = ARRAY_SIZE(bfin_spi0_resource), - .resource = bfin_spi0_resource, - .dev = { - .platform_data = &bfin_spi0_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { -#ifdef CONFIG_SERIAL_BFIN_UART0 - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -#endif -#ifdef CONFIG_SERIAL_BFIN_UART1 - { - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -#endif -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) -static struct resource bfin_sir_resources[] = { -#ifdef CONFIG_BFIN_SIR0 - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -#endif -#ifdef CONFIG_BFIN_SIR1 - { - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -#endif -}; - -static struct platform_device bfin_sir_device = { - .name = "bfin_sir", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_sir_resources), - .resource = bfin_sir_resources, -}; -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static struct resource bfin_twi0_resource[] = { - [0] = { - .start = TWI0_REGBASE, - .end = TWI0_REGBASE, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TWI, - .end = IRQ_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device i2c_bfin_twi_device = { - .name = "i2c-bfin-twi", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_twi0_resource), - .resource = bfin_twi0_resource, -}; -#endif - -#ifdef CONFIG_I2C_BOARDINFO -static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) - { - I2C_BOARD_INFO("pcf8574_lcd", 0x22), - }, -#endif -#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) - { - I2C_BOARD_INFO("pcf8574_keypad", 0x27), - .irq = IRQ_PF8, - }, -#endif -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, -}; -#endif - -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -#include -#include - -static struct gpio_keys_button bfin_gpio_keys_table[] = { - {BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"}, - {BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"}, -}; - -static struct gpio_keys_platform_data bfin_gpio_keys_data = { - .buttons = bfin_gpio_keys_table, - .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), -}; - -static struct platform_device bfin_device_gpiokeys = { - .name = "gpio-keys", - .dev = { - .platform_data = &bfin_gpio_keys_data, - }, -}; -#endif - -static struct resource bfin_gpios_resources = { - .start = 0, - .end = MAX_BLACKFIN_GPIOS - 1, - .flags = IORESOURCE_IRQ, -}; - -static struct platform_device bfin_gpios_device = { - .name = "simple-gpio", - .id = -1, - .num_resources = 1, - .resource = &bfin_gpios_resources, -}; - -static const unsigned int cclk_vlev_datasheet[] = -{ - VRPAIR(VLEV_100, 400000000), - VRPAIR(VLEV_105, 426000000), - VRPAIR(VLEV_110, 500000000), - VRPAIR(VLEV_115, 533000000), - VRPAIR(VLEV_120, 600000000), -}; - -static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { - .tuple_tab = cclk_vlev_datasheet, - .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), - .vr_settling_time = 25 /* us */, -}; - -static struct platform_device bfin_dpmc = { - .name = "bfin dpmc", - .dev = { - .platform_data = &bfin_dmpc_vreg_data, - }, -}; - -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) -#include - -static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { - .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, - .use_bl = 1, - .gpio_bl = GPIO_PG12, -}; - -static struct resource bfin_lq035q1_resources[] = { - { - .start = IRQ_PPI_ERROR, - .end = IRQ_PPI_ERROR, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_lq035q1_device = { - .name = "bfin-lq035q1", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_lq035q1_resources), - .resource = bfin_lq035q1_resources, - .dev = { - .platform_data = &bfin_lq035q1_data, - }, -}; -#endif - -static struct platform_device *stamp_devices[] __initdata = { - - &bfin_dpmc, - -#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) - &bf5xx_nand_device, -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) - &musb_device, -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mac_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &bfin_spi0_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) - &bfin_lq035q1_device, -#endif - -#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) - &bfin_sir_device, -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) - &i2c_bfin_twi_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) - &bfin_sport0_uart_device, - &bfin_sport1_uart_device, -#endif - -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) - &bfin_device_gpiokeys, -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) - &ezbrd_flash_device, -#endif - - &bfin_gpios_device, -}; - -static int __init stamp_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __func__); - -#ifdef CONFIG_I2C_BOARDINFO - i2c_register_board_info(0, bfin_i2c_board_info, - ARRAY_SIZE(bfin_i2c_board_info)); -#endif - - platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); - return 0; -} - -arch_initcall(stamp_init); - -void native_machine_restart(char *cmd) -{ - /* workaround reboot hang when booting from SPI */ - if ((bfin_read_SYSCR() & 0x7) == 0x3) - bfin_gpio_reset_spi0_ssel1(); -} - -void bfin_get_ether_addr(char *addr) -{ - /* the MAC is stored in OTP memory page 0xDF */ - u32 ret; - u64 otp_mac; - u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A; - - ret = otp_read(0xDF, 0x00, &otp_mac); - if (!(ret & 0x1)) { - char *otp_mac_p = (char *)&otp_mac; - for (ret = 0; ret < 6; ++ret) - addr[ret] = otp_mac_p[5 - ret]; - } -} -EXPORT_SYMBOL(bfin_get_ether_addr); diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c index 8ee2b744e234..762f754c06cc 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c @@ -42,7 +42,10 @@ #include #include #include +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) #include +#endif +#include #include #include #include @@ -126,16 +129,6 @@ static struct resource musb_resources[] = { }, }; -static struct musb_hdrc_config musb_config = { - .multipoint = 0, - .dyn_fifo = 0, - .soft_con = 1, - .dma = 1, - .num_eps = 7, - .dma_channels = 7, - .gpio_vrsel = GPIO_PG13, -}; - static struct musb_hdrc_platform_data musb_plat = { #if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, @@ -144,7 +137,7 @@ static struct musb_hdrc_platform_data musb_plat = { #elif defined(CONFIG_USB_GADGET_MUSB_HDRC) .mode = MUSB_PERIPHERAL, #endif - .config = &musb_config, + .multipoint = 0, }; static u64 musb_dmamask = ~(u32)0; @@ -225,7 +218,7 @@ static struct mtd_partition partition_info[] = { { .name = "linux kernel(nand)", .offset = 0, - .size = 4 * 1024 * 1024, + .size = 4 * SIZE_1M, }, { .name = "file system(nand)", @@ -853,38 +846,6 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) -#include -#include - -static struct bfin_rotary_platform_data bfin_rotary_data = { - /*.rotary_up_key = KEY_UP,*/ - /*.rotary_down_key = KEY_DOWN,*/ - .rotary_rel_code = REL_WHEEL, - .rotary_button_key = KEY_ENTER, - .debounce = 10, /* 0..17 */ - .mode = ROT_QUAD_ENC | ROT_DEBE, -}; - -static struct resource bfin_rotary_resources[] = { - { - .start = IRQ_CNT, - .end = IRQ_CNT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_rotary_device = { - .name = "bfin-rotary", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_rotary_resources), - .resource = bfin_rotary_resources, - .dev = { - .platform_data = &bfin_rotary_data, - }, -}; -#endif - static struct resource bfin_gpios_resources = { .start = 0, .end = MAX_BLACKFIN_GPIOS - 1, @@ -1001,10 +962,6 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_device_gpiokeys, #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) - &bfin_rotary_device, -#endif - #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) &ezkit_flash_device, #endif diff --git a/trunk/arch/blackfin/mach-bf527/head.S b/trunk/arch/blackfin/mach-bf527/head.S index 0eb1da85db73..28c486191209 100644 --- a/trunk/arch/blackfin/mach-bf527/head.S +++ b/trunk/arch/blackfin/mach-bf527/head.S @@ -87,9 +87,6 @@ ENTRY(_start_dma_code) r1 = PLL_BYPASS; /* Bypass the PLL? */ r1 = r1 << 8; /* Shift it over */ r0 = r1 | r0; /* add them all together */ -#ifdef ANOMALY_05000265 - BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */ -#endif p0.h = hi(PLL_CTL); p0.l = lo(PLL_CTL); /* Load the address */ diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h index 62373e61c585..b7b166f4f064 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h @@ -7,24 +7,12 @@ */ /* This file shoule be up to date with: - * - Revision B, 08/12/2008; ADSP-BF526 Blackfin Processor Anomaly List - * - Revision E, 08/18/2008; ADSP-BF527 Blackfin Processor Anomaly List + * - Revision C, 01/25/2008; ADSP-BF527 Blackfin Processor Anomaly List */ #ifndef _MACH_ANOMALY_H_ #define _MACH_ANOMALY_H_ -#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) -# define ANOMALY_BF526 1 -#else -# define ANOMALY_BF526 0 -#endif -#if defined(__ADSPBF523__) || defined(__ADSPBF525__) || defined(__ADSPBF527__) -# define ANOMALY_BF527 1 -#else -# define ANOMALY_BF527 0 -#endif - /* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported */ #define ANOMALY_05000074 (1) /* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */ @@ -35,124 +23,68 @@ #define ANOMALY_05000245 (1) /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ #define ANOMALY_05000265 (1) -/* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ -#define ANOMALY_05000310 (1) +/* New Feature: EMAC TX DMA Word Alignment */ +#define ANOMALY_05000285 (1) /* Errors when SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */ -#define ANOMALY_05000312 (ANOMALY_BF527) -/* PPI Is Level-Sensitive on First Transfer In Single Frame Sync Modes */ -#define ANOMALY_05000313 (__SILICON_REVISION__ < 2) +#define ANOMALY_05000312 (1) /* Incorrect Access of OTP_STATUS During otp_write() Function */ -#define ANOMALY_05000328 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000328 (1) /* Disallowed Configuration Prevents Subsequent Allowed Configuration on Host DMA Port */ -#define ANOMALY_05000337 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000337 (1) /* Ethernet MAC MDIO Reads Do Not Meet IEEE Specification */ -#define ANOMALY_05000341 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000341 (1) /* TWI May Not Operate Correctly Under Certain Signal Termination Conditions */ -#define ANOMALY_05000342 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000342 (1) /* USB Calibration Value Is Not Initialized */ -#define ANOMALY_05000346 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* USB Calibration Value to use */ -#define ANOMALY_05000346_value 0xE510 +#define ANOMALY_05000346 (1) /* Preboot Routine Incorrectly Alters Reset Value of USB Register */ -#define ANOMALY_05000347 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000347 (1) /* Security Features Are Not Functional */ -#define ANOMALY_05000348 (ANOMALY_BF527 && __SILICON_REVISION__ < 1) -/* bfrom_SysControl() Firmware Function Performs Improper System Reset */ -#define ANOMALY_05000353 (ANOMALY_BF526) +#define ANOMALY_05000348 (__SILICON_REVISION__ < 1) /* Regulator Programming Blocked when Hibernate Wakeup Source Remains Active */ -#define ANOMALY_05000355 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000355 (1) /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ -#define ANOMALY_05000357 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000357 (1) /* Incorrect Revision Number in DSPID Register */ -#define ANOMALY_05000364 (ANOMALY_BF527 && __SILICON_REVISION__ == 1) +#define ANOMALY_05000364 (__SILICON_REVISION__ > 0) /* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */ #define ANOMALY_05000366 (1) -/* Incorrect Default CSEL Value in PLL_DIV */ -#define ANOMALY_05000368 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +/* New Feature: Higher Default CCLK Rate */ +#define ANOMALY_05000368 (1) /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ -#define ANOMALY_05000371 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000371 (1) /* Authentication Fails To Initiate */ -#define ANOMALY_05000376 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000376 (__SILICON_REVISION__ > 0) /* Data Read From L3 Memory by USB DMA May be Corrupted */ -#define ANOMALY_05000380 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* 8-Bit NAND Flash Boot Mode Not Functional */ -#define ANOMALY_05000382 (__SILICON_REVISION__ < 2) -/* Host Must Not Read Back During Host DMA Boot */ -#define ANOMALY_05000384 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Boot from OTP Memory Not Functional */ -#define ANOMALY_05000385 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* bfrom_SysControl() Firmware Routine Not Functional */ -#define ANOMALY_05000386 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Programmable Preboot Settings Not Functional */ -#define ANOMALY_05000387 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* CRC32 Checksum Support Not Functional */ -#define ANOMALY_05000388 (__SILICON_REVISION__ < 2) +#define ANOMALY_05000380 (1) +/* USB Full-speed Mode not Fully Tested */ +#define ANOMALY_05000381 (1) +/* New Feature: Boot from OTP Memory */ +#define ANOMALY_05000385 (1) +/* New Feature: bfrom_SysControl() Routine */ +#define ANOMALY_05000386 (1) +/* New Feature: Programmable Preboot Settings */ +#define ANOMALY_05000387 (1) /* Reset Vector Must Not Be in SDRAM Memory Space */ -#define ANOMALY_05000389 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* pTempCurrent Not Present in ADI_BOOT_DATA Structure */ -#define ANOMALY_05000392 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Deprecated Value of dTempByteCount in ADI_BOOT_DATA Structure */ -#define ANOMALY_05000393 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Log Buffer Not Functional */ -#define ANOMALY_05000394 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Hook Routine Not Functional */ -#define ANOMALY_05000395 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Header Indirect Bit Not Functional */ -#define ANOMALY_05000396 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* BK_ONES, BK_ZEROS, and BK_DATECODE Constants Not Functional */ -#define ANOMALY_05000397 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* SWRESET, DFRESET and WDRESET Bits in the SYSCR Register Not Functional */ -#define ANOMALY_05000398 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* BCODE_NOBOOT in BCODE Field of SYSCR Register Not Functional */ -#define ANOMALY_05000399 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) +#define ANOMALY_05000389 (1) +/* New Feature: pTempCurrent Added to ADI_BOOT_DATA Structure */ +#define ANOMALY_05000392 (1) +/* New Feature: dTempByteCount Value Increased in ADI_BOOT_DATA Structure */ +#define ANOMALY_05000393 (1) +/* New Feature: Log Buffer Functionality */ +#define ANOMALY_05000394 (1) +/* New Feature: Hook Routine Functionality */ +#define ANOMALY_05000395 (1) +/* New Feature: Header Indirect Bit */ +#define ANOMALY_05000396 (1) +/* New Feature: BK_ONES, BK_ZEROS, and BK_DATECODE Constants */ +#define ANOMALY_05000397 (1) +/* New Feature: SWRESET, DFRESET and WDRESET Bits Added to SYSCR Register */ +#define ANOMALY_05000398 (1) +/* New Feature: BCODE_NOBOOT Added to BCODE Field of SYSCR Register */ +#define ANOMALY_05000399 (1) /* PPI Data Signals D0 and D8 do not Tristate After Disabling PPI */ -#define ANOMALY_05000401 (__SILICON_REVISION__ < 2) -/* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */ -#define ANOMALY_05000403 (__SILICON_REVISION__ < 2) -/* Lockbox SESR Disallows Certain User Interrupts */ -#define ANOMALY_05000404 (__SILICON_REVISION__ < 2) -/* Lockbox SESR Firmware Does Not Save/Restore Full Context */ -#define ANOMALY_05000405 (1) -/* Lockbox SESR Firmware Arguments Are Not Retained After First Initialization */ -#define ANOMALY_05000407 (__SILICON_REVISION__ < 2) -/* Lockbox Firmware Memory Cleanup Routine Does not Clear Registers */ -#define ANOMALY_05000408 (1) -/* Lockbox firmware leaves MDMA0 channel enabled */ -#define ANOMALY_05000409 (__SILICON_REVISION__ < 2) -/* Incorrect Default Internal Voltage Regulator Setting */ -#define ANOMALY_05000410 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* bfrom_SysControl() Firmware Function Cannot be Used to Enter Power Saving Modes */ -#define ANOMALY_05000411 (__SILICON_REVISION__ < 2) -/* OTP_CHECK_FOR_PREV_WRITE Bit is Not Functional in bfrom_OtpWrite() API */ -#define ANOMALY_05000414 (__SILICON_REVISION__ < 2) -/* DEB2_URGENT Bit Not Functional */ -#define ANOMALY_05000415 (__SILICON_REVISION__ < 2) -/* Speculative Fetches Can Cause Undesired External FIFO Operations */ -#define ANOMALY_05000416 (1) -/* SPORT0 Ignores External TSCLK0 on PG14 When TMR6 is an Output */ -#define ANOMALY_05000417 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* tSFSPE and tHFSPE Do Not Meet Data Sheet Specifications */ -#define ANOMALY_05000418 (__SILICON_REVISION__ < 2) -/* USB PLL_STABLE Bit May Not Accurately Reflect the USB PLL's Status */ -#define ANOMALY_05000420 (__SILICON_REVISION__ < 2) -/* TWI Fall Time (Tof) May Violate the Minimum I2C Specification */ -#define ANOMALY_05000421 (1) -/* TWI Input Capacitance (Ci) May Violate the Maximum I2C Specification */ -#define ANOMALY_05000422 (ANOMALY_BF527 && __SILICON_REVISION__ > 1) -/* Certain Ethernet Frames With Errors are Misclassified in RMII Mode */ -#define ANOMALY_05000423 (__SILICON_REVISION__ < 2) -/* Internal Voltage Regulator Not Trimmed */ -#define ANOMALY_05000424 (ANOMALY_BF527 && __SILICON_REVISION__ < 2) -/* Multichannel SPORT Channel Misalignment Under Specific Configuration */ -#define ANOMALY_05000425 (__SILICON_REVISION__ < 2) -/* Speculative Fetches of Indirect-Pointer Instructions Can Cause Spurious Hardware Errors */ -#define ANOMALY_05000426 (1) -/* WB_EDGE Bit in NFC_IRQSTAT Incorrectly Reflects Buffer Status Instead of IRQ Status */ -#define ANOMALY_05000429 (__SILICON_REVISION__ < 2) -/* Software System Reset Corrupts PLL_LOCKCNT Register */ -#define ANOMALY_05000430 (ANOMALY_BF527 && __SILICON_REVISION__ > 1) -/* bfrom_SysControl() Does Not Clear SIC_IWR1 Before Executing PLL Programming Sequence */ -#define ANOMALY_05000432 (ANOMALY_BF526) +#define ANOMALY_05000401 (1) /* Anomalies that don't exist on this proc */ #define ANOMALY_05000125 (0) @@ -165,8 +97,6 @@ #define ANOMALY_05000263 (0) #define ANOMALY_05000266 (0) #define ANOMALY_05000273 (0) -#define ANOMALY_05000285 (0) -#define ANOMALY_05000307 (0) #define ANOMALY_05000311 (0) #define ANOMALY_05000323 (0) #define ANOMALY_05000363 (0) diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/bf527.h b/trunk/arch/blackfin/mach-bf527/include/mach/bf527.h index 144f08d3f8ea..056eb4b9cd25 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/bf527.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/bf527.h @@ -30,6 +30,8 @@ #ifndef __MACH_BF527_H__ #define __MACH_BF527_H__ +#define SUPPORTED_REVID 2 + #define OFFSET_(x) ((x) & 0x0000FFFF) /*some misc defines*/ @@ -110,31 +112,16 @@ #ifdef CONFIG_BF527 #define CPU "BF527" -#define CPUID 0x27e4 -#endif -#ifdef CONFIG_BF526 -#define CPU "BF526" -#define CPUID 0x27e4 #endif #ifdef CONFIG_BF525 #define CPU "BF525" -#define CPUID 0x27e4 -#endif -#ifdef CONFIG_BF524 -#define CPU "BF524" -#define CPUID 0x27e4 -#endif -#ifdef CONFIG_BF523 -#define CPU "BF523" -#define CPUID 0x27e4 #endif #ifdef CONFIG_BF522 #define CPU "BF522" -#define CPUID 0x27e4 #endif - #ifndef CPU -#error Unknown CPU type - This kernel doesn't seem to be configured properly +#define CPU "UNKNOWN" +#define CPUID 0x0 #endif #endif /* __MACH_BF527_H__ */ diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/trunk/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h index 75722d6008b0..2526b6ed6faa 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h @@ -78,9 +78,6 @@ # define CONFIG_UART1_RTS_PIN -1 # endif #endif - -#define BFIN_UART_TX_FIFO_SIZE 2 - /* * The pin configuration is different from schematic */ @@ -122,6 +119,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) bfin_write16(uart->port.membase + OFFSET_LSR, -1); } +struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; @@ -166,6 +164,8 @@ struct bfin_serial_res bfin_serial_resource[] = { #endif }; +int nr_ports = ARRAY_SIZE(bfin_serial_resource); + #define DRIVER_NAME "bfin-uart" static void bfin_serial_hw_init(struct bfin_serial_port *uart) diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/trunk/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 68b55d03fedf..6ac2ed7026eb 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -1840,33 +1840,6 @@ #define DPRESCALE 0xf /* Load Counter Register */ -/* CNT_COMMAND bit field options */ - -#define W1LCNT_ZERO 0x0001 /* write 1 to load CNT_COUNTER with zero */ -#define W1LCNT_MIN 0x0004 /* write 1 to load CNT_COUNTER from CNT_MIN */ -#define W1LCNT_MAX 0x0008 /* write 1 to load CNT_COUNTER from CNT_MAX */ - -#define W1LMIN_ZERO 0x0010 /* write 1 to load CNT_MIN with zero */ -#define W1LMIN_CNT 0x0020 /* write 1 to load CNT_MIN from CNT_COUNTER */ -#define W1LMIN_MAX 0x0080 /* write 1 to load CNT_MIN from CNT_MAX */ - -#define W1LMAX_ZERO 0x0100 /* write 1 to load CNT_MAX with zero */ -#define W1LMAX_CNT 0x0200 /* write 1 to load CNT_MAX from CNT_COUNTER */ -#define W1LMAX_MIN 0x0400 /* write 1 to load CNT_MAX from CNT_MIN */ - -/* CNT_CONFIG bit field options */ - -#define CNTMODE_QUADENC 0x0000 /* quadrature encoder mode */ -#define CNTMODE_BINENC 0x0100 /* binary encoder mode */ -#define CNTMODE_UDCNT 0x0200 /* up/down counter mode */ -#define CNTMODE_DIRCNT 0x0400 /* direction counter mode */ -#define CNTMODE_DIRTMR 0x0500 /* direction timer mode */ - -#define BNDMODE_COMP 0x0000 /* boundary compare mode */ -#define BNDMODE_ZERO 0x1000 /* boundary compare and zero mode */ -#define BNDMODE_CAPT 0x2000 /* boundary capture mode */ -#define BNDMODE_AEXT 0x3000 /* boundary auto-extend mode */ - /* Bit masks for OTP_CONTROL */ #define FUSE_FADDR 0x1ff /* OTP/Fuse Address */ diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h index 7f6da2c386bb..ae4d205bfcf5 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/portmux.h @@ -67,10 +67,6 @@ #define P_UART1_RX (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(1)) #endif -#define P_CNT_CZM (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(3)) -#define P_CNT_CDG (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(3)) -#define P_CNT_CUD (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(3)) - #define P_HWAIT (P_DONTCARE) #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) diff --git a/trunk/arch/blackfin/mach-bf533/boards/H8606.c b/trunk/arch/blackfin/mach-bf533/boards/H8606.c index 72ac3ac8ef76..c66a68f30239 100644 --- a/trunk/arch/blackfin/mach-bf533/boards/H8606.c +++ b/trunk/arch/blackfin/mach-bf533/boards/H8606.c @@ -9,7 +9,7 @@ * Modified: * Copyright 2005 National ICT Australia (NICTA) * Copyright 2004-2006 Analog Devices Inc - * Copyright 2007,2008 HV Sistemas S.L. + * Copyright 2007 HV Sistemas S.L. * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * @@ -64,18 +64,18 @@ static struct platform_device rtc_device = { static struct resource dm9000_resources[] = { [0] = { .start = 0x20300000, - .end = 0x20300002, + .end = 0x20300000 + 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = 0x20300004, - .end = 0x20300006, + .start = 0x20300000 + 4, + .end = 0x20300000 + 5, .flags = IORESOURCE_MEM, }, [2] = { .start = IRQ_PF10, .end = IRQ_PF10, - .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IRQF_SHARED | IRQF_TRIGGER_HIGH), + .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), }, }; @@ -140,22 +140,18 @@ static struct platform_device net2272_bfin_device = { #if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) static struct mtd_partition bfin_spi_flash_partitions[] = { { - .name = "bootloader (spi)", - .size = 0x40000, + .name = "bootloader(spi)", + .size = 0x00060000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { - .name = "fpga (spi)", - .size = 0x30000, - .offset = 0x40000 + .name = "linux kernel(spi)", + .size = 0x100000, + .offset = 0x60000 }, { - .name = "linux kernel (spi)", - .size = 0x150000, - .offset = 0x70000 - }, { - .name = "jffs2 root file system (spi)", - .size = 0x640000, - .offset = 0x1c0000, + .name = "file system(spi)", + .size = 0x6a0000, + .offset = 0x00160000, } }; @@ -344,7 +340,7 @@ static struct platform_device bfin_sir_device = { static struct plat_serial8250_port serial8250_platform_data [] = { { - .membase = (void *)0x20200000, + .membase = 0x20200000, .mapbase = 0x20200000, .irq = IRQ_PF8, .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE, @@ -352,7 +348,7 @@ static struct plat_serial8250_port serial8250_platform_data [] = { .regshift = 1, .uartclk = 66666667, }, { - .membase = (void *)0x20200010, + .membase = 0x20200010, .mapbase = 0x20200010, .irq = IRQ_PF8, .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE, diff --git a/trunk/arch/blackfin/mach-bf533/head.S b/trunk/arch/blackfin/mach-bf533/head.S index 9fc95aaca439..01b2b7ead5ab 100644 --- a/trunk/arch/blackfin/mach-bf533/head.S +++ b/trunk/arch/blackfin/mach-bf533/head.S @@ -78,9 +78,6 @@ ENTRY(_start_dma_code) r1 = PLL_BYPASS; /* Bypass the PLL? */ r1 = r1 << 8; /* Shift it over */ r0 = r1 | r0; /* add them all together */ -#ifdef ANOMALY_05000265 - BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */ -#endif p0.h = hi(PLL_CTL); p0.l = lo(PLL_CTL); /* Load the address */ diff --git a/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h index f544fc56959a..8f7ea112fd3a 100644 --- a/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h @@ -7,7 +7,7 @@ */ /* This file shoule be up to date with: - * - Revision D, 06/18/2008; ADSP-BF531/BF532/BF533 Blackfin Processor Anomaly List + * - Revision C, 02/08/2008; ADSP-BF531/BF532/BF533 Blackfin Processor Anomaly List */ #ifndef _MACH_ANOMALY_H_ @@ -97,11 +97,11 @@ /* UART STB Bit Incorrectly Affects Receiver Setting */ #define ANOMALY_05000231 (__SILICON_REVISION__ < 5) /* PPI_FS3 Is Not Driven in 2 or 3 Internal Frame Sync Transmit Modes */ -#define ANOMALY_05000233 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000233 (__SILICON_REVISION__ < 4) /* Incorrect Revision Number in DSPID Register */ #define ANOMALY_05000234 (__SILICON_REVISION__ == 4) /* DF Bit in PLL_CTL Register Does Not Respond to Hardware Reset */ -#define ANOMALY_05000242 (__SILICON_REVISION__ < 5) +#define ANOMALY_05000242 (__SILICON_REVISION__ < 4) /* If I-Cache Is On, CSYNC/SSYNC/IDLE Around Change of Control Causes Failures */ #define ANOMALY_05000244 (__SILICON_REVISION__ < 5) /* Spurious Hardware Error from an Access in the Shadow of a Conditional Branch */ @@ -131,7 +131,7 @@ /* CSYNC/SSYNC/IDLE Causes Infinite Stall in Penultimate Instruction in Hardware Loop */ #define ANOMALY_05000264 (__SILICON_REVISION__ < 5) /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ -#define ANOMALY_05000265 (1) +#define ANOMALY_05000265 (__SILICON_REVISION__ < 5) /* High I/O Activity Causes Output Voltage of Internal Voltage Regulator (Vddint) to Increase */ #define ANOMALY_05000269 (__SILICON_REVISION__ < 5) /* High I/O Activity Causes Output Voltage of Internal Voltage Regulator (Vddint) to Decrease */ @@ -141,59 +141,56 @@ /* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */ #define ANOMALY_05000272 (1) /* Writes to Synchronous SDRAM Memory May Be Lost */ -#define ANOMALY_05000273 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000273 (1) /* Timing Requirements Change for External Frame Sync PPI Modes with Non-Zero PPI_DELAY */ #define ANOMALY_05000276 (1) /* Writes to an I/O Data Register One SCLK Cycle after an Edge Is Detected May Clear Interrupt */ -#define ANOMALY_05000277 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000277 (1) /* Disabling Peripherals with DMA Running May Cause DMA System Instability */ -#define ANOMALY_05000278 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000278 (1) /* False Hardware Error Exception When ISR Context Is Not Restored */ -#define ANOMALY_05000281 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000281 (1) /* Memory DMA Corruption with 32-Bit Data and Traffic Control */ -#define ANOMALY_05000282 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000282 (1) /* System MMR Write Is Stalled Indefinitely When Killed in a Particular Stage */ -#define ANOMALY_05000283 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000283 (1) /* SPORTs May Receive Bad Data If FIFOs Fill Up */ -#define ANOMALY_05000288 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000288 (1) /* Memory-To-Memory DMA Source/Destination Descriptors Must Be in Same Memory Space */ -#define ANOMALY_05000301 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000301 (1) /* SSYNCs After Writes To DMA MMR Registers May Not Be Handled Correctly */ #define ANOMALY_05000302 (__SILICON_REVISION__ < 5) /* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */ #define ANOMALY_05000305 (__SILICON_REVISION__ < 5) /* New Feature: Additional PPI Frame Sync Sampling Options (Not Available On Older Silicon) */ #define ANOMALY_05000306 (__SILICON_REVISION__ < 5) -/* SCKELOW Bit Does Not Maintain State Through Hibernate */ -#define ANOMALY_05000307 (1) /* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ #define ANOMALY_05000310 (1) /* Erroneous Flag (GPIO) Pin Operations under Specific Sequences */ -#define ANOMALY_05000311 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000311 (1) /* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */ -#define ANOMALY_05000312 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000312 (1) /* PPI Is Level-Sensitive on First Transfer */ -#define ANOMALY_05000313 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000313 (1) /* Killed System MMR Write Completes Erroneously On Next System MMR Access */ -#define ANOMALY_05000315 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000315 (1) /* Internal Voltage Regulator Values of 1.05V, 1.10V and 1.15V Not Allowed for LQFP Packages */ -#define ANOMALY_05000319 ((ANOMALY_BF531 || ANOMALY_BF532) && __SILICON_REVISION__ < 6) +#define ANOMALY_05000319 (ANOMALY_BF531 || ANOMALY_BF532) /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ -#define ANOMALY_05000357 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000357 (1) /* UART Break Signal Issues */ #define ANOMALY_05000363 (__SILICON_REVISION__ < 5) /* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */ #define ANOMALY_05000366 (1) /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ -#define ANOMALY_05000371 (__SILICON_REVISION__ < 6) +#define ANOMALY_05000371 (1) /* PPI Does Not Start Properly In Specific Mode */ -#define ANOMALY_05000400 (__SILICON_REVISION__ == 5) +#define ANOMALY_05000400 (__SILICON_REVISION__ >= 5) /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */ -#define ANOMALY_05000402 (__SILICON_REVISION__ == 5) +#define ANOMALY_05000402 (__SILICON_REVISION__ >= 5) /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */ #define ANOMALY_05000403 (1) -/* Speculative Fetches Can Cause Undesired External FIFO Operations */ -#define ANOMALY_05000416 (1) + /* These anomalies have been "phased" out of analog.com anomaly sheets and are * here to show running on older silicon just isn't feasible. @@ -271,7 +268,5 @@ /* Anomalies that don't exist on this proc */ #define ANOMALY_05000266 (0) #define ANOMALY_05000323 (0) -#define ANOMALY_05000353 (1) -#define ANOMALY_05000386 (1) #endif diff --git a/trunk/arch/blackfin/mach-bf533/include/mach/bf533.h b/trunk/arch/blackfin/mach-bf533/include/mach/bf533.h index dfc8c1ad2d7a..12a416931991 100644 --- a/trunk/arch/blackfin/mach-bf533/include/mach/bf533.h +++ b/trunk/arch/blackfin/mach-bf533/include/mach/bf533.h @@ -30,6 +30,8 @@ #ifndef __MACH_BF533_H__ #define __MACH_BF533_H__ +#define SUPPORTED_REVID 2 + #define OFFSET_(x) ((x) & 0x0000FFFF) /*some misc defines*/ @@ -141,19 +143,19 @@ #ifdef CONFIG_BF533 #define CPU "BF533" -#define CPUID 0x27a5 +#define CPUID 0x027a5000 #endif #ifdef CONFIG_BF532 #define CPU "BF532" -#define CPUID 0x275A +#define CPUID 0x0275A000 #endif #ifdef CONFIG_BF531 #define CPU "BF531" -#define CPUID 0x27a5 +#define CPUID 0x027a5000 #endif - #ifndef CPU -#error Unknown CPU type - This kernel doesn't seem to be configured properly +#define CPU "UNKNOWN" +#define CPUID 0x0 #endif #endif /* __MACH_BF533_H__ */ diff --git a/trunk/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/trunk/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index f3d9e495230c..ebf592b59aab 100644 --- a/trunk/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/trunk/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h @@ -69,8 +69,6 @@ # endif #endif -#define BFIN_UART_TX_FIFO_SIZE 2 - struct bfin_serial_port { struct uart_port port; unsigned int old_status; @@ -85,7 +83,7 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else -# if ANOMALY_05000363 +# if ANOMALY_05000230 unsigned int anomaly_threshold; # endif #endif @@ -113,6 +111,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) bfin_write16(uart->port.membase + OFFSET_LSR, -1); } +struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; @@ -143,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = { #define DRIVER_NAME "bfin-uart" +int nr_ports = BFIN_UART_NR_PORTS; static void bfin_serial_hw_init(struct bfin_serial_port *uart) { @@ -158,7 +158,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) } if (uart->rts_pin >= 0) { gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); + gpio_direction_input(uart->rts_pin, 0); } #endif } diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c index 8d394393201f..8482d22321f3 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c @@ -51,6 +51,7 @@ #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -554,7 +555,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { #endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -#include static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -575,30 +575,6 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { }; #endif -#if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE) -#include -static const struct ad7879_platform_data bfin_ad7879_ts_info = { - .model = 7879, /* Model = AD7879 */ - .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */ - .pressure_max = 10000, - .pressure_min = 0, - .first_conversion_delay = 3, /* wait 512us before do a first conversion */ - .acquisition_time = 1, /* 4us acquisition time per sample */ - .median = 2, /* do 8 measurements */ - .averaging = 1, /* take the average of 4 middle samples */ - .pen_down_acc_interval = 255, /* 9.4 ms */ - .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */ - .gpio_default = 1, /* During initialization set GPIO = HIGH */ -}; -#endif - -#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) -static struct bfin5xx_spi_chip spi_ad7879_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) static struct bfin5xx_spi_chip spidev_chip_info = { .enable_dma = 0, @@ -606,13 +582,6 @@ static struct bfin5xx_spi_chip spidev_chip_info = { }; #endif -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) -static struct bfin5xx_spi_chip lq035q1_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 8, -}; -#endif - #if defined(CONFIG_MTD_DATAFLASH) \ || defined(CONFIG_MTD_DATAFLASH_MODULE) @@ -752,18 +721,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .controller_data = &spi_ad7877_chip_info, }, #endif -#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) - { - .modalias = "ad7879", - .platform_data = &bfin_ad7879_ts_info, - .irq = IRQ_PF7, - .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &spi_ad7879_chip_info, - .mode = SPI_CPHA | SPI_CPOL, - }, -#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -773,16 +730,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .controller_data = &spidev_chip_info, }, #endif -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) - { - .modalias = "bfin-lq035q1-spi", - .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .controller_data = &lq035q1_spi_chip_info, - .mode = SPI_CPHA | SPI_CPOL, - }, -#endif }; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) @@ -830,34 +777,6 @@ static struct platform_device bfin_fb_adv7393_device = { }; #endif -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) -#include - -static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { - .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, - .use_bl = 0, /* let something else control the LCD Blacklight */ - .gpio_bl = GPIO_PF7, -}; - -static struct resource bfin_lq035q1_resources[] = { - { - .start = IRQ_PPI_ERROR, - .end = IRQ_PPI_ERROR, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_lq035q1_device = { - .name = "bfin-lq035q1", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_lq035q1_resources), - .resource = bfin_lq035q1_resources, - .dev = { - .platform_data = &bfin_lq035q1_data, - }, -}; -#endif - #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 @@ -937,7 +856,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) { I2C_BOARD_INFO("ad7142_joystick", 0x2C), - .irq = IRQ_PF5, + .irq = 55, }, #endif #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) @@ -948,14 +867,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) { I2C_BOARD_INFO("pcf8574_keypad", 0x27), - .irq = IRQ_PG6, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE) - { - I2C_BOARD_INFO("ad7879", 0x2F), - .irq = IRQ_PG5, - .platform_data = (void *)&bfin_ad7879_ts_info, + .irq = 72, }, #endif }; @@ -1085,10 +997,6 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_fb_device, #endif -#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) - &bfin_lq035q1_device, -#endif - #if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) &bfin_fb_adv7393_device, #endif diff --git a/trunk/arch/blackfin/mach-bf537/head.S b/trunk/arch/blackfin/mach-bf537/head.S index f5c94bf80e3b..12eb5cc571d0 100644 --- a/trunk/arch/blackfin/mach-bf537/head.S +++ b/trunk/arch/blackfin/mach-bf537/head.S @@ -87,9 +87,6 @@ ENTRY(_start_dma_code) r1 = PLL_BYPASS; /* Bypass the PLL? */ r1 = r1 << 8; /* Shift it over */ r0 = r1 | r0; /* add them all together */ -#ifdef ANOMALY_05000265 - BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */ -#endif p0.h = hi(PLL_CTL); p0.l = lo(PLL_CTL); /* Load the address */ diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h index c68992494f9e..8460ab9c324f 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h @@ -158,8 +158,6 @@ #define ANOMALY_05000266 (0) #define ANOMALY_05000311 (0) #define ANOMALY_05000323 (0) -#define ANOMALY_05000353 (1) #define ANOMALY_05000363 (0) -#define ANOMALY_05000386 (1) #endif diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/bf537.h b/trunk/arch/blackfin/mach-bf537/include/mach/bf537.h index 24d5c9d42323..cfe2a221112e 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/bf537.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/bf537.h @@ -30,6 +30,8 @@ #ifndef __MACH_BF537_H__ #define __MACH_BF537_H__ +#define SUPPORTED_REVID 2 + /* Masks for generic ERROR IRQ demultiplexing used in int-priority-sc.c */ #define SPI_ERR_MASK (TXCOL | RBSY | MODF | TXE) /* SPI_STAT */ @@ -121,19 +123,19 @@ #ifdef CONFIG_BF537 #define CPU "BF537" -#define CPUID 0x27c8 +#define CPUID 0x027c8000 #endif #ifdef CONFIG_BF536 #define CPU "BF536" -#define CPUID 0x27c8 +#define CPUID 0x027c8000 #endif #ifdef CONFIG_BF534 #define CPU "BF534" -#define CPUID 0x27c6 +#define CPUID 0x027c6000 #endif - #ifndef CPU -#error Unknown CPU type - This kernel doesn't seem to be configured properly +#define CPU "UNKNOWN" +#define CPUID 0x0 #endif #endif /* __MACH_BF537_H__ */ diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/trunk/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h index b3f87e1d16a2..1bf56ffa22f9 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h @@ -78,9 +78,6 @@ # define CONFIG_UART1_RTS_PIN -1 # endif #endif - -#define BFIN_UART_TX_FIFO_SIZE 2 - /* * The pin configuration is different from schematic */ @@ -122,6 +119,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) bfin_write16(uart->port.membase + OFFSET_LSR, -1); } +struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; @@ -166,6 +164,8 @@ struct bfin_serial_res bfin_serial_resource[] = { #endif }; +int nr_ports = ARRAY_SIZE(bfin_serial_resource); + #define DRIVER_NAME "bfin-uart" static void bfin_serial_hw_init(struct bfin_serial_port *uart) diff --git a/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c b/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c index 24192aaa9275..ce934ee174e0 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -36,8 +36,11 @@ #include #include #include +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) #include +#endif #include +#include #include #include #include @@ -172,7 +175,6 @@ static struct resource bfin_uart_resources[] = { { .start = 0xFFC03100, .end = 0xFFC031FF, - .flags = IORESOURCE_MEM, }, #endif }; @@ -266,16 +268,6 @@ static struct resource musb_resources[] = { }, }; -static struct musb_hdrc_config musb_config = { - .multipoint = 0, - .dyn_fifo = 0, - .soft_con = 1, - .dma = 1, - .num_eps = 7, - .dma_channels = 7, - .gpio_vrsel = GPIO_PH6, -}; - static struct musb_hdrc_platform_data musb_plat = { #if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, @@ -284,7 +276,7 @@ static struct musb_hdrc_platform_data musb_plat = { #elif defined(CONFIG_USB_GADGET_MUSB_HDRC) .mode = MUSB_PERIPHERAL, #endif - .config = &musb_config, + .multipoint = 0, }; static u64 musb_dmamask = ~(u32)0; @@ -329,12 +321,12 @@ static struct mtd_partition partition_info[] = { { .name = "linux kernel(nand)", .offset = 0, - .size = 4 * 1024 * 1024, + .size = 4 * SIZE_1M, }, { .name = "file system(nand)", - .offset = 4 * 1024 * 1024, - .size = (256 - 4) * 1024 * 1024, + .offset = 4 * SIZE_1M, + .size = (256 - 4) * SIZE_1M, }, }; diff --git a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c index 5288187a3ace..39357693046d 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c @@ -38,8 +38,11 @@ #include #include #include +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) #include +#endif #include +#include #include #include #include @@ -183,37 +186,6 @@ static struct platform_device bf54x_kpad_device = { }; #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) -#include - -static struct bfin_rotary_platform_data bfin_rotary_data = { - /*.rotary_up_key = KEY_UP,*/ - /*.rotary_down_key = KEY_DOWN,*/ - .rotary_rel_code = REL_WHEEL, - .rotary_button_key = KEY_ENTER, - .debounce = 10, /* 0..17 */ - .mode = ROT_QUAD_ENC | ROT_DEBE, -}; - -static struct resource bfin_rotary_resources[] = { - { - .start = IRQ_CNT, - .end = IRQ_CNT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_rotary_device = { - .name = "bfin-rotary", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_rotary_resources), - .resource = bfin_rotary_resources, - .dev = { - .platform_data = &bfin_rotary_data, - }, -}; -#endif - #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) static struct platform_device rtc_device = { .name = "rtc-bfin", @@ -342,16 +314,6 @@ static struct resource musb_resources[] = { }, }; -static struct musb_hdrc_config musb_config = { - .multipoint = 0, - .dyn_fifo = 0, - .soft_con = 1, - .dma = 1, - .num_eps = 7, - .dma_channels = 7, - .gpio_vrsel = GPIO_PE7, -}; - static struct musb_hdrc_platform_data musb_plat = { #if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, @@ -360,7 +322,7 @@ static struct musb_hdrc_platform_data musb_plat = { #elif defined(CONFIG_USB_GADGET_MUSB_HDRC) .mode = MUSB_PERIPHERAL, #endif - .config = &musb_config, + .multipoint = 0, }; static u64 musb_dmamask = ~(u32)0; @@ -405,7 +367,7 @@ static struct mtd_partition partition_info[] = { { .name = "linux kernel(nand)", .offset = 0, - .size = 4 * 1024 * 1024, + .size = 4 * SIZE_1M, }, { .name = "file system(nand)", @@ -462,7 +424,7 @@ static struct mtd_partition ezkit_partitions[] = { .offset = 0, }, { .name = "linux kernel(nor)", - .size = 0x400000, + .size = 0x1C0000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", @@ -479,7 +441,7 @@ static struct physmap_flash_data ezkit_flash_data = { static struct resource ezkit_flash_resource = { .start = 0x20000000, - .end = 0x21ffffff, + .end = 0x20ffffff, .flags = IORESOURCE_MEM, }; @@ -589,7 +551,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { { .modalias = "ad7877", .platform_data = &bfin_ad7877_ts_info, - .irq = IRQ_PJ11, /* newer boards (Rev 1.4+) use IRQ_PB4 */ + .irq = IRQ_PJ11, .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = 2, @@ -848,10 +810,6 @@ static struct platform_device *ezkit_devices[] __initdata = { &bf54x_kpad_device, #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) - &bfin_rotary_device, -#endif - #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) &i2c_bfin_twi0_device, #if !defined(CONFIG_BF542) diff --git a/trunk/arch/blackfin/mach-bf548/head.S b/trunk/arch/blackfin/mach-bf548/head.S index 93b361dff27b..4d5cfeacb123 100644 --- a/trunk/arch/blackfin/mach-bf548/head.S +++ b/trunk/arch/blackfin/mach-bf548/head.S @@ -73,19 +73,25 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; - /* enable self refresh via SRREQ */ +#if defined(CONFIG_BF54x) P2.H = hi(EBIU_RSTCTL); P2.L = lo(EBIU_RSTCTL); R0 = [P2]; BITSET (R0, 3); +#else + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITSET (R0, 24); +#endif [P2] = R0; SSYNC; - - /* wait for SRACK bit to be set */ +#if defined(CONFIG_BF54x) .LSRR_MODE: R0 = [P2]; CC = BITTST(R0, 4); if !CC JUMP .LSRR_MODE; +#endif r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ r0 = r0 << 9; /* Shift it over, */ @@ -94,9 +100,6 @@ ENTRY(_start_dma_code) r1 = PLL_BYPASS; /* Bypass the PLL? */ r1 = r1 << 8; /* Shift it over */ r0 = r1 | r0; /* add them all together */ -#ifdef ANOMALY_05000265 - BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */ -#endif p0.h = hi(PLL_CTL); p0.l = lo(PLL_CTL); /* Load the address */ @@ -120,7 +123,7 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; - /* disable self refresh by clearing SRREQ */ +#if defined(CONFIG_BF54x) P2.H = hi(EBIU_RSTCTL); P2.L = lo(EBIU_RSTCTL); R0 = [P2]; @@ -152,6 +155,41 @@ ENTRY(_start_dma_code) r0.h = hi(mem_DDRCTL2); [p0] = r0; ssync; +#else + p0.l = lo(EBIU_SDRRC); + p0.h = hi(EBIU_SDRRC); + r0 = mem_SDRRC; + w[p0] = r0.l; + ssync; + + p0.l = LO(EBIU_SDBCTL); + p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ + r0 = mem_SDBCTL; + w[p0] = r0.l; + ssync; + + P2.H = hi(EBIU_SDGCTL); + P2.L = lo(EBIU_SDGCTL); + R0 = [P2]; + BITCLR (R0, 24); + p0.h = hi(EBIU_SDSTAT); + p0.l = lo(EBIU_SDSTAT); + r2.l = w[p0]; + cc = bittst(r2,3); + if !cc jump .Lskip; + NOP; + BITSET (R0, 23); +.Lskip: + [P2] = R0; + SSYNC; + + R0.L = lo(mem_SDGCTL); + R0.H = hi(mem_SDGCTL); + R1 = [p2]; + R1 = R1 | R0; + [P2] = R1; + SSYNC; +#endif RTS; ENDPROC(_start_dma_code) diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h index 816b09278f62..3ad59655881a 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h @@ -2,18 +2,18 @@ * File: include/asm-blackfin/mach-bf548/anomaly.h * Bugs: Enter bugs at http://blackfin.uclinux.org/ * - * Copyright (C) 2004-2008 Analog Devices Inc. + * Copyright (C) 2004-2007 Analog Devices Inc. * Licensed under the GPL-2 or later. */ /* This file shoule be up to date with: - * - Revision G, 08/07/2008; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List + * - Revision E, 11/28/2007; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List */ #ifndef _MACH_ANOMALY_H_ #define _MACH_ANOMALY_H_ -/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported */ +/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */ #define ANOMALY_05000074 (1) /* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */ #define ANOMALY_05000119 (1) @@ -36,14 +36,14 @@ /* TWI Slave Boot Mode Is Not Functional */ #define ANOMALY_05000324 (__SILICON_REVISION__ < 1) /* External FIFO Boot Mode Is Not Functional */ -#define ANOMALY_05000325 (__SILICON_REVISION__ < 2) +#define ANOMALY_05000325 (__SILICON_REVISION__ < 1) /* Data Lost When Core and DMA Accesses Are Made to the USB FIFO Simultaneously */ #define ANOMALY_05000327 (__SILICON_REVISION__ < 1) /* Incorrect Access of OTP_STATUS During otp_write() Function */ #define ANOMALY_05000328 (__SILICON_REVISION__ < 1) /* Synchronous Burst Flash Boot Mode Is Not Functional */ #define ANOMALY_05000329 (__SILICON_REVISION__ < 1) -/* Host DMA Boot Modes Are Not Functional */ +/* Host DMA Boot Mode Is Not Functional */ #define ANOMALY_05000330 (__SILICON_REVISION__ < 1) /* Inadequate Timing Margins on DDR DQS to DQ and DQM Skew */ #define ANOMALY_05000334 (__SILICON_REVISION__ < 1) @@ -61,102 +61,26 @@ #define ANOMALY_05000344 (__SILICON_REVISION__ < 1) /* USB Calibration Value Is Not Intialized */ #define ANOMALY_05000346 (__SILICON_REVISION__ < 1) -/* USB Calibration Value to use */ -#define ANOMALY_05000346_value 0x5411 -/* Preboot Routine Incorrectly Alters Reset Value of USB Register */ +/* Boot ROM Kernel Incorrectly Alters Reset Value of USB Register */ #define ANOMALY_05000347 (__SILICON_REVISION__ < 1) /* Data Lost when Core Reads SDH Data FIFO */ #define ANOMALY_05000349 (__SILICON_REVISION__ < 1) /* PLL Status Register Is Inaccurate */ #define ANOMALY_05000351 (__SILICON_REVISION__ < 1) -/* bfrom_SysControl() Firmware Function Performs Improper System Reset */ -#define ANOMALY_05000353 (__SILICON_REVISION__ < 2) -/* Regulator Programming Blocked when Hibernate Wakeup Source Remains Active */ -#define ANOMALY_05000355 (__SILICON_REVISION__ < 1) -/* System Stalled During A Core Access To AMC While A Core Access To NFC FIFO Is Required */ -#define ANOMALY_05000356 (__SILICON_REVISION__ < 1) /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ #define ANOMALY_05000357 (1) /* External Memory Read Access Hangs Core With PLL Bypass */ #define ANOMALY_05000360 (1) /* DMAs that Go Urgent during Tight Core Writes to External Memory Are Blocked */ #define ANOMALY_05000365 (1) -/* WURESET Bit In SYSCR Register Does Not Properly Indicate Hibernate Wake-Up */ -#define ANOMALY_05000367 (__SILICON_REVISION__ < 1) /* Addressing Conflict between Boot ROM and Asynchronous Memory */ #define ANOMALY_05000369 (1) -/* Default PLL MSEL and SSEL Settings Can Cause 400MHz Product To Violate Specifications */ -#define ANOMALY_05000370 (__SILICON_REVISION__ < 1) /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ -#define ANOMALY_05000371 (__SILICON_REVISION__ < 2) -/* USB DP/DM Data Pins May Lose State When Entering Hibernate */ -#define ANOMALY_05000372 (__SILICON_REVISION__ < 1) +#define ANOMALY_05000371 (1) /* Mobile DDR Operation Not Functional */ #define ANOMALY_05000377 (1) /* Security/Authentication Speedpath Causes Authentication To Fail To Initiate */ -#define ANOMALY_05000378 (__SILICON_REVISION__ < 2) -/* 16-Bit NAND FLASH Boot Mode Is Not Functional */ -#define ANOMALY_05000379 (1) -/* 8-Bit NAND Flash Boot Mode Not Functional */ -#define ANOMALY_05000382 (__SILICON_REVISION__ < 1) -/* Some ATAPI Modes Are Not Functional */ -#define ANOMALY_05000383 (1) -/* Boot from OTP Memory Not Functional */ -#define ANOMALY_05000385 (__SILICON_REVISION__ < 1) -/* bfrom_SysControl() Firmware Routine Not Functional */ -#define ANOMALY_05000386 (__SILICON_REVISION__ < 1) -/* Programmable Preboot Settings Not Functional */ -#define ANOMALY_05000387 (__SILICON_REVISION__ < 1) -/* CRC32 Checksum Support Not Functional */ -#define ANOMALY_05000388 (__SILICON_REVISION__ < 1) -/* Reset Vector Must Not Be in SDRAM Memory Space */ -#define ANOMALY_05000389 (__SILICON_REVISION__ < 1) -/* Changed Meaning of BCODE Field in SYSCR Register */ -#define ANOMALY_05000390 (__SILICON_REVISION__ < 1) -/* Repeated Boot from Page-Mode or Burst-Mode Flash Memory May Fail */ -#define ANOMALY_05000391 (__SILICON_REVISION__ < 1) -/* pTempCurrent Not Present in ADI_BOOT_DATA Structure */ -#define ANOMALY_05000392 (__SILICON_REVISION__ < 1) -/* Deprecated Value of dTempByteCount in ADI_BOOT_DATA Structure */ -#define ANOMALY_05000393 (__SILICON_REVISION__ < 1) -/* Log Buffer Not Functional */ -#define ANOMALY_05000394 (__SILICON_REVISION__ < 1) -/* Hook Routine Not Functional */ -#define ANOMALY_05000395 (__SILICON_REVISION__ < 1) -/* Header Indirect Bit Not Functional */ -#define ANOMALY_05000396 (__SILICON_REVISION__ < 1) -/* BK_ONES, BK_ZEROS, and BK_DATECODE Constants Not Functional */ -#define ANOMALY_05000397 (__SILICON_REVISION__ < 1) -/* Lockbox SESR Disallows Certain User Interrupts */ -#define ANOMALY_05000404 (__SILICON_REVISION__ < 2) -/* Lockbox SESR Firmware Does Not Save/Restore Full Context */ -#define ANOMALY_05000405 (1) -/* Lockbox SESR Argument Checking Does Not Check L2 Memory Protection Range */ -#define ANOMALY_05000406 (__SILICON_REVISION__ < 2) -/* Lockbox SESR Firmware Arguments Are Not Retained After First Initialization */ -#define ANOMALY_05000407 (__SILICON_REVISION__ < 2) -/* Lockbox Firmware Memory Cleanup Routine Does not Clear Registers */ -#define ANOMALY_05000408 (1) -/* Lockbox firmware leaves MDMA0 channel enabled */ -#define ANOMALY_05000409 (__SILICON_REVISION__ < 2) -/* bfrom_SysControl() Firmware Function Cannot be Used to Enter Power Saving Modes */ -#define ANOMALY_05000411 (__SILICON_REVISION__ < 2) -/* NAND Boot Mode Not Compatible With Some NAND Flash Devices */ -#define ANOMALY_05000413 (__SILICON_REVISION__ < 2) -/* OTP_CHECK_FOR_PREV_WRITE Bit is Not Functional in bfrom_OtpWrite() API */ -#define ANOMALY_05000414 (__SILICON_REVISION__ < 2) -/* Speculative Fetches Can Cause Undesired External FIFO Operations */ -#define ANOMALY_05000416 (1) -/* Multichannel SPORT Channel Misalignment Under Specific Configuration */ -#define ANOMALY_05000425 (1) -/* Speculative Fetches of Indirect-Pointer Instructions Can Cause Spurious Hardware Errors */ -#define ANOMALY_05000426 (1) -/* CORE_EPPI_PRIO bit and SYS_EPPI_PRIO bit in the HMDMA1_CONTROL register are not functional */ -#define ANOMALY_05000427 (__SILICON_REVISION__ < 2) -/* WB_EDGE Bit in NFC_IRQSTAT Incorrectly Behaves as a Buffer Status Bit Instead of an IRQ Status Bit */ -#define ANOMALY_05000429 (__SILICON_REVISION__ < 2) -/* Software System Reset Corrupts PLL_LOCKCNT Register */ -#define ANOMALY_05000430 (__SILICON_REVISION__ >= 2) +#define ANOMALY_05000378 (1) /* Anomalies that don't exist on this proc */ #define ANOMALY_05000125 (0) @@ -169,7 +93,6 @@ #define ANOMALY_05000263 (0) #define ANOMALY_05000266 (0) #define ANOMALY_05000273 (0) -#define ANOMALY_05000307 (0) #define ANOMALY_05000311 (0) #define ANOMALY_05000323 (0) #define ANOMALY_05000363 (0) diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h b/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h index 49f9b403d458..e748588e8930 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/bf548.h @@ -30,6 +30,8 @@ #ifndef __MACH_BF548_H__ #define __MACH_BF548_H__ +#define SUPPORTED_REVID 0 + #define OFFSET_(x) ((x) & 0x0000FFFF) /*some misc defines*/ @@ -106,23 +108,20 @@ #if defined(CONFIG_BF542) # define CPU "BF542" -# define CPUID 0x27de +# define CPUID 0x027c8000 #elif defined(CONFIG_BF544) -# define CPU "BF544" -# define CPUID 0x27de +# define CPU "BF544" +# define CPUID 0x027c8000 #elif defined(CONFIG_BF547) -# define CPU "BF547" -# define CPUID 0x27de +# define CPU "BF547" #elif defined(CONFIG_BF548) -# define CPU "BF548" -# define CPUID 0x27de +# define CPU "BF548" +# define CPUID 0x027c6000 #elif defined(CONFIG_BF549) -# define CPU "BF549" -# define CPUID 0x27de -#endif - -#ifndef CPU -#error Unknown CPU type - This kernel doesn't seem to be configured properly +# define CPU "BF549" +#else +# define CPU "UNKNOWN" +# define CPUID 0x0 #endif #endif /* __MACH_BF48_H__ */ diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/trunk/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h index e4cf35e7ab9f..5e29446a8e03 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h @@ -82,9 +82,6 @@ # define CONFIG_UART1_RTS_PIN -1 # endif #endif - -#define BFIN_UART_TX_FIFO_SIZE 2 - /* * The pin configuration is different from schematic */ @@ -108,6 +105,7 @@ struct bfin_serial_port { #endif }; +struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; @@ -172,6 +170,8 @@ struct bfin_serial_res bfin_serial_resource[] = { #endif }; +int nr_ports = ARRAY_SIZE(bfin_serial_resource); + #define DRIVER_NAME "bfin-uart" static void bfin_serial_hw_init(struct bfin_serial_port *uart) diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/mem_map.h b/trunk/arch/blackfin/mach-bf548/include/mach/mem_map.h index a2228428dc06..f99f47bc3a07 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/mem_map.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/mem_map.h @@ -94,13 +94,13 @@ #endif /*CONFIG_BFIN_DCACHE*/ /* Level 2 Memory */ -#define L2_START 0xFEB00000 -#if defined(CONFIG_BF542) -# define L2_LENGTH 0 -#elif defined(CONFIG_BF544) -# define L2_LENGTH 0x10000 -#else -# define L2_LENGTH 0x20000 +#if !defined(CONFIG_BF542) +# define L2_START 0xFEB00000 +# if defined(CONFIG_BF544) +# define L2_LENGTH 0x10000 +# else +# define L2_LENGTH 0x20000 +# endif #endif /* Scratch Pad Memory */ diff --git a/trunk/arch/blackfin/mach-bf561/head.S b/trunk/arch/blackfin/mach-bf561/head.S index 31a777a9e699..75ea6a905829 100644 --- a/trunk/arch/blackfin/mach-bf561/head.S +++ b/trunk/arch/blackfin/mach-bf561/head.S @@ -77,9 +77,6 @@ ENTRY(_start_dma_code) r1 = PLL_BYPASS; /* Bypass the PLL? */ r1 = r1 << 8; /* Shift it over */ r0 = r1 | r0; /* add them all together */ -#ifdef ANOMALY_05000265 - BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */ -#endif p0.h = hi(PLL_CTL); p0.l = lo(PLL_CTL); /* Load the address */ diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h index 22990df04ae1..5c5d7d7d695f 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h @@ -270,7 +270,5 @@ #define ANOMALY_05000183 (0) #define ANOMALY_05000273 (0) #define ANOMALY_05000311 (0) -#define ANOMALY_05000353 (1) -#define ANOMALY_05000386 (1) #endif diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/bf561.h b/trunk/arch/blackfin/mach-bf561/include/mach/bf561.h index 18b1b3a223ab..3ef9e5f36136 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/bf561.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/bf561.h @@ -30,6 +30,8 @@ #ifndef __MACH_BF561_H__ #define __MACH_BF561_H__ +#define SUPPORTED_REVID 0x3 + #define OFFSET_(x) ((x) & 0x0000FFFF) /*some misc defines*/ @@ -211,11 +213,11 @@ #ifdef CONFIG_BF561 #define CPU "BF561" -#define CPUID 0x27bb +#define CPUID 0x027bb000 #endif - #ifndef CPU -#error Unknown CPU type - This kernel doesn't seem to be configured properly +#define CPU "UNKNOWN" +#define CPUID 0x0 #endif #endif /* __MACH_BF561_H__ */ diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/trunk/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h index 043bfcf26c52..8aa02780e642 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h @@ -69,8 +69,6 @@ # endif #endif -#define BFIN_UART_TX_FIFO_SIZE 2 - struct bfin_serial_port { struct uart_port port; unsigned int old_status; @@ -85,7 +83,7 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else -# if ANOMALY_05000363 +# if ANOMALY_05000230 unsigned int anomaly_threshold; # endif #endif @@ -113,6 +111,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) bfin_write16(uart->port.membase + OFFSET_LSR, -1); } +struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; int uart_irq; @@ -143,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = { #define DRIVER_NAME "bfin-uart" +int nr_ports = BFIN_UART_NR_PORTS; static void bfin_serial_hw_init(struct bfin_serial_port *uart) { @@ -158,7 +158,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) } if (uart->rts_pin >= 0) { gpio_request(uart->rts_pin, DRIVER_NAME); - gpio_direction_output(uart->rts_pin, 0); + gpio_direction_input(uart->rts_pin, 0); } #endif } diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/mem_map.h b/trunk/arch/blackfin/mach-bf561/include/mach/mem_map.h index f1d4c0637bd2..c26d8486cc4b 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/mem_map.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/mem_map.h @@ -35,16 +35,9 @@ /* Memory Map for ADSP-BF561 processors */ #ifdef CONFIG_BF561 -#define COREA_L1_CODE_START 0xFFA00000 -#define COREA_L1_DATA_A_START 0xFF800000 -#define COREA_L1_DATA_B_START 0xFF900000 -#define COREB_L1_CODE_START 0xFF600000 -#define COREB_L1_DATA_A_START 0xFF400000 -#define COREB_L1_DATA_B_START 0xFF500000 - -#define L1_CODE_START COREA_L1_CODE_START -#define L1_DATA_A_START COREA_L1_DATA_A_START -#define L1_DATA_B_START COREA_L1_DATA_B_START +#define L1_CODE_START 0xFFA00000 +#define L1_DATA_A_START 0xFF800000 +#define L1_DATA_B_START 0xFF900000 #define L1_CODE_LENGTH 0x4000 @@ -79,10 +72,7 @@ /* Scratch Pad Memory */ -#define COREA_L1_SCRATCH_START 0xFFB00000 -#define COREB_L1_SCRATCH_START 0xFF700000 - -#define L1_SCRATCH_START COREA_L1_SCRATCH_START +#define L1_SCRATCH_START 0xFFB00000 #define L1_SCRATCH_LENGTH 0x1000 #endif /* _MEM_MAP_533_H_ */ diff --git a/trunk/arch/blackfin/mach-common/cache.S b/trunk/arch/blackfin/mach-common/cache.S index db532181fbde..85f8c79b3c37 100644 --- a/trunk/arch/blackfin/mach-common/cache.S +++ b/trunk/arch/blackfin/mach-common/cache.S @@ -1,91 +1,148 @@ /* - * Blackfin cache control code + * File: arch/blackfin/mach-common/cache.S + * Based on: + * Author: LG Soft India * - * Copyright 2004-2008 Analog Devices Inc. + * Created: + * Description: cache control support * - * Enter bugs at http://blackfin.uclinux.org/ + * Modified: + * Copyright 2004-2006 Analog Devices Inc. * - * Licensed under the GPL-2 or later. + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * 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, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include +#include +#include #include #include -#include .text -/* Since all L1 caches work the same way, we use the same method for flushing - * them. Only the actual flush instruction differs. We write this in asm as - * GCC can be hard to coax into writing nice hardware loops. +/* + * blackfin_cache_flush_range(start, end) + * Invalidate all cache lines assocoiated with this + * area of memory. * - * Also, we assume the following register setup: - * R0 = start address - * R1 = end address + * start: Start address + * end: End address */ -.macro do_flush flushins:req optflushins optnopins label - - /* end = ((end - 1) & -L1_CACHE_BYTES) + L1_CACHE_BYTES; */ - R1 += -1; +ENTRY(_blackfin_icache_flush_range) R2 = -L1_CACHE_BYTES; - R1 = R1 & R2; - R1 += L1_CACHE_BYTES; - - /* count = (end - start) >> L1_CACHE_SHIFT */ - R2 = R1 - R0; - R2 >>= L1_CACHE_SHIFT; - P1 = R2; - -.ifnb \label -\label : -.endif - P0 = R0; - LSETUP (1f, 2f) LC1 = P1; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC(R3); + IFLUSH [P0]; 1: -.ifnb \optflushins - \optflushins [P0]; -.endif -.ifb \optnopins -2: -.endif - \flushins [P0++]; -.ifnb \optnopins -2: \optnopins; -.endif - + IFLUSH [P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + IFLUSH [P0]; + SSYNC(R3); RTS; -.endm - -/* Invalidate all instruction cache lines assocoiated with this memory area */ -ENTRY(_blackfin_icache_flush_range) - do_flush IFLUSH, , nop ENDPROC(_blackfin_icache_flush_range) -/* Flush all cache lines assocoiated with this area of memory. */ +/* + * blackfin_icache_dcache_flush_range(start, end) + * FLUSH all cache lines assocoiated with this + * area of memory. + * + * start: Start address + * end: End address + */ + ENTRY(_blackfin_icache_dcache_flush_range) - do_flush IFLUSH, FLUSH + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC(R3); + IFLUSH [P0]; +1: + FLUSH [P0]; + IFLUSH [P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + IFLUSH [P0]; + FLUSH [P0]; + SSYNC(R3); + RTS; ENDPROC(_blackfin_icache_dcache_flush_range) /* Throw away all D-cached data in specified region without any obligation to - * write them back. Since the Blackfin ISA does not have an "invalidate" - * instruction, we use flush/invalidate. Perhaps as a speed optimization we - * could bang on the DTEST MMRs ... + * write them back. However, we must clean the D-cached entries around the + * boundaries of the start and/or end address is not cache aligned. + * + * Start: start address, + * end : end address. */ + ENTRY(_blackfin_dcache_invalidate_range) - do_flush FLUSHINV + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC(R3); + FLUSHINV[P0]; +1: + FLUSHINV[P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + + /* If the data crosses a cache line, then we'll be pointing to + * the last cache line, but won't have flushed/invalidated it yet, + * so do one more. + */ + FLUSHINV[P0]; + SSYNC(R3); + RTS; ENDPROC(_blackfin_dcache_invalidate_range) -/* Flush all data cache lines assocoiated with this memory area */ ENTRY(_blackfin_dcache_flush_range) - do_flush FLUSH, , , .Ldfr + R2 = -L1_CACHE_BYTES; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC(R3); + FLUSH[P0]; +1: + FLUSH[P0++]; + CC = P0 < P1 (iu); + IF CC JUMP 1b (bp); + + /* If the data crosses a cache line, then we'll be pointing to + * the last cache line, but won't have flushed it yet, so do + * one more. + */ + FLUSH[P0]; + SSYNC(R3); + RTS; ENDPROC(_blackfin_dcache_flush_range) -/* Our headers convert the page structure to an address, so just need to flush - * its contents like normal. We know the start address is page aligned (which - * greater than our cache alignment), as is the end address. So just jump into - * the middle of the dcache flush function. - */ ENTRY(_blackfin_dflush_page) P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT); - jump .Ldfr; + P0 = R0; + CSYNC(R3); + FLUSH[P0]; + LSETUP (.Lfl1, .Lfl1) LC0 = P1; +.Lfl1: FLUSH [P0++]; + SSYNC(R3); + RTS; ENDPROC(_blackfin_dflush_page) diff --git a/trunk/arch/blackfin/mach-common/cpufreq.c b/trunk/arch/blackfin/mach-common/cpufreq.c index c22c47b60127..75cdad291e88 100644 --- a/trunk/arch/blackfin/mach-common/cpufreq.c +++ b/trunk/arch/blackfin/mach-common/cpufreq.c @@ -158,6 +158,8 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy) dpm_state_table[index].tscale); } + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.transition_latency = (bfin_read_PLL_LOCKCNT() / (sclk / 1000000)) * 1000; /*Now ,only support one cpu */ policy->cur = cclk; diff --git a/trunk/arch/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S index c13fa8da28c7..847c172a99eb 100644 --- a/trunk/arch/blackfin/mach-common/entry.S +++ b/trunk/arch/blackfin/mach-common/entry.S @@ -129,18 +129,6 @@ ENTRY(_ex_icplb_miss) #else call __cplb_hdr; #endif - -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* While we were processing this, did we double fault? */ - r7 = SEQSTAT; /* reason code is in bit 5:0 */ - r6.l = lo(SEQSTAT_EXCAUSE); - r6.h = hi(SEQSTAT_EXCAUSE); - r7 = r7 & r6; - r6 = 0x25; - CC = R7 == R6; - if CC JUMP _double_fault; -#endif - DEBUG_HWTRACE_RESTORE(p5, r7) RESTORE_ALL_SYS SP = EX_SCRATCH_REG; @@ -148,8 +136,11 @@ ENTRY(_ex_icplb_miss) ENDPROC(_ex_icplb_miss) ENTRY(_ex_syscall) + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; raise 15; /* invoked by TRAP #0, for sys call */ - jump.s _bfin_return_from_exception; + sp = EX_SCRATCH_REG; + rtx ENDPROC(_ex_syscall) ENTRY(_ex_soft_bp) @@ -190,8 +181,8 @@ ENTRY(_ex_single_step) if cc jump .Lfind_priority_done; jump.s .Lfind_priority_start; .Lfind_priority_done: - p4.l = _kgdb_single_step; - p4.h = _kgdb_single_step; + p4.l = _debugger_step; + p4.h = _debugger_step; r6 = [p4]; cc = r6 == 0; if cc jump .Ldo_single_step; @@ -259,29 +250,6 @@ ENTRY(_bfin_return_from_exception) R7=LC1; LC1=R7; #endif - -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* While we were processing the current exception, - * did we cause another, and double fault? - */ - r7 = SEQSTAT; /* reason code is in bit 5:0 */ - r6.l = lo(SEQSTAT_EXCAUSE); - r6.h = hi(SEQSTAT_EXCAUSE); - r7 = r7 & r6; - r6 = 0x25; - CC = R7 == R6; - if CC JUMP _double_fault; - - /* Did we cause a HW error? */ - p5.l = lo(ILAT); - p5.h = hi(ILAT); - r6 = [p5]; - r7 = 0x20; /* Did I just cause anther HW error? */ - r7 = r7 & r1; - CC = R7 == R6; - if CC JUMP _double_fault; -#endif - (R7:6,P5:4) = [sp++]; ASTAT = [sp++]; sp = EX_SCRATCH_REG; @@ -324,14 +292,6 @@ ENTRY(_ex_trap_c) [p4] = p5; csync; -#ifndef CONFIG_DEBUG_DOUBLEFAULT - /* - * Save these registers, as they are only valid in exception context - * (where we are now - as soon as we defer to IRQ5, they can change) - * DCPLB_STATUS and ICPLB_STATUS are also only valid in EVT3, - * but they are not very interesting, so don't save them - */ - p4.l = lo(DCPLB_FAULT_ADDR); p4.h = hi(DCPLB_FAULT_ADDR); r7 = [p4]; @@ -344,11 +304,12 @@ ENTRY(_ex_trap_c) p5.l = _saved_icplb_fault_addr; [p5] = r7; + p4.l = _excpt_saved_stuff; + p4.h = _excpt_saved_stuff; + r6 = retx; - p4.l = _saved_retx; - p4.h = _saved_retx; [p4] = r6; -#endif + r6 = SYSCFG; [p4 + 4] = r6; BITCLR(r6, 0); @@ -366,56 +327,59 @@ ENTRY(_ex_trap_c) r6 = 0x3f; sti r6; + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; + SP = EX_SCRATCH_REG; raise 5; - jump.s _bfin_return_from_exception; + rtx; ENDPROC(_ex_trap_c) /* We just realized we got an exception, while we were processing a different * exception. This is a unrecoverable event, so crash */ ENTRY(_double_fault) - /* Turn caches & protection off, to ensure we don't get any more - * double exceptions - */ - - P4.L = LO(IMEM_CONTROL); - P4.H = HI(IMEM_CONTROL); - - R5 = [P4]; /* Control Register*/ - BITCLR(R5,ENICPLB_P); - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P4] = R5; - SSYNC; - - P4.L = LO(DMEM_CONTROL); - P4.H = HI(DMEM_CONTROL); - R5 = [P4]; - BITCLR(R5,ENDCPLB_P); - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P4] = R5; - SSYNC; - - /* Fix up the stack */ - (R7:6,P5:4) = [sp++]; - ASTAT = [sp++]; - SP = EX_SCRATCH_REG; - - /* We should be out of the exception stack, and back down into - * kernel or user space stack - */ - SAVE_ALL_SYS + /* Turn caches & protection off, to ensure we don't get any more + * double exceptions + */ + + P4.L = LO(IMEM_CONTROL); + P4.H = HI(IMEM_CONTROL); + + R5 = [P4]; /* Control Register*/ + BITCLR(R5,ENICPLB_P); + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + + P4.L = LO(DMEM_CONTROL); + P4.H = HI(DMEM_CONTROL); + R5 = [P4]; + BITCLR(R5,ENDCPLB_P); + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + + /* Fix up the stack */ + (R7:6,P5:4) = [sp++]; + ASTAT = [sp++]; + SP = EX_SCRATCH_REG; + + /* We should be out of the exception stack, and back down into + * kernel or user space stack + */ + SAVE_ALL_SYS /* The dumping functions expect the return address in the RETI * slot. */ r6 = retx; [sp + PT_PC] = r6; - r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ - SP += -12; - call _double_fault_c; - SP += 12; + r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ + SP += -12; + call _double_fault_c; + SP += 12; .L_double_fault_panic: JUMP .L_double_fault_panic @@ -424,8 +388,8 @@ ENDPROC(_double_fault) ENTRY(_exception_to_level5) SAVE_ALL_SYS - p4.l = _saved_retx; - p4.h = _saved_retx; + p4.l = _excpt_saved_stuff; + p4.h = _excpt_saved_stuff; r6 = [p4]; [sp + PT_PC] = r6; @@ -456,17 +420,6 @@ ENTRY(_exception_to_level5) call _trap_c; SP += 12; -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* Grab ILAT */ - p2.l = lo(ILAT); - p2.h = hi(ILAT); - r0 = [p2]; - r1 = 0x20; /* Did I just cause anther HW error? */ - r0 = r0 & r1; - CC = R0 == R1; - if CC JUMP _double_fault; -#endif - call _ret_from_exception; RESTORE_ALL_SYS rti; @@ -483,48 +436,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ /* Try to deal with syscalls quickly. */ [--sp] = ASTAT; [--sp] = (R7:6,P5:4); - -#if ANOMALY_05000283 || ANOMALY_05000315 - cc = r7 == r7; - p5.h = HI(CHIPID); - p5.l = LO(CHIPID); - if cc jump 1f; - r7.l = W[p5]; -1: -#endif - -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* - * Save these registers, as they are only valid in exception context - * (where we are now - as soon as we defer to IRQ5, they can change) - * DCPLB_STATUS and ICPLB_STATUS are also only valid in EVT3, - * but they are not very interesting, so don't save them - */ - - p4.l = lo(DCPLB_FAULT_ADDR); - p4.h = hi(DCPLB_FAULT_ADDR); - r7 = [p4]; - p5.h = _saved_dcplb_fault_addr; - p5.l = _saved_dcplb_fault_addr; - [p5] = r7; - - r7 = [p4 + (ICPLB_FAULT_ADDR - DCPLB_FAULT_ADDR)]; - p5.h = _saved_icplb_fault_addr; - p5.l = _saved_icplb_fault_addr; - [p5] = r7; - - p4.l = _saved_retx; - p4.h = _saved_retx; - r6 = retx; - [p4] = r6; - r7 = SEQSTAT; /* reason code is in bit 5:0 */ - p4.l = _saved_seqstat; - p4.h = _saved_seqstat; - [p4] = r7; -#else - r7 = SEQSTAT; /* reason code is in bit 5:0 */ -#endif r6.l = lo(SEQSTAT_EXCAUSE); r6.h = hi(SEQSTAT_EXCAUSE); r7 = r7 & r6; @@ -704,9 +616,6 @@ ENTRY(_system_call) rts; ENDPROC(_system_call) -/* Do not mark as ENTRY() to avoid error in assembler ... - * this symbol need not be global anyways, so ... - */ _sys_trace: call _syscall_trace; @@ -1032,15 +941,6 @@ ENTRY(_early_trap) SAVE_ALL_SYS trace_buffer_stop(p0,r0); -#if ANOMALY_05000283 || ANOMALY_05000315 - cc = r5 == r5; - p4.h = HI(CHIPID); - p4.l = LO(CHIPID); - if cc jump 1f; - r5.l = W[p4]; -1: -#endif - /* Turn caches off, to ensure we don't get double exceptions */ P4.L = LO(IMEM_CONTROL); @@ -1092,12 +992,7 @@ ENTRY(_ex_table) */ .long _ex_syscall /* 0x00 - User Defined - Linux Syscall */ .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ -#ifdef CONFIG_KGDB - .long _ex_trap_c /* 0x02 - User Defined - KGDB initial connection - and break signal trap */ -#else .long _ex_replaceable /* 0x02 - User Defined */ -#endif .long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */ .long _ex_trap_c /* 0x04 - User Defined - dump trace buffer */ .long _ex_replaceable /* 0x05 - User Defined */ @@ -1537,7 +1432,15 @@ ENTRY(_sys_call_table) .rept NR_syscalls-(.-_sys_call_table)/4 .long _sys_ni_syscall .endr -END(_sys_call_table) + + /* + * Used to save the real RETX, IMASK and SYSCFG when temporarily + * storing safe values across the transition from exception to IRQ5. + */ +_excpt_saved_stuff: + .long 0; + .long 0; + .long 0; _exception_stack: .rept 1024 diff --git a/trunk/arch/blackfin/mach-common/head.S b/trunk/arch/blackfin/mach-common/head.S index f123a62e2451..191b4e974c4b 100644 --- a/trunk/arch/blackfin/mach-common/head.S +++ b/trunk/arch/blackfin/mach-common/head.S @@ -68,16 +68,6 @@ ENTRY(__start) M2 = r0; M3 = r0; - /* - * Clear ITEST_COMMAND and DTEST_COMMAND registers, - * Leaving these as non-zero can confuse the emulator - */ - p0.L = LO(DTEST_COMMAND); - p0.H = HI(DTEST_COMMAND); - [p0] = R0; - [p0 + (ITEST_COMMAND - DTEST_COMMAND)] = R0; - CSYNC; - trace_buffer_init(p0,r0); P0 = R1; R0 = R1; @@ -100,46 +90,12 @@ ENTRY(__start) [p0] = R0; SSYNC; - /* in case of double faults, save a few things */ - p0.l = _init_retx; - p0.h = _init_retx; + /* Save RETX, in case of doublefault */ + p0.l = ___retx; + p0.h = ___retx; R0 = RETX; [P0] = R0; -#ifdef CONFIG_DEBUG_DOUBLEFAULT - /* Only save these if we are storing them, - * This happens here, since L1 gets clobbered - * below - */ - p0.l = _saved_retx; - p0.h = _saved_retx; - p1.l = _init_saved_retx; - p1.h = _init_saved_retx; - r0 = [p0]; - [p1] = r0; - - p0.l = _saved_dcplb_fault_addr; - p0.h = _saved_dcplb_fault_addr; - p1.l = _init_saved_dcplb_fault_addr; - p1.h = _init_saved_dcplb_fault_addr; - r0 = [p0]; - [p1] = r0; - - p0.l = _saved_icplb_fault_addr; - p0.h = _saved_icplb_fault_addr; - p1.l = _init_saved_icplb_fault_addr; - p1.h = _init_saved_icplb_fault_addr; - r0 = [p0]; - [p1] = r0; - - p0.l = _saved_seqstat; - p0.h = _saved_seqstat; - p1.l = _init_saved_seqstat; - p1.h = _init_saved_seqstat; - r0 = [p0]; - [p1] = r0; -#endif - /* Initialize stack pointer */ sp.l = lo(INITIAL_STACK); sp.h = hi(INITIAL_STACK); @@ -151,7 +107,7 @@ ENTRY(__start) #endif /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ - call _bfin_relocate_l1_mem; + call _bf53x_relocate_l1_mem; #ifdef CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -206,60 +162,6 @@ ENTRY(_real_start) w[p0] = r0; ssync; -#if L1_DATA_A_LENGTH > 0 - r1.l = __sbss_l1; - r1.h = __sbss_l1; - r2.l = __ebss_l1; - r2.h = __ebss_l1; - r0 = 0 (z); - r2 = r2 - r1; - cc = r2 == 0; - if cc jump .L_a_l1_done; - r2 >>= 2; - p1 = r1; - p2 = r2; - lsetup (.L_clear_a_l1, .L_clear_a_l1 ) lc0 = p2; -.L_clear_a_l1: - [p1++] = r0; -.L_a_l1_done: -#endif - -#if L1_DATA_B_LENGTH > 0 - r1.l = __sbss_b_l1; - r1.h = __sbss_b_l1; - r2.l = __ebss_b_l1; - r2.h = __ebss_b_l1; - r0 = 0 (z); - r2 = r2 - r1; - cc = r2 == 0; - if cc jump .L_b_l1_done; - r2 >>= 2; - p1 = r1; - p2 = r2; - lsetup (.L_clear_b_l1, .L_clear_b_l1 ) lc0 = p2; -.L_clear_b_l1: - [p1++] = r0; -.L_b_l1_done: -#endif - -#if L2_LENGTH > 0 - r1.l = __sbss_l2; - r1.h = __sbss_l2; - r2.l = __ebss_l2; - r2.h = __ebss_l2; - r0 = 0 (z); - r2 = r2 - r1; - cc = r2 == 0; - if cc jump .L_l2_done; - r2 >>= 2; - p1 = r1; - p2 = r2; - lsetup (.L_clear_l2, .L_clear_l2 ) lc0 = p2; -.L_clear_l2: - [p1++] = r0; -.L_l2_done: -#endif - /* Zero out the bss region * Note: this will fail if bss is 0 bytes ... */ diff --git a/trunk/arch/blackfin/mach-common/interrupt.S b/trunk/arch/blackfin/mach-common/interrupt.S index 4a2ec7a9675a..b27e59d32401 100644 --- a/trunk/arch/blackfin/mach-common/interrupt.S +++ b/trunk/arch/blackfin/mach-common/interrupt.S @@ -143,7 +143,7 @@ ENTRY(_evt_ivhw) fp = 0; #endif -#if ANOMALY_05000283 || ANOMALY_05000315 +#if ANOMALY_05000283 cc = r7 == r7; p5.h = HI(CHIPID); p5.l = LO(CHIPID); @@ -179,16 +179,7 @@ ENTRY(_evt_ivhw) call _trap_c; SP += 12; -#ifdef EBIU_ERRMST - /* make sure EBIU_ERRMST is clear */ - p0.l = LO(EBIU_ERRMST); - p0.h = HI(EBIU_ERRMST); - r0.l = (CORE_ERROR | CORE_MERROR); - w[p0] = r0.l; -#endif - call _ret_from_exception; - .Lcommon_restore_all_sys: RESTORE_ALL_SYS rti; diff --git a/trunk/arch/blackfin/mach-common/ints-priority.c b/trunk/arch/blackfin/mach-common/ints-priority.c index 34e8a726ffda..5fa536727c61 100644 --- a/trunk/arch/blackfin/mach-common/ints-priority.c +++ b/trunk/arch/blackfin/mach-common/ints-priority.c @@ -243,14 +243,12 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) #endif static struct irq_chip bfin_core_irqchip = { - .name = "CORE", .ack = bfin_ack_noop, .mask = bfin_core_mask_irq, .unmask = bfin_core_unmask_irq, }; static struct irq_chip bfin_internal_irqchip = { - .name = "INTN", .ack = bfin_ack_noop, .mask = bfin_internal_mask_irq, .unmask = bfin_internal_unmask_irq, @@ -280,7 +278,6 @@ static void bfin_generic_error_unmask_irq(unsigned int irq) } static struct irq_chip bfin_generic_error_irqchip = { - .name = "ERROR", .ack = bfin_ack_noop, .mask_ack = bfin_generic_error_mask_irq, .mask = bfin_generic_error_mask_irq, @@ -364,14 +361,6 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, } #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ -static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) -{ - struct irq_desc *desc = irq_desc + irq; - /* May not call generic set_irq_handler() due to spinlock - recursion. */ - desc->handle_irq = handle; -} - #if !defined(CONFIG_BF54x) static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; @@ -484,9 +473,9 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) SSYNC(); if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - bfin_set_irq_handler(irq, handle_edge_irq); + set_irq_handler(irq, handle_edge_irq); else - bfin_set_irq_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); return 0; } @@ -506,7 +495,6 @@ int bfin_gpio_set_wake(unsigned int irq, unsigned int state) #endif static struct irq_chip bfin_gpio_irqchip = { - .name = "GPIO", .ack = bfin_gpio_ack_irq, .mask = bfin_gpio_mask_irq, .mask_ack = bfin_gpio_mask_ack_irq, @@ -816,10 +804,10 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { pint[bank]->edge_set = pintbit; - bfin_set_irq_handler(irq, handle_edge_irq); + set_irq_handler(irq, handle_edge_irq); } else { pint[bank]->edge_clear = pintbit; - bfin_set_irq_handler(irq, handle_level_irq); + set_irq_handler(irq, handle_level_irq); } SSYNC(); @@ -896,7 +884,6 @@ void bfin_pm_restore(void) #endif static struct irq_chip bfin_gpio_irqchip = { - .name = "GPIO", .ack = bfin_gpio_ack_irq, .mask = bfin_gpio_mask_irq, .mask_ack = bfin_gpio_mask_ack_irq, @@ -1149,4 +1136,8 @@ void do_irq(int vec, struct pt_regs *fp) vec = ivg->irqno; } asm_do_IRQ(vec, fp); + +#ifdef CONFIG_KGDB + kgdb_process_breakpoint(); +#endif } diff --git a/trunk/arch/blackfin/mm/Makefile b/trunk/arch/blackfin/mm/Makefile index d489f894f4b1..2a7202ce01fd 100644 --- a/trunk/arch/blackfin/mm/Makefile +++ b/trunk/arch/blackfin/mm/Makefile @@ -2,4 +2,4 @@ # arch/blackfin/mm/Makefile # -obj-y := sram-alloc.o isram-driver.o init.o +obj-y := blackfin_sram.o init.o diff --git a/trunk/arch/blackfin/mm/sram-alloc.c b/trunk/arch/blackfin/mm/blackfin_sram.c similarity index 96% rename from trunk/arch/blackfin/mm/sram-alloc.c rename to trunk/arch/blackfin/mm/blackfin_sram.c index 0f1ca6930c16..4f5e887a0d96 100644 --- a/trunk/arch/blackfin/mm/sram-alloc.c +++ b/trunk/arch/blackfin/mm/blackfin_sram.c @@ -1,13 +1,13 @@ /* - * File: arch/blackfin/mm/sram-alloc.c + * File: arch/blackfin/mm/blackfin_sram.c * Based on: * Author: * * Created: - * Description: SRAM allocator for Blackfin L1 and L2 memory + * Description: SRAM driver for Blackfin ADSP-BF5xx * * Modified: - * Copyright 2004-2008 Analog Devices Inc. + * Copyright 2004-2007 Analog Devices Inc. * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * @@ -78,7 +78,7 @@ static void __init l1sram_init(void) free_l1_ssram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_ssram_head.next) { - printk(KERN_INFO "Failed to initialize Scratchpad data SRAM\n"); + printk(KERN_INFO"Fail to initialize Scratchpad data SRAM.\n"); return; } @@ -102,7 +102,7 @@ static void __init l1_data_sram_init(void) free_l1_data_A_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_data_A_sram_head.next) { - printk(KERN_INFO "Failed to initialize L1 Data A SRAM\n"); + printk(KERN_INFO"Fail to initialize L1 Data A SRAM.\n"); return; } @@ -123,7 +123,7 @@ static void __init l1_data_sram_init(void) free_l1_data_B_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_data_B_sram_head.next) { - printk(KERN_INFO "Failed to initialize L1 Data B SRAM\n"); + printk(KERN_INFO"Fail to initialize L1 Data B SRAM.\n"); return; } @@ -151,7 +151,7 @@ static void __init l1_inst_sram_init(void) free_l1_inst_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_inst_sram_head.next) { - printk(KERN_INFO "Failed to initialize L1 Instruction SRAM\n"); + printk(KERN_INFO"Fail to initialize L1 Instruction SRAM.\n"); return; } @@ -179,7 +179,7 @@ static void __init l2_sram_init(void) free_l2_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l2_sram_head.next) { - printk(KERN_INFO "Failed to initialize L2 SRAM\n"); + printk(KERN_INFO"Fail to initialize L2 SRAM.\n"); return; } @@ -351,31 +351,28 @@ static int _sram_free(const void *addr, int sram_free(const void *addr) { - + if (0) {} #if L1_CODE_LENGTH != 0 - if (addr >= (void *)L1_CODE_START + else if (addr >= (void *)L1_CODE_START && addr < (void *)(L1_CODE_START + L1_CODE_LENGTH)) return l1_inst_sram_free(addr); - else #endif #if L1_DATA_A_LENGTH != 0 - if (addr >= (void *)L1_DATA_A_START + else if (addr >= (void *)L1_DATA_A_START && addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH)) return l1_data_A_sram_free(addr); - else #endif #if L1_DATA_B_LENGTH != 0 - if (addr >= (void *)L1_DATA_B_START + else if (addr >= (void *)L1_DATA_B_START && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) return l1_data_B_sram_free(addr); - else #endif #if L2_LENGTH != 0 - if (addr >= (void *)L2_START + else if (addr >= (void *)L2_START && addr < (void *)(L2_START + L2_LENGTH)) return l2_sram_free(addr); - else #endif + else return -1; } EXPORT_SYMBOL(sram_free); diff --git a/trunk/arch/blackfin/mm/isram-driver.c b/trunk/arch/blackfin/mm/isram-driver.c deleted file mode 100644 index 22913e7a1818..000000000000 --- a/trunk/arch/blackfin/mm/isram-driver.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Description: Instruction SRAM accessor functions for the Blackfin - * - * Copyright 2008 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include - -/* - * IMPORTANT WARNING ABOUT THESE FUNCTIONS - * - * The emulator will not function correctly if a write command is left in - * ITEST_COMMAND or DTEST_COMMAND AND access to cache memory is needed by - * the emulator. To avoid such problems, ensure that both ITEST_COMMAND - * and DTEST_COMMAND are zero when exiting these functions. - */ - - -/* - * On the Blackfin, L1 instruction sram (which operates at core speeds) can not - * be accessed by a normal core load, so we need to go through a few hoops to - * read/write it. - * To try to make it easier - we export a memcpy interface, where either src or - * dest can be in this special L1 memory area. - * The low level read/write functions should not be exposed to the rest of the - * kernel, since they operate on 64-bit data, and need specific address alignment - */ - -static DEFINE_SPINLOCK(dtest_lock); - -/* Takes a void pointer */ -#define IADDR2DTEST(x) \ - ({ unsigned long __addr = (unsigned long)(x); \ - (__addr & 0x47F8) | /* address bits 14 & 10:3 */ \ - (__addr & 0x0800) << 15 | /* address bit 11 */ \ - (__addr & 0x3000) << 4 | /* address bits 13:12 */ \ - (__addr & 0x8000) << 8 | /* address bit 15 */ \ - (0x1000004); /* isram access */ \ - }) - -/* Takes a pointer, and returns the offset (in bits) which things should be shifted */ -#define ADDR2OFFSET(x) ((((unsigned long)(x)) & 0x7) * 8) - -/* Takes a pointer, determines if it is the last byte in the isram 64-bit data type */ -#define ADDR2LAST(x) ((((unsigned long)x) & 0x7) == 0x7) - -static void isram_write(const void *addr, uint64_t data) -{ - uint32_t cmd; - unsigned long flags; - - if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH)) - return; - - cmd = IADDR2DTEST(addr) | 1; /* write */ - - /* - * Writes to DTEST_DATA[0:1] need to be atomic with write to DTEST_COMMAND - * While in exception context - atomicity is guaranteed or double fault - */ - spin_lock_irqsave(&dtest_lock, flags); - - bfin_write_DTEST_DATA0(data & 0xFFFFFFFF); - bfin_write_DTEST_DATA1(data >> 32); - - /* use the builtin, since interrupts are already turned off */ - __builtin_bfin_csync(); - bfin_write_DTEST_COMMAND(cmd); - __builtin_bfin_csync(); - - bfin_write_DTEST_COMMAND(0); - __builtin_bfin_csync(); - - spin_unlock_irqrestore(&dtest_lock, flags); -} - -static uint64_t isram_read(const void *addr) -{ - uint32_t cmd; - unsigned long flags; - uint64_t ret; - - if (addr > (void *)(L1_CODE_START + L1_CODE_LENGTH)) - return 0; - - cmd = IADDR2DTEST(addr) | 0; /* read */ - - /* - * Reads of DTEST_DATA[0:1] need to be atomic with write to DTEST_COMMAND - * While in exception context - atomicity is guaranteed or double fault - */ - spin_lock_irqsave(&dtest_lock, flags); - /* use the builtin, since interrupts are already turned off */ - __builtin_bfin_csync(); - bfin_write_DTEST_COMMAND(cmd); - __builtin_bfin_csync(); - ret = bfin_read_DTEST_DATA0() | ((uint64_t)bfin_read_DTEST_DATA1() << 32); - - bfin_write_DTEST_COMMAND(0); - __builtin_bfin_csync(); - spin_unlock_irqrestore(&dtest_lock, flags); - - return ret; -} - -static bool isram_check_addr(const void *addr, size_t n) -{ - if ((addr >= (void *)L1_CODE_START) && - (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) { - if ((addr + n) >= (void *)(L1_CODE_START + L1_CODE_LENGTH)) { - show_stack(NULL, NULL); - printk(KERN_ERR "isram_memcpy: copy involving %p length " - "(%zu) too long\n", addr, n); - } - return true; - } - return false; -} - -/* - * The isram_memcpy() function copies n bytes from memory area src to memory area dest. - * The isram_memcpy() function returns a pointer to dest. - * Either dest or src can be in L1 instruction sram. - */ -void *isram_memcpy(void *dest, const void *src, size_t n) -{ - uint64_t data_in = 0, data_out = 0; - size_t count; - bool dest_in_l1, src_in_l1, need_data, put_data; - unsigned char byte, *src_byte, *dest_byte; - - src_byte = (unsigned char *)src; - dest_byte = (unsigned char *)dest; - - dest_in_l1 = isram_check_addr(dest, n); - src_in_l1 = isram_check_addr(src, n); - - need_data = true; - put_data = true; - for (count = 0; count < n; count++) { - if (src_in_l1) { - if (need_data) { - data_in = isram_read(src + count); - need_data = false; - } - - if (ADDR2LAST(src + count)) - need_data = true; - - byte = (unsigned char)((data_in >> ADDR2OFFSET(src + count)) & 0xff); - - } else { - /* src is in L2 or L3 - so just dereference*/ - byte = src_byte[count]; - } - - if (dest_in_l1) { - if (put_data) { - data_out = isram_read(dest + count); - put_data = false; - } - - data_out &= ~((uint64_t)0xff << ADDR2OFFSET(dest + count)); - data_out |= ((uint64_t)byte << ADDR2OFFSET(dest + count)); - - if (ADDR2LAST(dest + count)) { - put_data = true; - isram_write(dest + count, data_out); - } - } else { - /* dest in L2 or L3 - so just dereference */ - dest_byte[count] = byte; - } - } - - /* make sure we dump the last byte if necessary */ - if (dest_in_l1 && !put_data) - isram_write(dest + count, data_out); - - return dest; -} -EXPORT_SYMBOL(isram_memcpy); - diff --git a/trunk/arch/cris/arch-v10/boot/tools/build.c b/trunk/arch/cris/arch-v10/boot/tools/build.c index c8adef364160..2f9bbb26d603 100644 --- a/trunk/arch/cris/arch-v10/boot/tools/build.c +++ b/trunk/arch/cris/arch-v10/boot/tools/build.c @@ -30,6 +30,7 @@ #include #include /* contains read/write */ #include +#include #include #define MINIX_HEADER 32 diff --git a/trunk/arch/cris/arch-v32/mach-a3/cpufreq.c b/trunk/arch/cris/arch-v32/mach-a3/cpufreq.c index ee391ecb5bc9..8e5a3cab8ad7 100644 --- a/trunk/arch/cris/arch-v32/mach-a3/cpufreq.c +++ b/trunk/arch/cris/arch-v32/mach-a3/cpufreq.c @@ -85,6 +85,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy) int result; /* cpuinfo and default policy values */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* 1ms */ policy->cur = cris_freq_get_cpu_frequency(0); diff --git a/trunk/arch/cris/arch-v32/mach-fs/cpufreq.c b/trunk/arch/cris/arch-v32/mach-fs/cpufreq.c index 58bd71e5bda9..d57631c0d8d1 100644 --- a/trunk/arch/cris/arch-v32/mach-fs/cpufreq.c +++ b/trunk/arch/cris/arch-v32/mach-fs/cpufreq.c @@ -81,6 +81,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy) int result; /* cpuinfo and default policy values */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* 1ms */ policy->cur = cris_freq_get_cpu_frequency(0); diff --git a/trunk/arch/frv/kernel/pm.c b/trunk/arch/frv/kernel/pm.c index be722fc1acff..d1113c5031f5 100644 --- a/trunk/arch/frv/kernel/pm.c +++ b/trunk/arch/frv/kernel/pm.c @@ -211,7 +211,7 @@ static int cmode_procctl(ctl_table *ctl, int write, struct file *filp, return try_set_cmode(new_cmode)?:*lenp; } -static int cmode_sysctl(ctl_table *table, +static int cmode_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -314,7 +314,7 @@ static int p0_procctl(ctl_table *ctl, int write, struct file *filp, return try_set_p0(new_p0)?:*lenp; } -static int p0_sysctl(ctl_table *table, +static int p0_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -358,7 +358,7 @@ static int cm_procctl(ctl_table *ctl, int write, struct file *filp, return try_set_cm(new_cm)?:*lenp; } -static int cm_sysctl(ctl_table *table, +static int cm_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c index 52ff9aec799d..64ee58d748be 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -111,7 +111,7 @@ EXPORT_SYMBOL(dma_free_coherent); * The 32-bit bus address to use is returned. * * Once the device is given the dma address, the device owns this memory - * until either dma_unmap_single or pci_dma_sync_single is performed. + * until either pci_unmap_single or pci_dma_sync_single is performed. */ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction direction) @@ -129,7 +129,7 @@ EXPORT_SYMBOL(dma_map_single); /* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the - * above dma_map_single interface. Here the scatter gather list + * above pci_map_single interface. Here the scatter gather list * elements are each tagged with the appropriate dma address * and length. They are obtained via sg_dma_{address,length}(SG). * @@ -139,7 +139,7 @@ EXPORT_SYMBOL(dma_map_single); * The routine returns the number of addr/length pairs actually * used, at most nents. * - * Device ownership issues as mentioned above for dma_map_single are + * Device ownership issues as mentioned above for pci_map_single are * the same here. */ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, @@ -158,20 +158,3 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, } EXPORT_SYMBOL(dma_map_sg); - -/* - * Map a single page of the indicated size for DMA in streaming mode. - * The 32-bit bus address to use is returned. - * - * Device ownership issues as mentioned above for dma_map_single are - * the same here. - */ -dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, - size_t size, enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); - flush_dcache_page(page); - return (dma_addr_t) page_to_phys(page) + offset; -} - -EXPORT_SYMBOL(dma_map_page); diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma.c b/trunk/arch/frv/mb93090-mb00/pci-dma.c index 3ddedebc4eb3..662f7b12d005 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma.c @@ -61,7 +61,7 @@ EXPORT_SYMBOL(dma_map_single); /* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the - * above dma_map_single interface. Here the scatter gather list + * above pci_map_single interface. Here the scatter gather list * elements are each tagged with the appropriate dma address * and length. They are obtained via sg_dma_{address,length}(SG). * @@ -71,7 +71,7 @@ EXPORT_SYMBOL(dma_map_single); * The routine returns the number of addr/length pairs actually * used, at most nents. * - * Device ownership issues as mentioned above for dma_map_single are + * Device ownership issues as mentioned above for pci_map_single are * the same here. */ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, @@ -105,13 +105,6 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, EXPORT_SYMBOL(dma_map_sg); -/* - * Map a single page of the indicated size for DMA in streaming mode. - * The 32-bit bus address to use is returned. - * - * Device ownership issues as mentioned above for dma_map_single are - * the same here. - */ dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction) { diff --git a/trunk/arch/frv/mb93090-mb00/pci-frv.c b/trunk/arch/frv/mb93090-mb00/pci-frv.c index 43d67534c712..edae117fcc2b 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-frv.c +++ b/trunk/arch/frv/mb93090-mb00/pci-frv.c @@ -201,6 +201,38 @@ void __init pcibios_resource_survey(void) pcibios_assign_resources(); } +int pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + /* * If we set up a device for bus mastering, we need to check the latency * timer as certain crappy BIOSes forget to set it properly. diff --git a/trunk/arch/frv/mb93090-mb00/pci-frv.h b/trunk/arch/frv/mb93090-mb00/pci-frv.h index f3fe55914793..0c7bf39dc729 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-frv.h +++ b/trunk/arch/frv/mb93090-mb00/pci-frv.h @@ -29,6 +29,7 @@ extern unsigned int __nongpreldata pci_probe; extern unsigned int pcibios_max_latency; void pcibios_resource_survey(void); +int pcibios_enable_resources(struct pci_dev *, int); /* pci-vdk.c */ diff --git a/trunk/arch/frv/mb93090-mb00/pci-vdk.c b/trunk/arch/frv/mb93090-mb00/pci-vdk.c index 0f41c3a72da5..f003cfa68b7a 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-vdk.c +++ b/trunk/arch/frv/mb93090-mb00/pci-vdk.c @@ -412,7 +412,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) { int err; - if ((err = pci_enable_resources(dev, mask)) < 0) + if ((err = pcibios_enable_resources(dev, mask)) < 0) return err; if (!dev->msi_enabled) pcibios_enable_irq(dev); diff --git a/trunk/arch/frv/mm/init.c b/trunk/arch/frv/mm/init.c index 0708284f85fb..1b851db34186 100644 --- a/trunk/arch/frv/mm/init.c +++ b/trunk/arch/frv/mm/init.c @@ -87,6 +87,8 @@ void __init paging_init(void) pkmap_page_table = alloc_bootmem_pages(PAGE_SIZE); + memset(pkmap_page_table, 0, PAGE_SIZE); + pge = swapper_pg_dir + pgd_index_k(PKMAP_BASE); pue = pud_offset(pge, PKMAP_BASE); pme = pmd_offset(pue, PKMAP_BASE); diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index c7966746fbfe..396ab059efa3 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -62,14 +62,13 @@ config GENERIC_TIME bool default y -config GENERIC_BUG - bool - depends on BUG - config TIME_LOW_RES bool default y +config ARCH_SUPPORTS_AOUT + def_bool y + config NO_IOPORT def_bool y diff --git a/trunk/arch/h8300/Kconfig.cpu b/trunk/arch/h8300/Kconfig.cpu index b65dcfe51d9c..582797db9603 100644 --- a/trunk/arch/h8300/Kconfig.cpu +++ b/trunk/arch/h8300/Kconfig.cpu @@ -1,7 +1,5 @@ menu "Processor type and features" -source "kernel/time/Kconfig" - choice prompt "H8/300 platform" default H8300H_GENERIC @@ -13,7 +11,6 @@ config H8300H_GENERIC config H8300H_AKI3068NET bool "AE-3068/69" - select CONFIG_H83068 help AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support More Information. (Japanese Only) @@ -24,7 +21,6 @@ config H8300H_AKI3068NET config H8300H_H8MAX bool "H8MAX" - select CONFIG_H83068 help H8MAX Evaluation Board Support More Information. (Japanese Only) @@ -32,7 +28,6 @@ config H8300H_H8MAX config H8300H_SIM bool "H8/300H Simulator" - select CONFIG_H83007 help GDB Simulator Support More Information. @@ -45,7 +40,6 @@ config H8S_GENERIC config H8S_EDOSK2674 bool "EDOSK-2674" - select CONFIG_H8S2768 help Renesas EDOSK-2674 Evaluation Board Support More Information. @@ -61,37 +55,44 @@ config H8S_SIM endchoice +if (H8300H_GENERIC || H8S_GENERIC) +menu "Detail Selection" +if (H8300H_GENERIC) choice prompt "CPU Selection" config H83002 bool "H8/3001,3002,3003" - select CPU_H8300H config H83007 bool "H8/3006,3007" - select CPU_H8300H config H83048 bool "H8/3044,3045,3046,3047,3048,3052" - select CPU_H8300H config H83068 bool "H8/3065,3066,3067,3068,3069" - select CPU_H8300H +endchoice +endif + +if (H8S_GENERIC) +choice + prompt "CPU Selection" config H8S2678 bool "H8S/2670,2673,2674R,2675,2676" - select CPU_H8S - endchoice +endif config CPU_CLOCK int "CPU Clock Frequency (/1KHz)" default "20000" help CPU Clock Frequency divide to 1000 +endmenu +endif +if (H8300H_GENERIC || H8S_GENERIC || H8300H_SIM || H8S_SIM || H8S_EDOSK2674) choice prompt "Kernel executes from" ---help--- @@ -106,61 +107,75 @@ config ROMKERNEL bool "ROM" help The kernel will be resident in FLASH/ROM when running. + endchoice +endif +if (H8300H_AKI3068NET) +config H83068 + bool + default y -config CPU_H8300H +config CPU_CLOCK + int + default "20000" + +config RAMKERNEL bool - depends on (H83002 || H83007 || H83048 || H83068) default y +endif -config CPU_H8S +if (H8300H_H8MAX) +config H83068 bool - depends on H8S2678 default y -choice - prompt "Timer" -config H8300_TIMER8 - bool "8bit timer (2ch cascade)" - depends on (H83007 || H83068 || H8S2678) +config CPU_CLOCK + int + default 25000 -config H8300_TIMER16 - bool "16bit timer" - depends on (H83007 || H83068) +config RAMKERNEL + bool + default y +endif -config H8300_ITU - bool "ITU" - depends on (H83002 || H83048) +if (H8300H_SIM) +config H83007 + bool + default y -config H8300_TPU - bool "TPU" - depends on H8S2678 -endchoice +config CPU_CLOCK + int + default "16000" +endif -if H8300_TIMER8 -choice - prompt "Timer Channel" -config H8300_TIMER8_CH0 - bool "Channel 0" -config H8300_TIMER8_CH2 - bool "Channel 2" - depends on CPU_H8300H -endchoice +if (H8S_EDOSK2674) +config H8S2678 + bool + default y +config CPU_CLOCK + int + default 33000 endif -config H8300_TIMER16_CH - int "16bit timer channel (0 - 2)" - depends on H8300_TIMER16 - range 0 2 +if (H8S_SIM) +config H8S2678 + bool + default y +config CPU_CLOCK + int + default 33000 +endif -config H8300_ITU_CH - int "ITU channel" - depends on H8300_ITU +config CPU_H8300H + bool + depends on (H83002 || H83007 || H83048 || H83068) + default y -config H8300_TPU_CH - int "TPU channel" - depends on H8300_TPU +config CPU_H8S + bool + depends on H8S2678 + default y config PREEMPT bool "Preemptible Kernel" diff --git a/trunk/arch/h8300/include/asm/a.out.h b/trunk/arch/h8300/include/asm/a.out.h new file mode 100644 index 000000000000..ded780f0a492 --- /dev/null +++ b/trunk/arch/h8300/include/asm/a.out.h @@ -0,0 +1,20 @@ +#ifndef __H8300_A_OUT_H__ +#define __H8300_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#endif /* __H8300_A_OUT_H__ */ diff --git a/trunk/arch/h8300/include/asm/bug.h b/trunk/arch/h8300/include/asm/bug.h index 887c19773185..edddf5b086e5 100644 --- a/trunk/arch/h8300/include/asm/bug.h +++ b/trunk/arch/h8300/include/asm/bug.h @@ -1,8 +1,4 @@ #ifndef _H8300_BUG_H #define _H8300_BUG_H - -/* always true */ -#define is_valid_bugaddr(addr) (1) - #include #endif diff --git a/trunk/arch/h8300/include/asm/elf.h b/trunk/arch/h8300/include/asm/elf.h index 94e2284c8816..a8b57d1f4128 100644 --- a/trunk/arch/h8300/include/asm/elf.h +++ b/trunk/arch/h8300/include/asm/elf.h @@ -55,7 +55,7 @@ typedef unsigned long elf_fpregset_t; #define ELF_PLATFORM (NULL) -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX) #define R_H8_NONE 0 #define R_H8_DIR32 1 diff --git a/trunk/arch/h8300/include/asm/io.h b/trunk/arch/h8300/include/asm/io.h index 33e842f3284b..26dc6ccd9441 100644 --- a/trunk/arch/h8300/include/asm/io.h +++ b/trunk/arch/h8300/include/asm/io.h @@ -295,40 +295,6 @@ static __inline__ void ctrl_outl(unsigned long b, unsigned long addr) *(volatile unsigned long*)addr = b; } -static __inline__ void ctrl_bclr(int b, unsigned long addr) -{ - if (__builtin_constant_p(b)) - switch (b) { - case 0: __asm__("bclr #0,@%0"::"r"(addr)); break; - case 1: __asm__("bclr #1,@%0"::"r"(addr)); break; - case 2: __asm__("bclr #2,@%0"::"r"(addr)); break; - case 3: __asm__("bclr #3,@%0"::"r"(addr)); break; - case 4: __asm__("bclr #4,@%0"::"r"(addr)); break; - case 5: __asm__("bclr #5,@%0"::"r"(addr)); break; - case 6: __asm__("bclr #6,@%0"::"r"(addr)); break; - case 7: __asm__("bclr #7,@%0"::"r"(addr)); break; - } - else - __asm__("bclr %w0,@%1"::"r"(b), "r"(addr)); -} - -static __inline__ void ctrl_bset(int b, unsigned long addr) -{ - if (__builtin_constant_p(b)) - switch (b) { - case 0: __asm__("bset #0,@%0"::"r"(addr)); break; - case 1: __asm__("bset #1,@%0"::"r"(addr)); break; - case 2: __asm__("bset #2,@%0"::"r"(addr)); break; - case 3: __asm__("bset #3,@%0"::"r"(addr)); break; - case 4: __asm__("bset #4,@%0"::"r"(addr)); break; - case 5: __asm__("bset #5,@%0"::"r"(addr)); break; - case 6: __asm__("bset #6,@%0"::"r"(addr)); break; - case 7: __asm__("bset #7,@%0"::"r"(addr)); break; - } - else - __asm__("bset %w0,@%1"::"r"(b), "r"(addr)); -} - /* Pages to physical address... */ #define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) #define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) diff --git a/trunk/arch/h8300/include/asm/md.h b/trunk/arch/h8300/include/asm/md.h index 1b7300e0a175..1a47dc6691fb 100644 --- a/trunk/arch/h8300/include/asm/md.h +++ b/trunk/arch/h8300/include/asm/md.h @@ -1,4 +1,4 @@ -/* +/* $Id: md.h,v 1.1 2002/11/19 02:09:26 gerg Exp $ * md.h: High speed xor_block operation for RAID4/5 * */ diff --git a/trunk/arch/h8300/include/asm/system.h b/trunk/arch/h8300/include/asm/system.h index d98d97685f06..4b8e475908ae 100644 --- a/trunk/arch/h8300/include/asm/system.h +++ b/trunk/arch/h8300/include/asm/system.h @@ -155,6 +155,4 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz #define arch_align_stack(x) (x) -void die(char *str, struct pt_regs *fp, unsigned long err); - #endif /* _H8300_SYSTEM_H */ diff --git a/trunk/arch/h8300/kernel/Makefile b/trunk/arch/h8300/kernel/Makefile index 8d4d2a54be9e..6c248c3c5c3b 100644 --- a/trunk/arch/h8300/kernel/Makefile +++ b/trunk/arch/h8300/kernel/Makefile @@ -7,6 +7,6 @@ extra-y := vmlinux.lds obj-y := process.o traps.o ptrace.o irq.o \ sys_h8300.o time.o signal.o \ setup.o gpio.o init_task.o syscalls.o \ - entry.o timer/ + entry.o obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o diff --git a/trunk/arch/h8300/kernel/module.c b/trunk/arch/h8300/kernel/module.c index cfc9127d2ced..4fd7138a6e03 100644 --- a/trunk/arch/h8300/kernel/module.c +++ b/trunk/arch/h8300/kernel/module.c @@ -114,10 +114,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { - module_bug_cleanup(mod); } diff --git a/trunk/arch/h8300/kernel/process.c b/trunk/arch/h8300/kernel/process.c index a8ef654a5a0b..dfbe7ab9ffe2 100644 --- a/trunk/arch/h8300/kernel/process.c +++ b/trunk/arch/h8300/kernel/process.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/h8300/kernel/time.c b/trunk/arch/h8300/kernel/time.c index 7f2d6cfbb4b6..e37c835e67cf 100644 --- a/trunk/arch/h8300/kernel/time.c +++ b/trunk/arch/h8300/kernel/time.c @@ -27,21 +27,27 @@ #include #include -#include +#include #define TICK_SIZE (tick_nsec / 1000) -void h8300_timer_tick(void) +/* + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "do_timer()" routine every clocktick + */ +static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) { - if (current->pid) - profile_tick(CPU_PROFILING); - write_seqlock(&xtime_lock); + /* may need to kick the hardware timer */ + platform_timer_eoi(); + do_timer(1); - write_sequnlock(&xtime_lock); - update_process_times(user_mode(get_irq_regs())); +#ifndef CONFIG_SMP + update_process_times(user_mode(regs)); +#endif + profile_tick(CPU_PROFILING); } -void __init time_init(void) +void time_init(void) { unsigned int year, mon, day, hour, min, sec; @@ -51,13 +57,12 @@ void __init time_init(void) year = 1980; mon = day = 1; hour = min = sec = 0; -#ifdef CONFIG_H8300_GETTOD - h8300_gettod (&year, &mon, &day, &hour, &min, &sec); -#endif + platform_gettod (&year, &mon, &day, &hour, &min, &sec); + if ((year += 1900) < 1970) year += 100; xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_nsec = 0; - h8300_timer_setup(); + platform_timer_setup(timer_interrupt); } diff --git a/trunk/arch/h8300/kernel/timer/Makefile b/trunk/arch/h8300/kernel/timer/Makefile deleted file mode 100644 index bef0510ea6ad..000000000000 --- a/trunk/arch/h8300/kernel/timer/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# h8300 internal timer handler - -obj-$(CONFIG_H8300_TIMER8) := timer8.o -obj-$(CONFIG_H8300_TIMER16) := timer16.o -obj-$(CONFIG_H8300_ITU) := itu.o -obj-$(CONFIG_H8300_TPU) := tpu.o diff --git a/trunk/arch/h8300/kernel/timer/itu.c b/trunk/arch/h8300/kernel/timer/itu.c deleted file mode 100644 index d1c926596b08..000000000000 --- a/trunk/arch/h8300/kernel/timer/itu.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * linux/arch/h8300/kernel/timer/itu.c - * - * Yoshinori Sato - * - * ITU Timer Handler - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if CONFIG_H8300_ITU_CH == 0 -#define ITUBASE 0xffff64 -#define ITUIRQ 24 -#elif CONFIG_H8300_ITU_CH == 1 -#define ITUBASE 0xffff6e -#define ITUIRQ 28 -#elif CONFIG_H8300_ITU_CH == 2 -#define ITUBASE 0xffff78 -#define ITUIRQ 32 -#elif CONFIG_H8300_ITU_CH == 3 -#define ITUBASE 0xffff82 -#define ITUIRQ 36 -#elif CONFIG_H8300_ITU_CH == 4 -#define ITUBASE 0xffff92 -#define ITUIRQ 40 -#else -#error Unknown timer channel. -#endif - -#define TCR 0 -#define TIOR 1 -#define TIER 2 -#define TSR 3 -#define TCNT 4 -#define GRA 6 -#define GRB 8 - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(IMFA, ITUBASE + TSR); - return IRQ_HANDLED; -} - -static struct irqaction itu_irq = { - .name = "itu", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, - .mask = CPU_MASK_NONE, -}; - -static const int __initdata divide_rate[] = {1, 2, 4, 8}; - -void __init h8300_timer_setup(void) -{ - unsigned int div; - unsigned int cnt; - - calc_param(cnt, div, divide_rate, 0x10000); - - setup_irq(ITUIRQ, &itu_irq); - - /* initalize timer */ - ctrl_outb(0, TSTR); - ctrl_outb(CCLR0 | div, ITUBASE + TCR); - ctrl_outb(0x01, ITUBASE + TIER); - ctrl_outw(cnt, ITUBASE + GRA); - ctrl_bset(CONFIG_H8300_ITU_CH, TSTR); -} diff --git a/trunk/arch/h8300/kernel/timer/timer16.c b/trunk/arch/h8300/kernel/timer/timer16.c deleted file mode 100644 index e14271b72119..000000000000 --- a/trunk/arch/h8300/kernel/timer/timer16.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * linux/arch/h8300/kernel/timer/timer16.c - * - * Yoshinori Sato - * - * 16bit Timer Handler - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* 16bit timer */ -#if CONFIG_H8300_TIMER16_CH == 0 -#define _16BASE 0xffff78 -#define _16IRQ 24 -#elif CONFIG_H8300_TIMER16_CH == 1 -#define _16BASE 0xffff80 -#define _16IRQ 28 -#elif CONFIG_H8300_TIMER16_CH == 2 -#define _16BASE 0xffff88 -#define _16IRQ 32 -#else -#error Unknown timer channel. -#endif - -#define TCR 0 -#define TIOR 1 -#define TCNT 2 -#define GRA 4 -#define GRB 6 - -#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*10000 /* Timer input freq. */ - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(CONFIG_H8300_TIMER16_CH, TISRA); - return IRQ_HANDLED; -} - -static struct irqaction timer16_irq = { - .name = "timer-16", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, - .mask = CPU_MASK_NONE, -}; - -static const int __initdata divide_rate[] = {1, 2, 4, 8}; - -void __init h8300_timer_setup(void) -{ - unsigned int div; - unsigned int cnt; - - calc_param(cnt, div, divide_rate, 0x10000); - - setup_irq(_16IRQ, &timer16_irq); - - /* initalize timer */ - ctrl_outb(0, TSTR); - ctrl_outb(CCLR0 | div, _16BASE + TCR); - ctrl_outw(cnt, _16BASE + GRA); - ctrl_bset(4 + CONFIG_H8300_TIMER16_CH, TISRA); - ctrl_bset(CONFIG_H8300_TIMER16_CH, TSTR); -} diff --git a/trunk/arch/h8300/kernel/timer/timer8.c b/trunk/arch/h8300/kernel/timer/timer8.c deleted file mode 100644 index 0556d7c7bea6..000000000000 --- a/trunk/arch/h8300/kernel/timer/timer8.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * linux/arch/h8300/kernel/cpu/timer/timer8.c - * - * Yoshinori Sato - * - * 8bit Timer Handler - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#if defined(CONFIG_CPU_H8300H) -#include -#endif -#if defined(CONFIG_CPU_H8S) -#include -#endif - -/* 8bit timer x2 */ -#define CMFA 6 - -#if defined(CONFIG_H8300_TIMER8_CH0) -#define _8BASE _8TCR0 -#ifdef CONFIG_CPU_H8300H -#define _8IRQ 36 -#endif -#ifdef CONFIG_CPU_H8S -#define _8IRQ 72 -#endif -#elif defined(CONFIG_H8300_TIMER8_CH2) -#ifdef CONFIG_CPU_H8300H -#define _8BASE _8TCR2 -#define _8IRQ 40 -#endif -#endif - -#ifndef _8BASE -#error Unknown timer channel. -#endif - -#define _8TCR 0 -#define _8TCSR 2 -#define TCORA 4 -#define TCORB 6 -#define _8TCNT 8 - -#define CMIEA 0x40 -#define CCLR_CMA 0x08 -#define CKS2 0x04 - -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(CMFA, _8BASE + _8TCSR); - return IRQ_HANDLED; -} - -static struct irqaction timer8_irq = { - .name = "timer-8", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, - .mask = CPU_MASK_NONE, -}; - -static const int __initdata divide_rate[] = {8, 64, 8192}; - -void __init h8300_timer_setup(void) -{ - unsigned int div; - unsigned int cnt; - - calc_param(cnt, div, divide_rate, 0x10000); - div++; - - setup_irq(_8IRQ, &timer8_irq); - -#if defined(CONFIG_CPU_H8S) - /* Timer module enable */ - ctrl_bclr(0, MSTPCRL) -#endif - - /* initalize timer */ - ctrl_outw(cnt, _8BASE + TCORA); - ctrl_outw(0x0000, _8BASE + _8TCSR); - ctrl_outw((CMIEA|CCLR_CMA|CKS2) << 8 | div, - _8BASE + _8TCR); -} diff --git a/trunk/arch/h8300/kernel/timer/tpu.c b/trunk/arch/h8300/kernel/timer/tpu.c deleted file mode 100644 index df7f453a9673..000000000000 --- a/trunk/arch/h8300/kernel/timer/tpu.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * linux/arch/h8300/kernel/timer/tpu.c - * - * Yoshinori Sato - * - * TPU Timer Handler - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* TPU */ -#if CONFIG_H8300_TPU_CH == 0 -#define TPUBASE 0xffffd0 -#define TPUIRQ 40 -#elif CONFIG_H8300_TPU_CH == 1 -#define TPUBASE 0xffffe0 -#define TPUIRQ 48 -#elif CONFIG_H8300_TPU_CH == 2 -#define TPUBASE 0xfffff0 -#define TPUIRQ 52 -#elif CONFIG_H8300_TPU_CH == 3 -#define TPUBASE 0xfffe80 -#define TPUIRQ 56 -#elif CONFIG_H8300_TPU_CH == 4 -#define TPUBASE 0xfffe90 -#define TPUIRQ 64 -#else -#error Unknown timer channel. -#endif - -#define _TCR 0 -#define _TMDR 1 -#define _TIOR 2 -#define _TIER 4 -#define _TSR 5 -#define _TCNT 6 -#define _GRA 8 -#define _GRB 10 - -#define CCLR0 0x20 - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - h8300_timer_tick(); - ctrl_bclr(0, TPUBASE + _TSR); - return IRQ_HANDLED; -} - -static struct irqaction tpu_irq = { - .name = "tpu", - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, - .mask = CPU_MASK_NONE, -}; - -const static int __initdata divide_rate[] = { -#if CONFIG_H8300_TPU_CH == 0 - 1,4,16,64,0,0,0,0, -#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5) - 1,4,16,64,0,0,256,0, -#elif (CONFIG_H8300_TPU_CH == 2) || (CONFIG_H8300_TPU_CH == 4) - 1,4,16,64,0,0,0,1024, -#elif CONFIG_H8300_TPU_CH == 3 - 1,4,16,64,0,1024,256,4096, -#endif -}; - -void __init h8300_timer_setup(void) -{ - unsigned int cnt; - unsigned int div; - - calc_param(cnt, div, divide_rate, 0x10000); - - setup_irq(TPUIRQ, &tpu_irq); - - /* TPU module enabled */ - ctrl_bclr(3, MSTPCRH); - - ctrl_outb(0, TSTR); - ctrl_outb(CCLR0 | div, TPUBASE + _TCR); - ctrl_outb(0, TPUBASE + _TMDR); - ctrl_outw(0, TPUBASE + _TIOR); - ctrl_outb(0x01, TPUBASE + _TIER); - ctrl_outw(cnt, TPUBASE + _GRA); - ctrl_bset(CONFIG_H8300_TPU_CH, TSTR); -} diff --git a/trunk/arch/h8300/kernel/traps.c b/trunk/arch/h8300/kernel/traps.c index 3c0b66bc669e..f8f7d7ea97f1 100644 --- a/trunk/arch/h8300/kernel/traps.c +++ b/trunk/arch/h8300/kernel/traps.c @@ -20,14 +20,12 @@ #include #include #include -#include #include #include #include #include - -static DEFINE_SPINLOCK(die_lock); +#include /* * this must be called very early as the kernel might @@ -96,19 +94,16 @@ static void dump(struct pt_regs *fp) printk("\n\n"); } -void die(char *str, struct pt_regs *fp, unsigned long err) +void die_if_kernel (char *str, struct pt_regs *fp, int nr) { - static int diecount; + extern int console_loglevel; - oops_enter(); + if (!(fp->ccr & PS_S)) + return; - console_verbose(); - spin_lock_irq(&die_lock); - report_bug(fp->pc, fp); - printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++diecount); + console_loglevel = 15; dump(fp); - spin_unlock_irq(&die_lock); do_exit(SIGSEGV); } diff --git a/trunk/arch/h8300/mm/fault.c b/trunk/arch/h8300/mm/fault.c index 1d092abebf03..29e9af9f0e6a 100644 --- a/trunk/arch/h8300/mm/fault.c +++ b/trunk/arch/h8300/mm/fault.c @@ -20,6 +20,8 @@ #include #include +extern void die_if_kernel(char *, struct pt_regs *, long); + /* * This routine handles page faults. It determines the problem, and * then passes it off to one of the appropriate routines. @@ -48,8 +50,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, } else printk(KERN_ALERT "Unable to handle kernel access"); printk(" at virtual address %08lx\n",address); - if (!user_mode(regs)) - die("Oops", regs, error_code); + die_if_kernel("Oops", regs, error_code); do_exit(SIGKILL); return 1; diff --git a/trunk/arch/h8300/platform/h8300h/aki3068net/Makefile b/trunk/arch/h8300/platform/h8300h/aki3068net/Makefile index b7ff78050b7f..b03c328f8c70 100644 --- a/trunk/arch/h8300/platform/h8300h/aki3068net/Makefile +++ b/trunk/arch/h8300/platform/h8300h/aki3068net/Makefile @@ -3,3 +3,4 @@ # extra-y := crt0_ram.o +obj-y := timer.o diff --git a/trunk/arch/h8300/platform/h8300h/aki3068net/timer.c b/trunk/arch/h8300/platform/h8300h/aki3068net/timer.c new file mode 100644 index 000000000000..27cd85d56128 --- /dev/null +++ b/trunk/arch/h8300/platform/h8300h/aki3068net/timer.c @@ -0,0 +1,51 @@ +/* + * linux/arch/h8300/platform/h8300h/aki3068net/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CMFA 6 + +#define CMIEA 0x40 +#define CCLR_CMA 0x08 +#define CLK_DIV8192 0x03 + +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */ + +void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *)) +{ + /* setup 8bit timer ch2 */ + ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */ + ctrl_outb(0x00, _8TCSR2); /* no output */ + request_irq(40, timer_int, 0, "timer", 0); + ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */ +} + +void platform_timer_eoi(void) +{ + *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA); +} + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/trunk/arch/h8300/platform/h8300h/generic/Makefile b/trunk/arch/h8300/platform/h8300h/generic/Makefile index 2b12a170209e..32b964a9010e 100644 --- a/trunk/arch/h8300/platform/h8300h/generic/Makefile +++ b/trunk/arch/h8300/platform/h8300h/generic/Makefile @@ -3,3 +3,4 @@ # extra-y := crt0_$(MODEL).o +obj-y := timer.o diff --git a/trunk/arch/h8300/platform/h8300h/generic/timer.c b/trunk/arch/h8300/platform/h8300h/generic/timer.c new file mode 100644 index 000000000000..6f5cefe0cceb --- /dev/null +++ b/trunk/arch/h8300/platform/h8300h/generic/timer.c @@ -0,0 +1,95 @@ +/* + * linux/arch/h8300/platform/h8300h/generic/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if defined(CONFIG_H83007) || defined(CONFIG_H83068) +#include +#define CMFA 6 + +#define CMIEA 0x40 +#define CCLR_CMA 0x08 +#define CLK_DIV8192 0x03 + +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */ + +void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *)) +{ + /* setup 8bit timer ch2 */ + ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */ + ctrl_outb(0x00, _8TCSR2); /* no output */ + request_irq(40, timer_int, 0, "timer", 0); + ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */ +} + +void platform_timer_eoi(void) +{ + *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA); +} +#endif + +#if defined(CONFIG_H83002) || defined(CONFIG_H83048) +/* FIXME! */ +#define TSTR 0x00ffff60 +#define TSNC 0x00ffff61 +#define TMDR 0x00ffff62 +#define TFCR 0x00ffff63 +#define TOER 0x00ffff90 +#define TOCR 0x00ffff91 +/* ITU0 */ +#define TCR 0x00ffff64 +#define TIOR 0x00ffff65 +#define TIER 0x00ffff66 +#define TSR 0x00ffff67 +#define TCNT 0x00ffff68 +#define GRA 0x00ffff6a +#define GRB 0x00ffff6c + +#define CCLR_CMGRA 0x20 +#define CLK_DIV8 0x03 + +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8 /* Timer input freq. */ + +void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *)) +{ + *(unsigned short *)GRA= H8300_TIMER_FREQ / HZ; /* set interval */ + *(unsigned short *)TCNT=0; /* clear counter */ + ctrl_outb(0x80|CCLR_CMGRA|CLK_DIV8, TCR); /* set ITU0 clock */ + ctrl_outb(0x88, TIOR); /* no output */ + request_irq(26, timer_int, 0, "timer", 0); + ctrl_outb(0xf9, TIER); /* compare match GRA interrupt */ + ctrl_outb(ctrl_inb(TSNC) & ~0x01, TSNC); /* ITU0 async */ + ctrl_outb(ctrl_inb(TMDR) & ~0x01, TMDR); /* ITU0 normal mode */ + ctrl_outb(ctrl_inb(TSTR) | 0x01, TSTR); /* ITU0 Start */ + return 0; +} + +void platform_timer_eoi(void) +{ + ctrl_outb(ctrl_inb(TSR) & ~0x01,TSR); +} +#endif + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/trunk/arch/h8300/platform/h8300h/h8max/Makefile b/trunk/arch/h8300/platform/h8300h/h8max/Makefile index b7ff78050b7f..b03c328f8c70 100644 --- a/trunk/arch/h8300/platform/h8300h/h8max/Makefile +++ b/trunk/arch/h8300/platform/h8300h/h8max/Makefile @@ -3,3 +3,4 @@ # extra-y := crt0_ram.o +obj-y := timer.o diff --git a/trunk/arch/h8300/platform/h8300h/h8max/timer.c b/trunk/arch/h8300/platform/h8300h/h8max/timer.c new file mode 100644 index 000000000000..85a574afe9d0 --- /dev/null +++ b/trunk/arch/h8300/platform/h8300h/h8max/timer.c @@ -0,0 +1,52 @@ +/* + * linux/arch/h8300/platform/h8300h/h8max/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CMFA 6 + +#define CMIEA 0x40 +#define CCLR_CMA 0x08 +#define CLK_DIV8192 0x03 + +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */ + +void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *)) +{ + /* setup 8bit timer ch2 */ + ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */ + ctrl_outb(0x00, _8TCSR2); /* no output */ + request_irq(40, timer_int, 0, "timer", 0); + ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */ +} + +void platform_timer_eoi(void) +{ + *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA); +} + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} + diff --git a/trunk/arch/h8300/platform/h8s/edosk2674/Makefile b/trunk/arch/h8300/platform/h8s/edosk2674/Makefile index 8e349723bb4f..f763654ac6fe 100644 --- a/trunk/arch/h8300/platform/h8s/edosk2674/Makefile +++ b/trunk/arch/h8300/platform/h8s/edosk2674/Makefile @@ -3,3 +3,4 @@ # extra-y := crt0_$(MODEL).o +obj-y := timer.o diff --git a/trunk/arch/h8300/platform/h8s/edosk2674/timer.c b/trunk/arch/h8300/platform/h8s/edosk2674/timer.c new file mode 100644 index 000000000000..bfb1424482f4 --- /dev/null +++ b/trunk/arch/h8300/platform/h8s/edosk2674/timer.c @@ -0,0 +1,54 @@ +/* + * linux/arch/h8300/platform/h8s/edosk2674/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CMFA 6 + +#define CMIEA 0x40 +#define CCLR_CMA 0x08 +#define CLK_DIV8192 0x03 + +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */ + +void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *)) +{ + /* 8bit timer module enabled */ + ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL); + /* setup 8bit timer ch1 */ + ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1); /* set interval */ + ctrl_outb(0x00, _8TCSR1); /* no output */ + request_irq(76, timer_int, 0, "timer" ,0); + ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1); /* start count */ +} + +void platform_timer_eoi(void) +{ + *(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA); +} + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ +/* FIXME! not RTC support */ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/trunk/arch/h8300/platform/h8s/generic/Makefile b/trunk/arch/h8300/platform/h8s/generic/Makefile index 44b4685c664c..055d53a9811b 100644 --- a/trunk/arch/h8300/platform/h8s/generic/Makefile +++ b/trunk/arch/h8300/platform/h8s/generic/Makefile @@ -3,3 +3,4 @@ # extra-y = crt0_$(MODEL).o +obj-y := timer.o diff --git a/trunk/arch/h8300/platform/h8s/generic/timer.c b/trunk/arch/h8300/platform/h8s/generic/timer.c new file mode 100644 index 000000000000..c2211c6e79da --- /dev/null +++ b/trunk/arch/h8300/platform/h8s/generic/timer.c @@ -0,0 +1,53 @@ +/* + * linux/arch/h8300/platform/h8s/generic/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CMFA 6 + +#define CMIEA 0x40 +#define CCLR_CMA 0x08 +#define CLK_DIV8192 0x03 + +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */ + +void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *)) +{ + /* 8bit timer module enabled */ + ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL); + /* setup 8bit timer ch1 */ + ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1); /* set interval */ + ctrl_outb(0x00, _8TCSR1); /* no output */ + request_irq(76, timer_int, 0, "timer" ,0); + ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1); /* start count */ +} + +void platform_timer_eoi(void) +{ + *(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA); +} + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 3b7aa38254a8..48e496fe1e75 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -60,6 +60,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config HUGETLB_PAGE_SIZE_VARIABLE bool depends on HUGETLB_PAGE diff --git a/trunk/arch/ia64/ia32/binfmt_elf32.c b/trunk/arch/ia64/ia32/binfmt_elf32.c index f92bdaac8976..4f0c30c38e99 100644 --- a/trunk/arch/ia64/ia32/binfmt_elf32.c +++ b/trunk/arch/ia64/ia32/binfmt_elf32.c @@ -41,7 +41,7 @@ randomize_stack_top(unsigned long stack_top); #define elf_map elf32_map #undef SET_PERSONALITY -#define SET_PERSONALITY(ex) elf32_set_personality() +#define SET_PERSONALITY(ex, ibcs2) elf32_set_personality() #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack)) diff --git a/trunk/arch/ia64/ia32/ia32_entry.S b/trunk/arch/ia64/ia32/ia32_entry.S index 53505bb04771..ff88c48c5d19 100644 --- a/trunk/arch/ia64/ia32/ia32_entry.S +++ b/trunk/arch/ia64/ia32/ia32_entry.S @@ -251,8 +251,8 @@ ia32_syscall_table: data8 compat_sys_setrlimit /* 75 */ data8 compat_sys_old_getrlimit data8 compat_sys_getrusage - data8 compat_sys_gettimeofday - data8 compat_sys_settimeofday + data8 sys32_gettimeofday + data8 sys32_settimeofday data8 sys32_getgroups16 /* 80 */ data8 sys32_setgroups16 data8 sys32_old_select diff --git a/trunk/arch/ia64/ia32/ia32priv.h b/trunk/arch/ia64/ia32/ia32priv.h index 0f15349c3c6b..dd0c53687a96 100644 --- a/trunk/arch/ia64/ia32/ia32priv.h +++ b/trunk/arch/ia64/ia32/ia32priv.h @@ -332,8 +332,8 @@ void ia64_elf32_init(struct pt_regs *regs); #define ELF_PLATFORM NULL #ifdef __KERNEL__ -# define SET_PERSONALITY(EX) \ - (current->personality = PER_LINUX) +# define SET_PERSONALITY(EX,IBCS2) \ + (current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX) #endif #define IA32_EFLAG 0x200 diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index f4430bb4bbdc..bf196cbb3796 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -118,6 +118,41 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use return error; } +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) +{ + compat_ino_t ino; + int err; + + if ((u64) stat->size > MAX_NON_LFS || + !old_valid_dev(stat->dev) || + !old_valid_dev(stat->rdev)) + return -EOVERFLOW; + + ino = stat->ino; + if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) + return -EOVERFLOW; + + if (clear_user(ubuf, sizeof(*ubuf))) + return -EFAULT; + + err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); + err |= __put_user(ino, &ubuf->st_ino); + err |= __put_user(stat->mode, &ubuf->st_mode); + err |= __put_user(stat->nlink, &ubuf->st_nlink); + err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); + err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid); + err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev); + err |= __put_user(stat->size, &ubuf->st_size); + err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime); + err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec); + err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime); + err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec); + err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime); + err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec); + err |= __put_user(stat->blksize, &ubuf->st_blksize); + err |= __put_user(stat->blocks, &ubuf->st_blocks); + return err; +} #if PAGE_SHIFT > IA32_PAGE_SHIFT @@ -1113,12 +1148,68 @@ sys32_pipe (int __user *fd) return retval; } +static inline long +get_tv32 (struct timeval *o, struct compat_timeval __user *i) +{ + return (!access_ok(VERIFY_READ, i, sizeof(*i)) || + (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec))); +} + +static inline long +put_tv32 (struct compat_timeval __user *o, struct timeval *i) +{ + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || + (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec))); +} + asmlinkage unsigned long sys32_alarm (unsigned int seconds) { return alarm_setitimer(seconds); } +/* Translations due to time_t size differences. Which affects all + sorts of things, like timeval and itimerval. */ + +extern struct timezone sys_tz; + +asmlinkage long +sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz) +{ + if (tv) { + struct timeval ktv; + do_gettimeofday(&ktv); + if (put_tv32(tv, &ktv)) + return -EFAULT; + } + if (tz) { + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + return 0; +} + +asmlinkage long +sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz) +{ + struct timeval ktv; + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_tv32(&ktv, tv)) + return -EFAULT; + kts.tv_sec = ktv.tv_sec; + kts.tv_nsec = ktv.tv_usec * 1000; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + struct sel_arg_struct { unsigned int n; unsigned int inp; diff --git a/trunk/arch/ia64/include/asm/a.out.h b/trunk/arch/ia64/include/asm/a.out.h new file mode 100644 index 000000000000..193dcfb67596 --- /dev/null +++ b/trunk/arch/ia64/include/asm/a.out.h @@ -0,0 +1,32 @@ +#ifndef _ASM_IA64_A_OUT_H +#define _ASM_IA64_A_OUT_H + +/* + * No a.out format has been (or should be) defined so this file is + * just a dummy that allows us to get binfmt_elf compiled. It + * probably would be better to clean up binfmt_elf.c so it does not + * necessarily depend on there being a.out support. + * + * Modified 1998-2002 + * David Mosberger-Tang , Hewlett-Packard Co. + */ + +#include + +struct exec { + unsigned long a_info; + unsigned long a_text; + unsigned long a_data; + unsigned long a_bss; + unsigned long a_entry; +}; + +#define N_TXTADDR(x) 0 +#define N_DATADDR(x) 0 +#define N_BSSADDR(x) 0 +#define N_DRSIZE(x) 0 +#define N_TRSIZE(x) 0 +#define N_SYMSIZE(x) 0 +#define N_TXTOFF(x) 0 + +#endif /* _ASM_IA64_A_OUT_H */ diff --git a/trunk/arch/ia64/include/asm/elf.h b/trunk/arch/ia64/include/asm/elf.h index 86eddee029cb..2acb6b6543c9 100644 --- a/trunk/arch/ia64/include/asm/elf.h +++ b/trunk/arch/ia64/include/asm/elf.h @@ -202,7 +202,7 @@ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst); relevant until we have real hardware to play with... */ #define ELF_PLATFORM NULL -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX) #define elf_read_implies_exec(ex, executable_stack) \ ((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0) diff --git a/trunk/arch/ia64/include/asm/statfs.h b/trunk/arch/ia64/include/asm/statfs.h index 1e589669de56..811097974f31 100644 --- a/trunk/arch/ia64/include/asm/statfs.h +++ b/trunk/arch/ia64/include/asm/statfs.h @@ -8,13 +8,55 @@ * David Mosberger-Tang , Hewlett-Packard Co */ +#ifndef __KERNEL_STRICT_NAMES +# include +typedef __kernel_fsid_t fsid_t; +#endif + /* - * We need compat_statfs64 to be packed, because the i386 ABI won't - * add padding at the end to bring it to a multiple of 8 bytes, but - * the IA64 ABI will. + * This is ugly --- we're already 64-bit, so just duplicate the definitions */ -#define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4))) +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; + + +struct statfs64 { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; -#include +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +} __attribute__((packed)); #endif /* _ASM_IA64_STATFS_H */ diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index f482a9098e32..200100ea7610 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index 00289c178f89..f57113f1f892 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -36,6 +36,9 @@ config NO_IOPORT config NO_DMA def_bool y +config ARCH_SUPPORTS_AOUT + def_bool y + config HZ int default 100 diff --git a/trunk/arch/m32r/kernel/process.c b/trunk/arch/m32r/kernel/process.c index 7103d91e1a2f..5be4faaf5b1c 100644 --- a/trunk/arch/m32r/kernel/process.c +++ b/trunk/arch/m32r/kernel/process.c @@ -11,7 +11,7 @@ #undef DEBUG_PROCESS #ifdef DEBUG_PROCESS #define DPRINTK(fmt, args...) printk("%s:%d:%s: " fmt, __FILE__, __LINE__, \ - __func__, ##args) + __FUNCTION__, ##args) #else #define DPRINTK(fmt, args...) #endif diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 677c93a490f6..8c5e1de68fcb 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -5,7 +5,6 @@ config M68K bool default y - select HAVE_AOUT select HAVE_IDE config MMU @@ -54,6 +53,9 @@ config NO_IOPORT config NO_DMA def_bool SUN3 +config ARCH_SUPPORTS_AOUT + def_bool y + config HZ int default 100 @@ -105,9 +107,21 @@ config PCMCIA To compile this driver as modules, choose M here: the modules will be called pcmcia_core and ds. +config SUN3 + bool "Sun3 support" + select M68020 + select MMU_SUN3 if MMU + help + This option enables support for the Sun 3 series of workstations + (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires + that all other hardware types must be disabled, as Sun 3 kernels + are incompatible with all other m68k targets (including Sun 3x!). + + If you don't want to compile a kernel exclusively for a Sun 3, say N. + config AMIGA bool "Amiga support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help This option enables support for the Amiga series of computers. If you plan to use this kernel on an Amiga, say Y here and browse the @@ -115,16 +129,33 @@ config AMIGA config ATARI bool "Atari support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help This option enables support for the 68000-based Atari series of computers (including the TT, Falcon and Medusa). If you plan to use this kernel on an Atari, say Y here and browse the material available in ; otherwise say N. +config HADES + bool "Hades support" + depends on ATARI && BROKEN + help + This option enables support for the Hades Atari clone. If you plan + to use this kernel on a Hades, say Y here; otherwise say N. + +config PCI + bool + depends on HADES + default y + help + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside + your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or + VESA. If you have PCI, say Y, otherwise N. + config MAC bool "Macintosh support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help This option enables support for the Apple Macintosh series of computers (yes, there is experimental support now, at least for part @@ -145,14 +176,14 @@ config M68K_L2_CACHE config APOLLO bool "Apollo support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help Say Y here if you want to run Linux on an MC680x0-based Apollo Domain workstation such as the DN3500. config VME bool "VME (Motorola and BVM) support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help Say Y here if you want to build a kernel for a 680x0 based VME board. Boards currently supported include Motorola boards MVME147, @@ -189,7 +220,7 @@ config BVME6000 config HP300 bool "HP9000/300 and HP9000/400 support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help This option enables support for the HP9000/300 and HP9000/400 series of workstations. Support for these machines is still somewhat @@ -208,7 +239,7 @@ config DIO config SUN3X bool "Sun3x support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 select M68030 help This option enables support for the Sun 3x series of workstations. @@ -221,7 +252,7 @@ config SUN3X config Q40 bool "Q40/Q60 support" - select MMU_MOTOROLA if MMU + depends on !MMU_SUN3 help The Q40 is a Motorola 68040-based successor to the Sinclair QL manufactured in Germany. There is an official Q40 home page at @@ -229,19 +260,6 @@ config Q40 Q60. Select your CPU below. For 68LC060 don't forget to enable FPU emulation. -config SUN3 - bool "Sun3 support" - depends on !MMU_MOTOROLA - select MMU_SUN3 if MMU - select M68020 - help - This option enables support for the Sun 3 series of workstations - (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires - that all other hardware types must be disabled, as Sun 3 kernels - are incompatible with all other m68k targets (including Sun 3x!). - - If you don't want to compile a kernel exclusively for a Sun 3, say N. - comment "Processor type" config M68020 @@ -279,10 +297,10 @@ config M68060 config MMU_MOTOROLA bool depends on MMU && !MMU_SUN3 + default y config MMU_SUN3 bool - depends on MMU && !MMU_MOTOROLA config M68KFPU_EMU bool "Math emulation support (EXPERIMENTAL)" diff --git a/trunk/arch/m68k/amiga/config.c b/trunk/arch/m68k/amiga/config.c index 0a3f9e8ebde0..df679d96b1cb 100644 --- a/trunk/arch/m68k/amiga/config.c +++ b/trunk/arch/m68k/amiga/config.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -985,11 +984,3 @@ static int amiga_get_hardware_list(char *buffer) return len; } - -/* - * The Amiga keyboard driver needs key_maps, but we cannot export it in - * drivers/char/defkeymap.c, as it is autogenerated - */ -#ifdef CONFIG_HW_CONSOLE -EXPORT_SYMBOL_GPL(key_maps); -#endif diff --git a/trunk/arch/m68k/atari/Makefile b/trunk/arch/m68k/atari/Makefile index 0cac723306f9..2cd905efe63a 100644 --- a/trunk/arch/m68k/atari/Makefile +++ b/trunk/arch/m68k/atari/Makefile @@ -5,4 +5,7 @@ obj-y := config.o time.o debug.o ataints.o stdma.o \ atasound.o stram.o +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_HADES) += hades-pci.o +endif obj-$(CONFIG_ATARI_KBD_CORE) += atakeyb.o diff --git a/trunk/arch/m68k/atari/ataints.c b/trunk/arch/m68k/atari/ataints.c index dba4afabb444..b45593a60bdd 100644 --- a/trunk/arch/m68k/atari/ataints.c +++ b/trunk/arch/m68k/atari/ataints.c @@ -407,8 +407,10 @@ void __init atari_init_IRQ(void) * gets overruns) */ - vectors[VEC_INT2] = falcon_hblhandler; - vectors[VEC_INT4] = falcon_hblhandler; + if (!MACH_IS_HADES) { + vectors[VEC_INT2] = falcon_hblhandler; + vectors[VEC_INT4] = falcon_hblhandler; + } } if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) { diff --git a/trunk/arch/m68k/atari/atakeyb.c b/trunk/arch/m68k/atari/atakeyb.c index c038b7c7eff0..bb959fbab2dc 100644 --- a/trunk/arch/m68k/atari/atakeyb.c +++ b/trunk/arch/m68k/atari/atakeyb.c @@ -635,3 +635,15 @@ int atari_keyb_init(void) return 0; } EXPORT_SYMBOL_GPL(atari_keyb_init); + +int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode) +{ +#ifdef CONFIG_MAGIC_SYSRQ + /* ALT+HELP pressed? */ + if ((keycode == 98) && ((shift_state & 0xff) == 8)) + *keycodep = 0xff; + else +#endif + *keycodep = keycode; + return 1; +} diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index af031855f796..5945e1505558 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -231,7 +231,7 @@ void __init config_atari(void) */ printk("Atari hardware found: "); - if (MACH_IS_MEDUSA) { + if (MACH_IS_MEDUSA || MACH_IS_HADES) { /* There's no Atari video hardware on the Medusa, but all the * addresses below generate a DTACK so no bus error occurs! */ } else if (hwreg_present(f030_xreg)) { @@ -269,6 +269,10 @@ void __init config_atari(void) ATARIHW_SET(SCSI_DMA); printk("TT_SCSI_DMA "); } + if (!MACH_IS_HADES && hwreg_present(&st_dma.dma_hi)) { + ATARIHW_SET(STND_DMA); + printk("STND_DMA "); + } /* * The ST-DMA address registers aren't readable * on all Medusas, so the test below may fail @@ -290,11 +294,12 @@ void __init config_atari(void) ATARIHW_SET(YM_2149); printk("YM2149 "); } - if (!MACH_IS_MEDUSA && hwreg_present(&tt_dmasnd.ctrl)) { + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present(&tt_dmasnd.ctrl)) { ATARIHW_SET(PCM_8BIT); printk("PCM "); } - if (hwreg_present(&falcon_codec.unused5)) { + if (!MACH_IS_HADES && hwreg_present(&falcon_codec.unused5)) { ATARIHW_SET(CODEC); printk("CODEC "); } @@ -308,7 +313,7 @@ void __init config_atari(void) (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) #else - !MACH_IS_MEDUSA + !MACH_IS_MEDUSA && !MACH_IS_HADES #endif ) { ATARIHW_SET(SCC_DMA); @@ -322,7 +327,10 @@ void __init config_atari(void) ATARIHW_SET(ST_ESCC); printk("ST_ESCC "); } - if (hwreg_present(&tt_scu.sys_mask)) { + if (MACH_IS_HADES) { + ATARIHW_SET(VME); + printk("VME "); + } else if (hwreg_present(&tt_scu.sys_mask)) { ATARIHW_SET(SCU); /* Assume a VME bus if there's a SCU */ ATARIHW_SET(VME); @@ -332,7 +340,7 @@ void __init config_atari(void) ATARIHW_SET(ANALOG_JOY); printk("ANALOG_JOY "); } - if (hwreg_present(blitter.halftone)) { + if (!MACH_IS_HADES && hwreg_present(blitter.halftone)) { ATARIHW_SET(BLITTER); printk("BLITTER "); } @@ -341,7 +349,8 @@ void __init config_atari(void) printk("IDE "); } #if 1 /* This maybe wrong */ - if (!MACH_IS_MEDUSA && hwreg_present(&tt_microwire.data) && + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present(&tt_microwire.data) && hwreg_present(&tt_microwire.mask) && (tt_microwire.mask = 0x7ff, udelay(1), @@ -360,18 +369,19 @@ void __init config_atari(void) mach_hwclk = atari_tt_hwclk; mach_set_clock_mmss = atari_tt_set_clock_mmss; } - if (hwreg_present(&mste_rtc.sec_ones)) { + if (!MACH_IS_HADES && hwreg_present(&mste_rtc.sec_ones)) { ATARIHW_SET(MSTE_CLK); printk("MSTE_CLK "); mach_hwclk = atari_mste_hwclk; mach_set_clock_mmss = atari_mste_set_clock_mmss; } - if (!MACH_IS_MEDUSA && hwreg_present(&dma_wd.fdc_speed) && + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present(&dma_wd.fdc_speed) && hwreg_write(&dma_wd.fdc_speed, 0)) { ATARIHW_SET(FDCSPEED); printk("FDC_SPEED "); } - if (!ATARIHW_PRESENT(ST_SCSI)) { + if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) { ATARIHW_SET(ACSI); printk("ACSI "); } @@ -439,7 +449,7 @@ void __init config_atari(void) * 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible * in the last 16MB of the address space. */ - tos_version = (MACH_IS_MEDUSA) ? + tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ? 0xfff : *(unsigned short *)0xff000002; atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68; } @@ -501,7 +511,8 @@ static void atari_reset(void) * On the Medusa, phys. 0x4 may contain garbage because it's no * ROM. See above for explanation why we cannot use PTOV(4). */ - reset_addr = MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 : + reset_addr = MACH_IS_HADES ? 0x7fe00030 : + MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 : *(unsigned long *) 0xff000004; /* reset ACIA for switch off OverScan, if it's active */ @@ -595,6 +606,8 @@ static void atari_get_model(char *model) if (MACH_IS_MEDUSA) /* Medusa has TT _MCH cookie */ strcat(model, "Medusa"); + else if (MACH_IS_HADES) + strcat(model, "Hades"); else strcat(model, "TT"); break; diff --git a/trunk/arch/m68k/atari/hades-pci.c b/trunk/arch/m68k/atari/hades-pci.c new file mode 100644 index 000000000000..2bbabc008708 --- /dev/null +++ b/trunk/arch/m68k/atari/hades-pci.c @@ -0,0 +1,440 @@ +/* + * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone. + * + * Written by Wout Klaren. + */ + +#include +#include +#include + +#if 0 +# define DBG_DEVS(args) printk args +#else +# define DBG_DEVS(args) +#endif + +#if defined(CONFIG_PCI) && defined(CONFIG_HADES) + +#include +#include +#include + +#include +#include +#include +#include + +#define HADES_MEM_BASE 0x80000000 +#define HADES_MEM_SIZE 0x20000000 +#define HADES_CONFIG_BASE 0xA0000000 +#define HADES_CONFIG_SIZE 0x10000000 +#define HADES_IO_BASE 0xB0000000 +#define HADES_IO_SIZE 0x10000000 +#define HADES_VIRT_IO_SIZE 0x00010000 /* Only 64k is remapped and actually used. */ + +#define N_SLOTS 4 /* Number of PCI slots. */ + +static const char pci_mem_name[] = "PCI memory space"; +static const char pci_io_name[] = "PCI I/O space"; +static const char pci_config_name[] = "PCI config space"; + +static struct resource config_space = { + .name = pci_config_name, + .start = HADES_CONFIG_BASE, + .end = HADES_CONFIG_BASE + HADES_CONFIG_SIZE - 1 +}; +static struct resource io_space = { + .name = pci_io_name, + .start = HADES_IO_BASE, + .end = HADES_IO_BASE + HADES_IO_SIZE - 1 +}; + +static const unsigned long pci_conf_base_phys[] = { + 0xA0080000, 0xA0040000, 0xA0020000, 0xA0010000 +}; +static unsigned long pci_conf_base_virt[N_SLOTS]; +static unsigned long pci_io_base_virt; + +/* + * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn, + * unsigned char where) + * + * Calculate the address of the PCI configuration area of the given + * device. + * + * BUG: boards with multiple functions are probably not correctly + * supported. + */ + +static void *mk_conf_addr(struct pci_dev *dev, int where) +{ + int device = dev->devfn >> 3, function = dev->devfn & 7; + void *result; + + DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n", + dev->bus->number, dev->devfn, where, pci_addr)); + + if (device > 3) + { + DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device)); + return NULL; + } + + if (dev->bus->number != 0) + { + DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device)); + return NULL; + } + + result = (void *) (pci_conf_base_virt[device] | (function << 8) | (where)); + DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result)); + return result; +} + +static int hades_read_config_byte(struct pci_dev *dev, int where, u8 *value) +{ + volatile unsigned char *pci_addr; + + *value = 0xff; + + if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = *pci_addr; + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_read_config_word(struct pci_dev *dev, int where, u16 *value) +{ + volatile unsigned short *pci_addr; + + *value = 0xffff; + + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = le16_to_cpu(*pci_addr); + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_read_config_dword(struct pci_dev *dev, int where, u32 *value) +{ + volatile unsigned int *pci_addr; + unsigned char header_type; + int result; + + *value = 0xffffffff; + + if (where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = le32_to_cpu(*pci_addr); + + /* + * Check if the value is an address on the bus. If true, add the + * base address of the PCI memory or PCI I/O area on the Hades. + */ + + if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE, + &header_type)) != PCIBIOS_SUCCESSFUL) + return result; + + if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || + ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && + (where <= PCI_BASE_ADDRESS_5)))) + { + if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * Base address register that contains an I/O address. If the + * address is valid on the Hades (0 <= *value < HADES_VIRT_IO_SIZE), + * add 'pci_io_base_virt' to the value. + */ + + if (*value < HADES_VIRT_IO_SIZE) + *value += pci_io_base_virt; + } + else + { + /* + * Base address register that contains an memory address. If the + * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE), + * add HADES_MEM_BASE to the value. + */ + + if (*value == 0) + { + /* + * Base address is 0. Test if this base + * address register is used. + */ + + *pci_addr = 0xffffffff; + if (*pci_addr != 0) + { + *pci_addr = *value; + if (*value < HADES_MEM_SIZE) + *value += HADES_MEM_BASE; + } + } + else + { + if (*value < HADES_MEM_SIZE) + *value += HADES_MEM_BASE; + } + } + } + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_byte(struct pci_dev *dev, int where, u8 value) +{ + volatile unsigned char *pci_addr; + + if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *pci_addr = value; + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_word(struct pci_dev *dev, int where, u16 value) +{ + volatile unsigned short *pci_addr; + + if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *pci_addr = cpu_to_le16(value); + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_dword(struct pci_dev *dev, int where, u32 value) +{ + volatile unsigned int *pci_addr; + unsigned char header_type; + int result; + + if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* + * Check if the value is an address on the bus. If true, subtract the + * base address of the PCI memory or PCI I/O area on the Hades. + */ + + if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE, + &header_type)) != PCIBIOS_SUCCESSFUL) + return result; + + if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || + ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && + (where <= PCI_BASE_ADDRESS_5)))) + { + if ((value & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * I/O address. Check if the address is valid address on + * the Hades (pci_io_base_virt <= value < pci_io_base_virt + + * HADES_VIRT_IO_SIZE) or if the value is 0xffffffff. If not + * true do not write the base address register. If it is a + * valid base address subtract 'pci_io_base_virt' from the value. + */ + + if ((value >= pci_io_base_virt) && (value < (pci_io_base_virt + + HADES_VIRT_IO_SIZE))) + value -= pci_io_base_virt; + else + { + if (value != 0xffffffff) + return PCIBIOS_SET_FAILED; + } + } + else + { + /* + * Memory address. Check if the address is valid address on + * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or + * if the value is 0xffffffff. If not true do not write + * the base address register. If it is a valid base address + * subtract HADES_MEM_BASE from the value. + */ + + if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE))) + value -= HADES_MEM_BASE; + else + { + if (value != 0xffffffff) + return PCIBIOS_SET_FAILED; + } + } + } + + *pci_addr = cpu_to_le32(value); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * static inline void hades_fixup(void) + * + * Assign IRQ numbers as used by Linux to the interrupt pins + * of the PCI cards. + */ + +static void __init hades_fixup(int pci_modify) +{ + char irq_tab[4] = { + [0] = IRQ_TT_MFP_IO0, /* Slot 0. */ + [1] = IRQ_TT_MFP_IO1, /* Slot 1. */ + [2] = IRQ_TT_MFP_SCC, /* Slot 2. */ + [3] = IRQ_TT_MFP_SCSIDMA /* Slot 3. */ + }; + struct pci_dev *dev = NULL; + unsigned char slot; + + /* + * Go through all devices, fixing up irqs as we see fit: + */ + + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + { + if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) + { + slot = PCI_SLOT(dev->devfn); /* Determine slot number. */ + dev->irq = irq_tab[slot]; + if (pci_modify) + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } + } +} + +/* + * static void hades_conf_device(struct pci_dev *dev) + * + * Machine dependent Configure the given device. + * + * Parameters: + * + * dev - the pci device. + */ + +static void __init hades_conf_device(struct pci_dev *dev) +{ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0); +} + +static struct pci_ops hades_pci_ops = { + .read_byte = hades_read_config_byte, + .read_word = hades_read_config_word, + .read_dword = hades_read_config_dword, + .write_byte = hades_write_config_byte, + .write_word = hades_write_config_word, + .write_dword = hades_write_config_dword +}; + +/* + * struct pci_bus_info *init_hades_pci(void) + * + * Machine specific initialisation: + * + * - Allocate and initialise a 'pci_bus_info' structure + * - Initialise hardware + * + * Result: pointer to 'pci_bus_info' structure. + */ + +struct pci_bus_info * __init init_hades_pci(void) +{ + struct pci_bus_info *bus; + int i; + + /* + * Remap I/O and configuration space. + */ + + pci_io_base_virt = (unsigned long) ioremap(HADES_IO_BASE, HADES_VIRT_IO_SIZE); + + for (i = 0; i < N_SLOTS; i++) + pci_conf_base_virt[i] = (unsigned long) ioremap(pci_conf_base_phys[i], 0x10000); + + /* + * Allocate memory for bus info structure. + */ + + bus = kzalloc(sizeof(struct pci_bus_info), GFP_KERNEL); + if (unlikely(!bus)) + goto iounmap_base_virt; + + /* + * Claim resources. The m68k has no separate I/O space, both + * PCI memory space and PCI I/O space are in memory space. Therefore + * the I/O resources are requested in memory space as well. + */ + + if (unlikely(request_resource(&iomem_resource, &config_space) != 0)) + goto free_bus; + + if (unlikely(request_resource(&iomem_resource, &io_space) != 0)) + goto release_config_space; + + bus->mem_space.start = HADES_MEM_BASE; + bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1; + bus->mem_space.name = pci_mem_name; +#if 1 + if (unlikely(request_resource(&iomem_resource, &bus->mem_space) != 0)) + goto release_io_space; +#endif + bus->io_space.start = pci_io_base_virt; + bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1; + bus->io_space.name = pci_io_name; +#if 1 + if (unlikely(request_resource(&ioport_resource, &bus->io_space) != 0)) + goto release_bus_mem_space; +#endif + /* + * Set hardware dependent functions. + */ + + bus->m68k_pci_ops = &hades_pci_ops; + bus->fixup = hades_fixup; + bus->conf_device = hades_conf_device; + + /* + * Select high to low edge for PCI interrupts. + */ + + tt_mfp.active_edge &= ~0x27; + + return bus; + +release_bus_mem_space: + release_resource(&bus->mem_space); +release_io_space: + release_resource(&io_space); +release_config_space: + release_resource(&config_space); +free_bus: + kfree(bus); +iounmap_base_virt: + iounmap((void *)pci_io_base_virt); + + for (i = 0; i < N_SLOTS; i++) + iounmap((void *)pci_conf_base_virt[i]); + + return NULL; +} +#endif diff --git a/trunk/arch/m68k/atari/time.c b/trunk/arch/m68k/atari/time.c index 1edde27fa32d..e0d3c8bfb408 100644 --- a/trunk/arch/m68k/atari/time.c +++ b/trunk/arch/m68k/atari/time.c @@ -20,9 +20,6 @@ #include -DEFINE_SPINLOCK(rtc_lock); -EXPORT_SYMBOL_GPL(rtc_lock); - void __init atari_sched_init(irq_handler_t timer_routine) { @@ -194,14 +191,13 @@ int atari_tt_hwclk( int op, struct rtc_time *t ) } if (!(ctrl & RTC_DM_BINARY)) { - sec = bin2bcd(sec); - min = bin2bcd(min); - hour = bin2bcd(hour); - day = bin2bcd(day); - mon = bin2bcd(mon); - year = bin2bcd(year); - if (wday >= 0) - wday = bin2bcd(wday); + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hour); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(year); + if (wday >= 0) BIN_TO_BCD(wday); } } @@ -256,13 +252,13 @@ int atari_tt_hwclk( int op, struct rtc_time *t ) } if (!(ctrl & RTC_DM_BINARY)) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); - wday = bcd2bin(wday); + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + BCD_TO_BIN(wday); } if (!(ctrl & RTC_24H)) { @@ -322,7 +318,7 @@ int atari_tt_set_clock_mmss (unsigned long nowtime) rtc_minutes = RTC_READ (RTC_MINUTES); if (!(save_control & RTC_DM_BINARY)) - rtc_minutes = bcd2bin(rtc_minutes); + BCD_TO_BIN (rtc_minutes); /* Since we're only adjusting minutes and seconds, don't interfere with hour overflow. This avoids messing with unknown time zones @@ -333,8 +329,8 @@ int atari_tt_set_clock_mmss (unsigned long nowtime) { if (!(save_control & RTC_DM_BINARY)) { - real_seconds = bin2bcd(real_seconds); - real_minutes = bin2bcd(real_minutes); + BIN_TO_BCD (real_seconds); + BIN_TO_BCD (real_minutes); } RTC_WRITE (RTC_SECONDS, real_seconds); RTC_WRITE (RTC_MINUTES, real_minutes); diff --git a/trunk/arch/m68k/bvme6000/config.c b/trunk/arch/m68k/bvme6000/config.c index 65c9204ab9ac..9433a88a33c4 100644 --- a/trunk/arch/m68k/bvme6000/config.c +++ b/trunk/arch/m68k/bvme6000/config.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,9 @@ extern void bvme6000_reset (void); extern void bvme6000_waitbut(void); void bvme6000_set_vectors (void); +static unsigned char bcd2bin (unsigned char b); +static unsigned char bin2bcd (unsigned char b); + /* Save tick handler routine pointer, will point to do_timer() in * kernel/sched.c, called via bvme6000_process_int() */ @@ -262,6 +264,17 @@ unsigned long bvme6000_gettimeoffset (void) return v; } +static unsigned char bcd2bin (unsigned char b) +{ + return ((b>>4)*10 + (b&15)); +} + +static unsigned char bin2bcd (unsigned char b) +{ + return (((b/10)*16) + (b%10)); +} + + /* * Looks like op is non-zero for setting the clock, and zero for * reading the clock. diff --git a/trunk/arch/m68k/bvme6000/rtc.c b/trunk/arch/m68k/bvme6000/rtc.c index 808c9018b115..e8ac3f7d72df 100644 --- a/trunk/arch/m68k/bvme6000/rtc.c +++ b/trunk/arch/m68k/bvme6000/rtc.c @@ -57,16 +57,16 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, rtc->msr = 0x40; memset(&wtime, 0, sizeof(struct rtc_time)); do { - wtime.tm_sec = bcd2bin(rtc->bcd_sec); - wtime.tm_min = bcd2bin(rtc->bcd_min); - wtime.tm_hour = bcd2bin(rtc->bcd_hr); - wtime.tm_mday = bcd2bin(rtc->bcd_dom); - wtime.tm_mon = bcd2bin(rtc->bcd_mth)-1; - wtime.tm_year = bcd2bin(rtc->bcd_year); + wtime.tm_sec = BCD2BIN(rtc->bcd_sec); + wtime.tm_min = BCD2BIN(rtc->bcd_min); + wtime.tm_hour = BCD2BIN(rtc->bcd_hr); + wtime.tm_mday = BCD2BIN(rtc->bcd_dom); + wtime.tm_mon = BCD2BIN(rtc->bcd_mth)-1; + wtime.tm_year = BCD2BIN(rtc->bcd_year); if (wtime.tm_year < 70) wtime.tm_year += 100; - wtime.tm_wday = bcd2bin(rtc->bcd_dow)-1; - } while (wtime.tm_sec != bcd2bin(rtc->bcd_sec)); + wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1; + } while (wtime.tm_sec != BCD2BIN(rtc->bcd_sec)); rtc->msr = msr; local_irq_restore(flags); return copy_to_user(argp, &wtime, sizeof wtime) ? @@ -114,14 +114,14 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, rtc->t0cr_rtmr = yrs%4; rtc->bcd_tenms = 0; - rtc->bcd_sec = bin2bcd(sec); - rtc->bcd_min = bin2bcd(min); - rtc->bcd_hr = bin2bcd(hrs); - rtc->bcd_dom = bin2bcd(day); - rtc->bcd_mth = bin2bcd(mon); - rtc->bcd_year = bin2bcd(yrs%100); + rtc->bcd_sec = BIN2BCD(sec); + rtc->bcd_min = BIN2BCD(min); + rtc->bcd_hr = BIN2BCD(hrs); + rtc->bcd_dom = BIN2BCD(day); + rtc->bcd_mth = BIN2BCD(mon); + rtc->bcd_year = BIN2BCD(yrs%100); if (rtc_tm.tm_wday >= 0) - rtc->bcd_dow = bin2bcd(rtc_tm.tm_wday+1); + rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1); rtc->t0cr_rtmr = yrs%4 | 0x08; rtc->msr = msr; diff --git a/trunk/arch/m68k/kernel/Makefile b/trunk/arch/m68k/kernel/Makefile index 55d5d6b680a2..3a7f62225504 100644 --- a/trunk/arch/m68k/kernel/Makefile +++ b/trunk/arch/m68k/kernel/Makefile @@ -14,4 +14,5 @@ obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ devres-y = ../../../kernel/irq/devres.o +obj-$(CONFIG_PCI) += bios32.o obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo diff --git a/trunk/arch/m68k/kernel/bios32.c b/trunk/arch/m68k/kernel/bios32.c new file mode 100644 index 000000000000..af170c2be735 --- /dev/null +++ b/trunk/arch/m68k/kernel/bios32.c @@ -0,0 +1,514 @@ +/* + * bios32.c - PCI BIOS functions for m68k systems. + * + * Written by Wout Klaren. + * + * Based on the DEC Alpha bios32.c by Dave Rusling and David Mosberger. + */ + +#include +#include + +#if 0 +# define DBG_DEVS(args) printk args +#else +# define DBG_DEVS(args) +#endif + +#ifdef CONFIG_PCI + +/* + * PCI support for Linux/m68k. Currently only the Hades is supported. + * + * The support for PCI bridges in the DEC Alpha version has + * been removed in this version. + */ + +#include +#include +#include + +#include +#include +#include + +#define KB 1024 +#define MB (1024*KB) +#define GB (1024*MB) + +#define MAJOR_REV 0 +#define MINOR_REV 5 + +/* + * Align VAL to ALIGN, which must be a power of two. + */ + +#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) + +/* + * Offsets relative to the I/O and memory base addresses from where resources + * are allocated. + */ + +#define IO_ALLOC_OFFSET 0x00004000 +#define MEM_ALLOC_OFFSET 0x04000000 + +/* + * Declarations of hardware specific initialisation functions. + */ + +extern struct pci_bus_info *init_hades_pci(void); + +/* + * Bus info structure of the PCI bus. A pointer to this structure is + * put in the sysdata member of the pci_bus structure. + */ + +static struct pci_bus_info *bus_info; + +static int pci_modify = 1; /* If set, layout the PCI bus ourself. */ +static int skip_vga; /* If set do not modify base addresses + of vga cards.*/ +static int disable_pci_burst; /* If set do not allow PCI bursts. */ + +static unsigned int io_base; +static unsigned int mem_base; + +/* + * static void disable_dev(struct pci_dev *dev) + * + * Disable PCI device DEV so that it does not respond to I/O or memory + * accesses. + * + * Parameters: + * + * dev - device to disable. + */ + +static void __init disable_dev(struct pci_dev *dev) +{ + unsigned short cmd; + + if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) + return; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + + cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER); + pci_write_config_word(dev, PCI_COMMAND, cmd); +} + +/* + * static void layout_dev(struct pci_dev *dev) + * + * Layout memory and I/O for a device. + * + * Parameters: + * + * device - device to layout memory and I/O for. + */ + +static void __init layout_dev(struct pci_dev *dev) +{ + unsigned short cmd; + unsigned int base, mask, size, reg; + unsigned int alignto; + int i; + + /* + * Skip video cards if requested. + */ + + if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) + return; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + + for (reg = PCI_BASE_ADDRESS_0, i = 0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++) + { + /* + * Figure out how much space and of what type this + * device wants. + */ + + pci_write_config_dword(dev, reg, 0xffffffff); + pci_read_config_dword(dev, reg, &base); + + if (!base) + { + /* this base-address register is unused */ + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + continue; + } + + /* + * We've read the base address register back after + * writing all ones and so now we must decode it. + */ + + if (base & PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * I/O space base address register. + */ + + cmd |= PCI_COMMAND_IO; + + base &= PCI_BASE_ADDRESS_IO_MASK; + mask = (~base << 1) | 0x1; + size = (mask & base) & 0xffffffff; + + /* + * Align to multiple of size of minimum base. + */ + + alignto = max_t(unsigned int, 0x040, size); + base = ALIGN(io_base, alignto); + io_base = base + size; + pci_write_config_dword(dev, reg, base | PCI_BASE_ADDRESS_SPACE_IO); + + dev->resource[i].start = base; + dev->resource[i].end = dev->resource[i].start + size - 1; + dev->resource[i].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; + + DBG_DEVS(("layout_dev: IO address: %lX\n", base)); + } + else + { + unsigned int type; + + /* + * Memory space base address register. + */ + + cmd |= PCI_COMMAND_MEMORY; + type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK; + base &= PCI_BASE_ADDRESS_MEM_MASK; + mask = (~base << 1) | 0x1; + size = (mask & base) & 0xffffffff; + switch (type) + { + case PCI_BASE_ADDRESS_MEM_TYPE_32: + case PCI_BASE_ADDRESS_MEM_TYPE_64: + break; + + case PCI_BASE_ADDRESS_MEM_TYPE_1M: + printk("bios32 WARNING: slot %d, function %d " + "requests memory below 1MB---don't " + "know how to do that.\n", + PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + continue; + } + + /* + * Align to multiple of size of minimum base. + */ + + alignto = max_t(unsigned int, 0x1000, size); + base = ALIGN(mem_base, alignto); + mem_base = base + size; + pci_write_config_dword(dev, reg, base); + + dev->resource[i].start = base; + dev->resource[i].end = dev->resource[i].start + size - 1; + dev->resource[i].flags = IORESOURCE_MEM; + + if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) + { + /* + * 64-bit address, set the highest 32 bits + * to zero. + */ + + reg += 4; + pci_write_config_dword(dev, reg, 0); + + i++; + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } + } + + /* + * Enable device: + */ + + if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED || + dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA || + dev->class >> 8 == PCI_CLASS_DISPLAY_VGA || + dev->class >> 8 == PCI_CLASS_DISPLAY_XGA) + { + /* + * All of these (may) have I/O scattered all around + * and may not use i/o-base address registers at all. + * So we just have to always enable I/O to these + * devices. + */ + cmd |= PCI_COMMAND_IO; + } + + pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); + + pci_write_config_byte(dev, PCI_LATENCY_TIMER, (disable_pci_burst) ? 0 : 32); + + if (bus_info != NULL) + bus_info->conf_device(dev); /* Machine dependent configuration. */ + + DBG_DEVS(("layout_dev: bus %d slot 0x%x VID 0x%x DID 0x%x class 0x%x\n", + dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class)); +} + +/* + * static void layout_bus(struct pci_bus *bus) + * + * Layout memory and I/O for all devices on the given bus. + * + * Parameters: + * + * bus - bus. + */ + +static void __init layout_bus(struct pci_bus *bus) +{ + unsigned int bio, bmem; + struct pci_dev *dev; + + DBG_DEVS(("layout_bus: starting bus %d\n", bus->number)); + + if (!bus->devices && !bus->children) + return; + + /* + * Align the current bases on appropriate boundaries (4K for + * IO and 1MB for memory). + */ + + bio = io_base = ALIGN(io_base, 4*KB); + bmem = mem_base = ALIGN(mem_base, 1*MB); + + /* + * PCI devices might have been setup by a PCI BIOS emulation + * running under TOS. In these cases there is a + * window during which two devices may have an overlapping + * address range. To avoid this causing trouble, we first + * turn off the I/O and memory address decoders for all PCI + * devices. They'll be re-enabled only once all address + * decoders are programmed consistently. + */ + + DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number)); + + for (dev = bus->devices; dev; dev = dev->sibling) + { + if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || + (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) + disable_dev(dev); + } + + /* + * Allocate space to each device: + */ + + DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number)); + + for (dev = bus->devices; dev; dev = dev->sibling) + { + if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || + (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) + layout_dev(dev); + } + + DBG_DEVS(("layout_bus: bus %d finished\n", bus->number)); +} + +/* + * static void pcibios_fixup(void) + * + * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is + * true. This might be necessary because not every m68k machine with a PCI + * bus has a PCI BIOS. This function should be called right after + * pci_scan_bus() in pcibios_init(). + */ + +static void __init pcibios_fixup(void) +{ + if (pci_modify) + { + /* + * Set base addresses for allocation of I/O and memory space. + */ + + io_base = bus_info->io_space.start + IO_ALLOC_OFFSET; + mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET; + + /* + * Scan the tree, allocating PCI memory and I/O space. + */ + + layout_bus(pci_bus_b(pci_root.next)); + } + + /* + * Fix interrupt assignments, etc. + */ + + bus_info->fixup(pci_modify); +} + +/* + * static void pcibios_claim_resources(struct pci_bus *bus) + * + * Claim all resources that are assigned to devices on the given bus. + * + * Parameters: + * + * bus - bus. + */ + +static void __init pcibios_claim_resources(struct pci_bus *bus) +{ + struct pci_dev *dev; + int i; + + while (bus) + { + for (dev = bus->devices; (dev != NULL); dev = dev->sibling) + { + for (i = 0; i < PCI_NUM_RESOURCES; i++) + { + struct resource *r = &dev->resource[i]; + struct resource *pr; + struct pci_bus_info *bus_info = (struct pci_bus_info *) dev->sysdata; + + if ((r->start == 0) || (r->parent != NULL)) + continue; +#if 1 + if (r->flags & IORESOURCE_IO) + pr = &bus_info->io_space; + else + pr = &bus_info->mem_space; +#else + if (r->flags & IORESOURCE_IO) + pr = &ioport_resource; + else + pr = &iomem_resource; +#endif + if (request_resource(pr, r) < 0) + { + printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", i, dev->name); + } + } + } + + if (bus->children) + pcibios_claim_resources(bus->children); + + bus = bus->next; + } +} + +/* + * int pcibios_assign_resource(struct pci_dev *dev, int i) + * + * Assign a new address to a PCI resource. + * + * Parameters: + * + * dev - device. + * i - resource. + * + * Result: 0 if successful. + */ + +int __init pcibios_assign_resource(struct pci_dev *dev, int i) +{ + struct resource *r = &dev->resource[i]; + struct resource *pr = pci_find_parent_resource(dev, r); + unsigned long size = r->end + 1; + + if (!pr) + return -EINVAL; + + if (r->flags & IORESOURCE_IO) + { + if (size > 0x100) + return -EFBIG; + + if (allocate_resource(pr, r, size, bus_info->io_space.start + + IO_ALLOC_OFFSET, bus_info->io_space.end, 1024)) + return -EBUSY; + } + else + { + if (allocate_resource(pr, r, size, bus_info->mem_space.start + + MEM_ALLOC_OFFSET, bus_info->mem_space.end, size)) + return -EBUSY; + } + + if (i < 6) + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, r->start); + + return 0; +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev; + void *sysdata; + + sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata; + + for (dev = bus->devices; (dev != NULL); dev = dev->sibling) + dev->sysdata = sysdata; +} + +void __init pcibios_init(void) +{ + printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV); + + bus_info = NULL; +#ifdef CONFIG_HADES + if (MACH_IS_HADES) + bus_info = init_hades_pci(); +#endif + if (bus_info != NULL) + { + printk("PCI: Probing PCI hardware\n"); + pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info); + pcibios_fixup(); + pcibios_claim_resources(pci_root); + } + else + printk("PCI: No PCI bus detected\n"); +} + +char * __init pcibios_setup(char *str) +{ + if (!strcmp(str, "nomodify")) + { + pci_modify = 0; + return NULL; + } + else if (!strcmp(str, "skipvga")) + { + skip_vga = 1; + return NULL; + } + else if (!strcmp(str, "noburst")) + { + disable_pci_burst = 1; + return NULL; + } + + return str; +} +#endif /* CONFIG_PCI */ diff --git a/trunk/arch/m68k/kernel/dma.c b/trunk/arch/m68k/kernel/dma.c index 2bb4245404d8..6f8c080dd9f9 100644 --- a/trunk/arch/m68k/kernel/dma.c +++ b/trunk/arch/m68k/kernel/dma.c @@ -66,8 +66,8 @@ void dma_free_coherent(struct device *dev, size_t size, } EXPORT_SYMBOL(dma_free_coherent); -void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, - size_t size, enum dma_data_direction dir) +inline void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: diff --git a/trunk/arch/m68k/kernel/ints.c b/trunk/arch/m68k/kernel/ints.c index 7e8a0d394e61..ded7dd2f67b2 100644 --- a/trunk/arch/m68k/kernel/ints.c +++ b/trunk/arch/m68k/kernel/ints.c @@ -429,9 +429,8 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } -#ifdef CONFIG_PROC_FS void init_irq_proc(void) { /* Insert /proc/irq driver here */ } -#endif + diff --git a/trunk/arch/m68k/kernel/process.c b/trunk/arch/m68k/kernel/process.c index 3042c2bc8c58..7888cdf91f5d 100644 --- a/trunk/arch/m68k/kernel/process.c +++ b/trunk/arch/m68k/kernel/process.c @@ -78,7 +78,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) static void default_idle(void) { if (!need_resched()) -#if defined(MACH_ATARI_ONLY) +#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES) /* block out HSYNC on the atari (falcon) */ __asm__("stop #0x2200" : : : "cc"); #else diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index 6d813de2baf1..75b8340b254b 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -883,7 +883,8 @@ void show_trace(unsigned long *stack) if (i % 5 == 0) printk("\n "); #endif - printk(" [<%08lx>] %pS\n", addr, (void *)addr); + printk(" [<%08lx>]", addr); + print_symbol(" %s\n", addr); i++; } } @@ -899,8 +900,10 @@ void show_registers(struct pt_regs *regs) int i; print_modules(); - printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc); - printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2); + printk("PC: [<%08lx>]",regs->pc); + print_symbol(" %s", regs->pc); + printk("\nSR: %04x SP: %p a2: %08lx\n", + regs->sr, regs, regs->a2); printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", regs->d0, regs->d1, regs->d2, regs->d3); printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", diff --git a/trunk/arch/m68k/kernel/vmlinux-std.lds b/trunk/arch/m68k/kernel/vmlinux-std.lds index f846d4e3e5e1..99b0784c0552 100644 --- a/trunk/arch/m68k/kernel/vmlinux-std.lds +++ b/trunk/arch/m68k/kernel/vmlinux-std.lds @@ -34,11 +34,11 @@ SECTIONS CONSTRUCTORS } - . = ALIGN(16); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - .bss : { *(.bss) } /* BSS */ + . = ALIGN(16); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } :data + _edata = .; /* End of data section */ /* will be freed after init */ @@ -48,7 +48,7 @@ SECTIONS _sinittext = .; INIT_TEXT _einittext = .; - } :data + } .init.data : { INIT_DATA } . = ALIGN(16); __setup_start = .; @@ -74,7 +74,6 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - NOTES . = ALIGN(8192); __init_end = .; diff --git a/trunk/arch/m68k/mm/kmap.c b/trunk/arch/m68k/mm/kmap.c index df620ac2a296..46b7d6035aab 100644 --- a/trunk/arch/m68k/mm/kmap.c +++ b/trunk/arch/m68k/mm/kmap.c @@ -66,10 +66,8 @@ static struct vm_struct *get_io_area(unsigned long size) for (p = &iolist; (tmp = *p) ; p = &tmp->next) { if (size + addr < (unsigned long)tmp->addr) break; - if (addr > KMAP_END-size) { - kfree(area); + if (addr > KMAP_END-size) return NULL; - } addr = tmp->size + (unsigned long)tmp->addr; } area->addr = (void *)addr; diff --git a/trunk/arch/m68k/mvme16x/rtc.c b/trunk/arch/m68k/mvme16x/rtc.c index cea5e3e4e636..432a9f13b2ed 100644 --- a/trunk/arch/m68k/mvme16x/rtc.c +++ b/trunk/arch/m68k/mvme16x/rtc.c @@ -52,15 +52,15 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, /* Ensure clock and real-time-mode-register are accessible */ rtc->ctrl = RTC_READ; memset(&wtime, 0, sizeof(struct rtc_time)); - wtime.tm_sec = bcd2bin(rtc->bcd_sec); - wtime.tm_min = bcd2bin(rtc->bcd_min); - wtime.tm_hour = bcd2bin(rtc->bcd_hr); - wtime.tm_mday = bcd2bin(rtc->bcd_dom); - wtime.tm_mon = bcd2bin(rtc->bcd_mth)-1; - wtime.tm_year = bcd2bin(rtc->bcd_year); + wtime.tm_sec = BCD2BIN(rtc->bcd_sec); + wtime.tm_min = BCD2BIN(rtc->bcd_min); + wtime.tm_hour = BCD2BIN(rtc->bcd_hr); + wtime.tm_mday = BCD2BIN(rtc->bcd_dom); + wtime.tm_mon = BCD2BIN(rtc->bcd_mth)-1; + wtime.tm_year = BCD2BIN(rtc->bcd_year); if (wtime.tm_year < 70) wtime.tm_year += 100; - wtime.tm_wday = bcd2bin(rtc->bcd_dow)-1; + wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1; rtc->ctrl = 0; local_irq_restore(flags); return copy_to_user(argp, &wtime, sizeof wtime) ? @@ -104,12 +104,12 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, local_irq_save(flags); rtc->ctrl = RTC_WRITE; - rtc->bcd_sec = bin2bcd(sec); - rtc->bcd_min = bin2bcd(min); - rtc->bcd_hr = bin2bcd(hrs); - rtc->bcd_dom = bin2bcd(day); - rtc->bcd_mth = bin2bcd(mon); - rtc->bcd_year = bin2bcd(yrs%100); + rtc->bcd_sec = BIN2BCD(sec); + rtc->bcd_min = BIN2BCD(min); + rtc->bcd_hr = BIN2BCD(hrs); + rtc->bcd_dom = BIN2BCD(day); + rtc->bcd_mth = BIN2BCD(mon); + rtc->bcd_year = BIN2BCD(yrs%100); rtc->ctrl = 0; local_irq_restore(flags); diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c index 9c7eefa3f98a..be9de2f3dc48 100644 --- a/trunk/arch/m68k/q40/config.c +++ b/trunk/arch/m68k/q40/config.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -217,6 +216,17 @@ int q40_parse_bootinfo(const struct bi_record *rec) } +static inline unsigned char bcd2bin(unsigned char b) +{ + return (b >> 4) * 10 + (b & 15); +} + +static inline unsigned char bin2bcd(unsigned char b) +{ + return (b / 10) * 16 + (b % 10); +} + + static unsigned long q40_gettimeoffset(void) { return 5000 * (ql_ticks != 0); diff --git a/trunk/arch/m68k/sun3x/time.c b/trunk/arch/m68k/sun3x/time.c index 536a04aaf22f..f5eaafb00d21 100644 --- a/trunk/arch/m68k/sun3x/time.c +++ b/trunk/arch/m68k/sun3x/time.c @@ -47,23 +47,23 @@ int sun3x_hwclk(int set, struct rtc_time *t) if(set) { h->csr |= C_WRITE; - h->sec = bin2bcd(t->tm_sec); - h->min = bin2bcd(t->tm_min); - h->hour = bin2bcd(t->tm_hour); - h->wday = bin2bcd(t->tm_wday); - h->mday = bin2bcd(t->tm_mday); - h->month = bin2bcd(t->tm_mon); - h->year = bin2bcd(t->tm_year); + h->sec = BIN2BCD(t->tm_sec); + h->min = BIN2BCD(t->tm_min); + h->hour = BIN2BCD(t->tm_hour); + h->wday = BIN2BCD(t->tm_wday); + h->mday = BIN2BCD(t->tm_mday); + h->month = BIN2BCD(t->tm_mon); + h->year = BIN2BCD(t->tm_year); h->csr &= ~C_WRITE; } else { h->csr |= C_READ; - t->tm_sec = bcd2bin(h->sec); - t->tm_min = bcd2bin(h->min); - t->tm_hour = bcd2bin(h->hour); - t->tm_wday = bcd2bin(h->wday); - t->tm_mday = bcd2bin(h->mday); - t->tm_mon = bcd2bin(h->month); - t->tm_year = bcd2bin(h->year); + t->tm_sec = BCD2BIN(h->sec); + t->tm_min = BCD2BIN(h->min); + t->tm_hour = BCD2BIN(h->hour); + t->tm_wday = BCD2BIN(h->wday); + t->tm_mday = BCD2BIN(h->mday); + t->tm_mon = BCD2BIN(h->month); + t->tm_year = BCD2BIN(h->year); h->csr &= ~C_READ; } diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index 0a8998315e5e..2e7515e8db98 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -73,6 +73,9 @@ config GENERIC_CLOCKEVENTS config NO_IOPORT def_bool y +config ARCH_SUPPORTS_AOUT + def_bool y + source "init/Kconfig" menu "Processor type and features" diff --git a/trunk/arch/m68knommu/include/asm/a.out.h b/trunk/arch/m68knommu/include/asm/a.out.h new file mode 100644 index 000000000000..ce18ef99de04 --- /dev/null +++ b/trunk/arch/m68knommu/include/asm/a.out.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/m68knommu/include/asm/elf.h b/trunk/arch/m68knommu/include/asm/elf.h index b8046837f384..27f0ec70fba8 100644 --- a/trunk/arch/m68knommu/include/asm/elf.h +++ b/trunk/arch/m68knommu/include/asm/elf.h @@ -105,6 +105,6 @@ typedef struct user_m68kfp_struct elf_fpregset_t; #define ELF_PLATFORM (NULL) -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) #endif diff --git a/trunk/arch/m68knommu/kernel/process.c b/trunk/arch/m68knommu/kernel/process.c index 3f2d7745f31e..47502d5ec19f 100644 --- a/trunk/arch/m68knommu/kernel/process.c +++ b/trunk/arch/m68knommu/kernel/process.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m68knommu/kernel/traps.c b/trunk/arch/m68knommu/kernel/traps.c index 5d5d56bcd0ef..46f8f9d0c408 100644 --- a/trunk/arch/m68knommu/kernel/traps.c +++ b/trunk/arch/m68knommu/kernel/traps.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index b905744d7915..cd5fbf6f0784 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -52,7 +52,6 @@ config BCM47XX select SSB select SSB_DRIVER_MIPS select SSB_DRIVER_EXTIF - select SSB_EMBEDDED select SSB_PCICORE_HOSTMODE if PCI select GENERIC_GPIO select SYS_HAS_EARLY_PRINTK diff --git a/trunk/arch/mips/bcm47xx/gpio.c b/trunk/arch/mips/bcm47xx/gpio.c index 9b798800258c..f5a53acf995a 100644 --- a/trunk/arch/mips/bcm47xx/gpio.c +++ b/trunk/arch/mips/bcm47xx/gpio.c @@ -12,51 +12,68 @@ #include #include -#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES) -static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES); -#else -static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES); -#endif - -int gpio_request(unsigned gpio, const char *tag) +int bcm47xx_gpio_to_irq(unsigned gpio) { - if (ssb_chipco_available(&ssb_bcm47xx.chipco) && - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) - return -EINVAL; - - if (ssb_extif_available(&ssb_bcm47xx.extif) && - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) + if (ssb_bcm47xx.chipco.dev) + return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2; + else if (ssb_bcm47xx.extif.dev) + return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2; + else return -EINVAL; - - if (test_and_set_bit(gpio, gpio_in_use)) - return -EBUSY; - - return 0; } -EXPORT_SYMBOL(gpio_request); +EXPORT_SYMBOL_GPL(bcm47xx_gpio_to_irq); -void gpio_free(unsigned gpio) +int bcm47xx_gpio_get_value(unsigned gpio) { - if (ssb_chipco_available(&ssb_bcm47xx.chipco) && - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) - return; + if (ssb_bcm47xx.chipco.dev) + return ssb_chipco_gpio_in(&ssb_bcm47xx.chipco, 1 << gpio); + else if (ssb_bcm47xx.extif.dev) + return ssb_extif_gpio_in(&ssb_bcm47xx.extif, 1 << gpio); + else + return 0; +} +EXPORT_SYMBOL_GPL(bcm47xx_gpio_get_value); - if (ssb_extif_available(&ssb_bcm47xx.extif) && - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) - return; +void bcm47xx_gpio_set_value(unsigned gpio, int value) +{ + if (ssb_bcm47xx.chipco.dev) + ssb_chipco_gpio_out(&ssb_bcm47xx.chipco, + 1 << gpio, + value ? 1 << gpio : 0); + else if (ssb_bcm47xx.extif.dev) + ssb_extif_gpio_out(&ssb_bcm47xx.extif, + 1 << gpio, + value ? 1 << gpio : 0); +} +EXPORT_SYMBOL_GPL(bcm47xx_gpio_set_value); - clear_bit(gpio, gpio_in_use); +int bcm47xx_gpio_direction_input(unsigned gpio) +{ + if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES)) + ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco, + 1 << gpio, 0); + else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES)) + ssb_extif_gpio_outen(&ssb_bcm47xx.extif, + 1 << gpio, 0); + else + return -EINVAL; + return 0; } -EXPORT_SYMBOL(gpio_free); +EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_input); -int gpio_to_irq(unsigned gpio) +int bcm47xx_gpio_direction_output(unsigned gpio, int value) { - if (ssb_chipco_available(&ssb_bcm47xx.chipco)) - return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2; - else if (ssb_extif_available(&ssb_bcm47xx.extif)) - return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2; + bcm47xx_gpio_set_value(gpio, value); + + if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES)) + ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco, + 1 << gpio, 1 << gpio); + else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES)) + ssb_extif_gpio_outen(&ssb_bcm47xx.extif, + 1 << gpio, 1 << gpio); else return -EINVAL; + return 0; } -EXPORT_SYMBOL_GPL(gpio_to_irq); +EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_output); diff --git a/trunk/arch/mips/bcm47xx/setup.c b/trunk/arch/mips/bcm47xx/setup.c index 2f580fa160c9..8d36f186890e 100644 --- a/trunk/arch/mips/bcm47xx/setup.c +++ b/trunk/arch/mips/bcm47xx/setup.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -42,7 +41,7 @@ static void bcm47xx_machine_restart(char *command) printk(KERN_ALERT "Please stand by while rebooting the system...\n"); local_irq_disable(); /* Set the watchdog timer to reset immediately */ - ssb_watchdog_timer_set(&ssb_bcm47xx, 1); + ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 1); while (1) cpu_relax(); } @@ -51,7 +50,7 @@ static void bcm47xx_machine_halt(void) { /* Disable interrupts and watchdog and spin forever */ local_irq_disable(); - ssb_watchdog_timer_set(&ssb_bcm47xx, 0); + ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 0); while (1) cpu_relax(); } diff --git a/trunk/arch/mips/bcm47xx/wgt634u.c b/trunk/arch/mips/bcm47xx/wgt634u.c index ef00e7f58c24..d1d90c9ef2fa 100644 --- a/trunk/arch/mips/bcm47xx/wgt634u.c +++ b/trunk/arch/mips/bcm47xx/wgt634u.c @@ -11,9 +11,6 @@ #include #include #include -#include -#include -#include #include /* GPIO definitions for the WGT634U */ @@ -102,30 +99,6 @@ static struct platform_device *wgt634u_devices[] __initdata = { &wgt634u_gpio_leds, }; -static irqreturn_t gpio_interrupt(int irq, void *ignored) -{ - int state; - - /* Interrupts are shared, check if the current one is - a GPIO interrupt. */ - if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco, - SSB_CHIPCO_IRQ_GPIO)) - return IRQ_NONE; - - state = gpio_get_value(WGT634U_GPIO_RESET); - - /* Interrupt are level triggered, revert the interrupt polarity - to clear the interrupt. */ - gpio_polarity(WGT634U_GPIO_RESET, state); - - if (!state) { - printk(KERN_INFO "Reset button pressed"); - ctrl_alt_del(); - } - - return IRQ_HANDLED; -} - static int __init wgt634u_init(void) { /* There is no easy way to detect that we are running on a WGT634U @@ -139,19 +112,6 @@ static int __init wgt634u_init(void) ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) { struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; - - printk(KERN_INFO "WGT634U machine detected.\n"); - - if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET), - gpio_interrupt, IRQF_SHARED, - "WGT634U GPIO", &ssb_bcm47xx.chipco)) { - gpio_direction_input(WGT634U_GPIO_RESET); - gpio_intmask(WGT634U_GPIO_RESET, 1); - ssb_chipco_irq_mask(&ssb_bcm47xx.chipco, - SSB_CHIPCO_IRQ_GPIO, - SSB_CHIPCO_IRQ_GPIO); - } - wgt634u_flash_data.width = mcore->flash_buswidth; wgt634u_flash_resource.start = mcore->flash_window; wgt634u_flash_resource.end = mcore->flash_window diff --git a/trunk/arch/mips/emma2rh/common/irq.c b/trunk/arch/mips/emma2rh/common/irq.c index 91cbd959ab67..d95604773667 100644 --- a/trunk/arch/mips/emma2rh/common/irq.c +++ b/trunk/arch/mips/emma2rh/common/irq.c @@ -29,6 +29,7 @@ #include #include +#include #include #include diff --git a/trunk/arch/mips/emma2rh/common/prom.c b/trunk/arch/mips/emma2rh/common/prom.c index e14a2e3d8842..5e92b3a9c5b8 100644 --- a/trunk/arch/mips/emma2rh/common/prom.c +++ b/trunk/arch/mips/emma2rh/common/prom.c @@ -30,6 +30,7 @@ #include #include #include +#include const char *get_system_type(void) { diff --git a/trunk/arch/mips/emma2rh/markeins/platform.c b/trunk/arch/mips/emma2rh/markeins/platform.c index fb9cda253ab0..d70627de7cfe 100644 --- a/trunk/arch/mips/emma2rh/markeins/platform.c +++ b/trunk/arch/mips/emma2rh/markeins/platform.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/trunk/arch/mips/include/asm/a.out.h b/trunk/arch/mips/include/asm/a.out.h new file mode 100644 index 000000000000..cad8371422ab --- /dev/null +++ b/trunk/arch/mips/include/asm/a.out.h @@ -0,0 +1,35 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999, 2003 by Ralf Baechle + */ +#ifndef _ASM_A_OUT_H +#define _ASM_A_OUT_H + +#ifdef __KERNEL__ + + +#endif + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for + file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, + in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in + bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#endif /* _ASM_A_OUT_H */ diff --git a/trunk/arch/mips/include/asm/elf.h b/trunk/arch/mips/include/asm/elf.h index a8eac1697b3d..f69f7acba637 100644 --- a/trunk/arch/mips/include/asm/elf.h +++ b/trunk/arch/mips/include/asm/elf.h @@ -247,8 +247,10 @@ extern struct mips_abi mips_abi_n32; #ifdef CONFIG_32BIT -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY(ex, ibcs2) \ do { \ + if (ibcs2) \ + set_personality(PER_SVR4); \ set_personality(PER_LINUX); \ \ current->thread.abi = &mips_abi; \ @@ -294,7 +296,7 @@ do { \ #define __SET_PERSONALITY32(ex) do { } while (0) #endif -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY(ex, ibcs2) \ do { \ clear_thread_flag(TIF_32BIT_REGS); \ clear_thread_flag(TIF_32BIT_ADDR); \ @@ -304,7 +306,9 @@ do { \ else \ current->thread.abi = &mips_abi; \ \ - if (current->personality != PER_LINUX32) \ + if (ibcs2) \ + set_personality(PER_SVR4); \ + else if (current->personality != PER_LINUX32) \ set_personality(PER_LINUX); \ } while (0) diff --git a/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h b/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h index d8ff4cd89ab5..cfc8f4d618ce 100644 --- a/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ b/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h @@ -9,46 +9,47 @@ #ifndef __BCM47XX_GPIO_H #define __BCM47XX_GPIO_H -#include -#include - #define BCM47XX_EXTIF_GPIO_LINES 5 #define BCM47XX_CHIPCO_GPIO_LINES 16 -extern int gpio_request(unsigned gpio, const char *label); -extern void gpio_free(unsigned gpio); -extern int gpio_to_irq(unsigned gpio); +extern int bcm47xx_gpio_to_irq(unsigned gpio); +extern int bcm47xx_gpio_get_value(unsigned gpio); +extern void bcm47xx_gpio_set_value(unsigned gpio, int value); +extern int bcm47xx_gpio_direction_input(unsigned gpio); +extern int bcm47xx_gpio_direction_output(unsigned gpio, int value); -static inline int gpio_get_value(unsigned gpio) +static inline int gpio_request(unsigned gpio, const char *label) { - return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio); + return 0; } -static inline void gpio_set_value(unsigned gpio, int value) +static inline void gpio_free(unsigned gpio) { - ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0); } -static inline int gpio_direction_input(unsigned gpio) +static inline int gpio_to_irq(unsigned gpio) { - return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); + return bcm47xx_gpio_to_irq(gpio); } -static inline int gpio_direction_output(unsigned gpio, int value) +static inline int gpio_get_value(unsigned gpio) { - return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); + return bcm47xx_gpio_get_value(gpio); } -static int gpio_intmask(unsigned gpio, int value) +static inline void gpio_set_value(unsigned gpio, int value) +{ + bcm47xx_gpio_set_value(gpio, value); +} + +static inline int gpio_direction_input(unsigned gpio) { - return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, - value ? 1 << gpio : 0); + return bcm47xx_gpio_direction_input(gpio); } -static int gpio_polarity(unsigned gpio, int value) +static inline int gpio_direction_output(unsigned gpio, int value) { - return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, - value ? 1 << gpio : 0); + return bcm47xx_gpio_direction_output(gpio, value); } diff --git a/trunk/arch/mips/include/asm/mach-bcm47xx/war.h b/trunk/arch/mips/include/asm/mach-bcm47xx/war.h index 87cd4651dda3..4a2b7986b582 100644 --- a/trunk/arch/mips/include/asm/mach-bcm47xx/war.h +++ b/trunk/arch/mips/include/asm/mach-bcm47xx/war.h @@ -5,8 +5,8 @@ * * Copyright (C) 2002, 2004, 2007 by Ralf Baechle */ -#ifndef __ASM_MIPS_MACH_BCM47XX_WAR_H -#define __ASM_MIPS_MACH_BCM47XX_WAR_H +#ifndef __ASM_MIPS_MACH_BCM947XX_WAR_H +#define __ASM_MIPS_MACH_BCM947XX_WAR_H #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 @@ -22,4 +22,4 @@ #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 -#endif /* __ASM_MIPS_MACH_BCM47XX_WAR_H */ +#endif /* __ASM_MIPS_MACH_BCM947XX_WAR_H */ diff --git a/trunk/arch/mips/include/asm/mach-generic/ide.h b/trunk/arch/mips/include/asm/mach-generic/ide.h index 9c93a5b36f2a..73008f7bdc93 100644 --- a/trunk/arch/mips/include/asm/mach-generic/ide.h +++ b/trunk/arch/mips/include/asm/mach-generic/ide.h @@ -19,6 +19,35 @@ #include #include +static __inline__ int ide_probe_legacy(void) +{ +#ifdef CONFIG_PCI + struct pci_dev *dev; + /* + * This can be called on the ide_setup() path, super-early in + * boot. But the down_read() will enable local interrupts, + * which can cause some machines to crash. So here we detect + * and flag that situation and bail out early. + */ + if (no_pci_devices()) + return 0; + dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL); + if (dev) + goto found; + dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); + if (dev) + goto found; + return 0; +found: + pci_dev_put(dev); + return 1; +#elif defined(CONFIG_EISA) || defined(CONFIG_ISA) + return 1; +#else + return 0; +#endif +} + /* MIPS port and memory-mapped I/O string operations. */ static inline void __ide_flush_prologue(void) { diff --git a/trunk/arch/mips/include/asm/mach-ip22/ds1286.h b/trunk/arch/mips/include/asm/mach-ip22/ds1286.h new file mode 100644 index 000000000000..f19f1eafbc71 --- /dev/null +++ b/trunk/arch/mips/include/asm/mach-ip22/ds1286.h @@ -0,0 +1,18 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998, 2001, 03 by Ralf Baechle + * + * RTC routines for PC style attached Dallas chip. + */ +#ifndef __ASM_MACH_IP22_DS1286_H +#define __ASM_MACH_IP22_DS1286_H + +#include + +#define rtc_read(reg) (hpc3c0->rtcregs[(reg)] & 0xff) +#define rtc_write(data, reg) do { hpc3c0->rtcregs[(reg)] = (data); } while(0) + +#endif /* __ASM_MACH_IP22_DS1286_H */ diff --git a/trunk/arch/mips/include/asm/mach-ip28/ds1286.h b/trunk/arch/mips/include/asm/mach-ip28/ds1286.h new file mode 100644 index 000000000000..471bb9a33e0f --- /dev/null +++ b/trunk/arch/mips/include/asm/mach-ip28/ds1286.h @@ -0,0 +1,4 @@ +#ifndef __ASM_MACH_IP28_DS1286_H +#define __ASM_MACH_IP28_DS1286_H +#include +#endif /* __ASM_MACH_IP28_DS1286_H */ diff --git a/trunk/arch/mips/include/asm/spinlock.h b/trunk/arch/mips/include/asm/spinlock.h index 1a1f320c30d8..5d98a3cb85b7 100644 --- a/trunk/arch/mips/include/asm/spinlock.h +++ b/trunk/arch/mips/include/asm/spinlock.h @@ -147,7 +147,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) " ori %[ticket], %[ticket], 0x2000 \n" " xori %[ticket], %[ticket], 0x2000 \n" " sc %[ticket], %[ticket_ptr] \n" - " beqzl %[ticket], 1b \n" + " beqzl %[ticket], 2f \n" : [ticket_ptr] "+m" (lock->lock), [ticket] "=&r" (tmp)); } else { diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index aa2c55e3b55f..2fefb14414b7 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -63,6 +63,41 @@ #define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) #endif +/* + * Revalidate the inode. This is required for proper NFS attribute caching. + */ + +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) +{ + struct compat_stat tmp; + + if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) + return -EOVERFLOW; + + memset(&tmp, 0, sizeof(tmp)); + tmp.st_dev = new_encode_dev(stat->dev); + tmp.st_ino = stat->ino; + if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) + return -EOVERFLOW; + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + SET_UID(tmp.st_uid, stat->uid); + SET_GID(tmp.st_gid, stat->gid); + tmp.st_rdev = new_encode_dev(stat->rdev); + tmp.st_size = stat->size; + tmp.st_atime = stat->atime.tv_sec; + tmp.st_mtime = stat->mtime.tv_sec; + tmp.st_ctime = stat->ctime.tv_sec; +#ifdef STAT_HAVE_NSEC + tmp.st_atime_nsec = stat->atime.tv_nsec; + tmp.st_mtime_nsec = stat->mtime.tv_nsec; + tmp.st_ctime_nsec = stat->ctime.tv_nsec; +#endif + tmp.st_blocks = stat->blocks; + tmp.st_blksize = stat->blksize; + return copy_to_user(statbuf, &tmp, sizeof(tmp)) ? -EFAULT : 0; +} + asmlinkage unsigned long sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) @@ -133,6 +168,72 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, return sys_ftruncate(fd, merge_64(a2, a3)); } +static inline long +get_tv32(struct timeval *o, struct compat_timeval __user *i) +{ + return (!access_ok(VERIFY_READ, i, sizeof(*i)) || + (__get_user(o->tv_sec, &i->tv_sec) | + __get_user(o->tv_usec, &i->tv_usec))); +} + +static inline long +put_tv32(struct compat_timeval __user *o, struct timeval *i) +{ + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || + (__put_user(i->tv_sec, &o->tv_sec) | + __put_user(i->tv_usec, &o->tv_usec))); +} + +extern struct timezone sys_tz; + +asmlinkage int +sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + if (tv) { + struct timeval ktv; + do_gettimeofday(&ktv); + if (put_tv32(tv, &ktv)) + return -EFAULT; + } + if (tz) { + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + return 0; +} + +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) +{ + long usec; + + if (!access_ok(VERIFY_READ, i, sizeof(*i))) + return -EFAULT; + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + +asmlinkage int +sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_ts32(&kts, tv)) + return -EFAULT; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, unsigned int offset_low, loff_t __user * result, unsigned int origin) diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index 26760cad8b69..75bb1300dd7a 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -39,7 +39,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, __cpu_name[n], + seq_printf(m, fmt, __cpu_name[smp_processor_id()], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index ca2e4026ad20..22fc19bbe87f 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/rtlx.c b/trunk/arch/mips/kernel/rtlx.c index 4ce93aa7b372..dfd868b68364 100644 --- a/trunk/arch/mips/kernel/rtlx.c +++ b/trunk/arch/mips/kernel/rtlx.c @@ -522,8 +522,8 @@ static int __init rtlx_module_init(void) atomic_set(&channel_wqs[i].in_open, 0); mutex_init(&channel_wqs[i].mutex); - dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, - "%s%d", module_name, i); + dev = device_create_drvdata(mt_class, NULL, MKDEV(major, i), + NULL, "%s%d", module_name, i); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_chrdev; diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index e266b3aa6560..324c5499dec2 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -214,7 +214,7 @@ EXPORT(sysn32_call_table) PTR sys_fchown PTR sys_lchown PTR sys_umask - PTR compat_sys_gettimeofday + PTR sys32_gettimeofday PTR compat_sys_getrlimit /* 6095 */ PTR compat_sys_getrusage PTR compat_sys_sysinfo @@ -279,7 +279,7 @@ EXPORT(sysn32_call_table) PTR sys_chroot PTR sys_sync PTR sys_acct - PTR compat_sys_settimeofday + PTR sys32_settimeofday PTR compat_sys_mount /* 6160 */ PTR sys_umount PTR sys_swapon diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 6c7ef8313ebd..85fedac99a57 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -283,8 +283,8 @@ sys_call_table: PTR compat_sys_setrlimit /* 4075 */ PTR compat_sys_getrlimit PTR compat_sys_getrusage - PTR compat_sys_gettimeofday - PTR compat_sys_settimeofday + PTR sys32_gettimeofday + PTR sys32_settimeofday PTR sys_getgroups /* 4080 */ PTR sys_setgroups PTR sys_ni_syscall /* old_select */ diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 37970d9b2186..343015a2f418 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -7,6 +7,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. */ +#include #include #include #include diff --git a/trunk/arch/mips/kernel/vmlinux.lds.S b/trunk/arch/mips/kernel/vmlinux.lds.S index 58738c8d754f..afb119f35682 100644 --- a/trunk/arch/mips/kernel/vmlinux.lds.S +++ b/trunk/arch/mips/kernel/vmlinux.lds.S @@ -104,7 +104,7 @@ SECTIONS . = ALIGN(_PAGE_SIZE); __nosave_end = .; - . = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT); + . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff --git a/trunk/arch/mips/lasat/sysctl.c b/trunk/arch/mips/lasat/sysctl.c index 8f88886feb12..866881ec0cf8 100644 --- a/trunk/arch/mips/lasat/sysctl.c +++ b/trunk/arch/mips/lasat/sysctl.c @@ -38,13 +38,14 @@ #endif /* Strategy function to write EEPROM after changing string entry */ -int sysctl_lasatstring(ctl_table *table, +int sysctl_lasatstring(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen) { int r; - r = sysctl_string(table, oldval, oldlenp, newval, newlen); + r = sysctl_string(table, name, + nlen, oldval, oldlenp, newval, newlen); if (r < 0) return r; @@ -112,13 +113,13 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, #endif /* Sysctl for setting the IP addresses */ -int sysctl_lasat_intvec(ctl_table *table, +int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen) { int r; - r = sysctl_intvec(table, oldval, oldlenp, newval, newlen); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) return r; @@ -130,7 +131,7 @@ int sysctl_lasat_intvec(ctl_table *table, #ifdef CONFIG_DS1603 /* Same for RTC */ -int sysctl_lasat_rtc(ctl_table *table, +int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen) { @@ -139,7 +140,7 @@ int sysctl_lasat_rtc(ctl_table *table, rtctmp = read_persistent_clock(); if (rtctmp < 0) rtctmp = 0; - r = sysctl_intvec(table, oldval, oldlenp, newval, newlen); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) return r; if (newval && newlen) @@ -210,13 +211,13 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp, } #endif -static int sysctl_lasat_prid(ctl_table *table, +static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen) { int r; - r = sysctl_intvec(table, oldval, oldlenp, newval, newlen); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) return r; if (newval && newlen) { diff --git a/trunk/arch/mips/pci/fixup-emma2rh.c b/trunk/arch/mips/pci/fixup-emma2rh.c index 846eae9cdd05..a2705895561d 100644 --- a/trunk/arch/mips/pci/fixup-emma2rh.c +++ b/trunk/arch/mips/pci/fixup-emma2rh.c @@ -29,6 +29,7 @@ #include #include +#include #include diff --git a/trunk/arch/mips/pci/ops-pnx8550.c b/trunk/arch/mips/pci/ops-pnx8550.c index 1e6213fa7bdb..0e160d9f07c3 100644 --- a/trunk/arch/mips/pci/ops-pnx8550.c +++ b/trunk/arch/mips/pci/ops-pnx8550.c @@ -29,6 +29,8 @@ #include #include +#include + static inline void clear_status(void) { diff --git a/trunk/arch/mips/pci/pci-emma2rh.c b/trunk/arch/mips/pci/pci-emma2rh.c index 772e283daa63..d99591a0cdfe 100644 --- a/trunk/arch/mips/pci/pci-emma2rh.c +++ b/trunk/arch/mips/pci/pci-emma2rh.c @@ -29,6 +29,7 @@ #include #include +#include #include diff --git a/trunk/arch/mips/pci/pci.c b/trunk/arch/mips/pci/pci.c index a377e9d2d029..c7fe6ec621e6 100644 --- a/trunk/arch/mips/pci/pci.c +++ b/trunk/arch/mips/pci/pci.c @@ -34,8 +34,6 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head; unsigned long PCIBIOS_MIN_IO = 0x0000; unsigned long PCIBIOS_MIN_MEM = 0; -static int pci_initialized; - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -76,42 +74,6 @@ pcibios_align_resource(void *data, struct resource *res, res->start = start; } -static void __devinit pcibios_scanbus(struct pci_controller *hose) -{ - static int next_busno; - static int need_domain_info; - struct pci_bus *bus; - - if (!hose->iommu) - PCI_DMA_BUS_IS_PHYS = 1; - - if (hose->get_busno && pci_probe_only) - next_busno = (*hose->get_busno)(); - - bus = pci_scan_bus(next_busno, hose->pci_ops, hose); - hose->bus = bus; - - need_domain_info = need_domain_info || hose->index; - hose->need_domain_info = need_domain_info; - if (bus) { - next_busno = bus->subordinate + 1; - /* Don't allow 8-bit bus number overflow inside the hose - - reserve some space for bridges. */ - if (next_busno > 224) { - next_busno = 0; - need_domain_info = 1; - } - - if (!pci_probe_only) { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - pci_enable_bridges(bus); - } - } -} - -static DEFINE_MUTEX(pci_scan_mutex); - void __devinit register_pci_controller(struct pci_controller *hose) { if (request_resource(&iomem_resource, hose->mem_resource) < 0) @@ -131,17 +93,6 @@ void __devinit register_pci_controller(struct pci_controller *hose) printk(KERN_WARNING "registering PCI controller with io_map_base unset\n"); } - - /* - * Scan the bus if it is register after the PCI subsystem - * initialization. - */ - if (pci_initialized) { - mutex_lock(&pci_scan_mutex); - pcibios_scanbus(hose); - mutex_unlock(&pci_scan_mutex); - } - return; out: @@ -174,15 +125,38 @@ static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) static int __init pcibios_init(void) { struct pci_controller *hose; + struct pci_bus *bus; + int next_busno; + int need_domain_info = 0; /* Scan all of the recorded PCI controllers. */ - for (hose = hose_head; hose; hose = hose->next) - pcibios_scanbus(hose); + for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { + + if (!hose->iommu) + PCI_DMA_BUS_IS_PHYS = 1; + + if (hose->get_busno && pci_probe_only) + next_busno = (*hose->get_busno)(); + + bus = pci_scan_bus(next_busno, hose->pci_ops, hose); + hose->bus = bus; + need_domain_info = need_domain_info || hose->index; + hose->need_domain_info = need_domain_info; + if (bus) { + next_busno = bus->subordinate + 1; + /* Don't allow 8-bit bus number overflow inside the hose - + reserve some space for bridges. */ + if (next_busno > 224) { + next_busno = 0; + need_domain_info = 1; + } + } + } + if (!pci_probe_only) + pci_assign_unassigned_resources(); pci_fixup_irqs(common_swizzle, pcibios_map_irq); - pci_initialized = 1; - return 0; } diff --git a/trunk/arch/mips/rb532/time.c b/trunk/arch/mips/rb532/time.c index 1377d599f0e3..8e7a46855b50 100644 --- a/trunk/arch/mips/rb532/time.c +++ b/trunk/arch/mips/rb532/time.c @@ -28,6 +28,7 @@ #include #include +#include #include #include diff --git a/trunk/arch/mips/sgi-ip22/ip22-platform.c b/trunk/arch/mips/sgi-ip22/ip22-platform.c index deddbf0ebe5c..52486c4d2b01 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-platform.c +++ b/trunk/arch/mips/sgi-ip22/ip22-platform.c @@ -192,18 +192,3 @@ static int __init sgi_button_devinit(void) } device_initcall(sgi_button_devinit); - -static int __init sgi_ds1286_devinit(void) -{ - struct resource res; - - memset(&res, 0, sizeof(res)); - res.start = HPC3_CHIP0_BASE + offsetof(struct hpc3_regs, rtcregs); - res.end = res.start + sizeof(hpc3c0->rtcregs) - 1; - res.flags = IORESOURCE_MEM; - - return IS_ERR(platform_device_register_simple("rtc-ds1286", -1, - &res, 1)); -} - -device_initcall(sgi_ds1286_devinit); diff --git a/trunk/arch/mips/sgi-ip22/ip22-setup.c b/trunk/arch/mips/sgi-ip22/ip22-setup.c index b9a931358e23..896a1ef84829 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-setup.c +++ b/trunk/arch/mips/sgi-ip22/ip22-setup.c @@ -4,6 +4,7 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) */ +#include #include #include #include diff --git a/trunk/arch/mips/sgi-ip22/ip22-time.c b/trunk/arch/mips/sgi-ip22/ip22-time.c index 3dcb27ec0c53..10e505491655 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-time.c +++ b/trunk/arch/mips/sgi-ip22/ip22-time.c @@ -10,6 +10,7 @@ * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org) */ #include +#include #include #include #include @@ -28,6 +29,69 @@ #include #include +/* + * Note that mktime uses month from 1 to 12 while rtc_time_to_tm + * uses 0 to 11. + */ +unsigned long read_persistent_clock(void) +{ + unsigned int yrs, mon, day, hrs, min, sec; + unsigned int save_control; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; + + sec = BCD2BIN(hpc3c0->rtcregs[RTC_SECONDS] & 0xff); + min = BCD2BIN(hpc3c0->rtcregs[RTC_MINUTES] & 0xff); + hrs = BCD2BIN(hpc3c0->rtcregs[RTC_HOURS] & 0x3f); + day = BCD2BIN(hpc3c0->rtcregs[RTC_DATE] & 0xff); + mon = BCD2BIN(hpc3c0->rtcregs[RTC_MONTH] & 0x1f); + yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff); + + hpc3c0->rtcregs[RTC_CMD] = save_control; + spin_unlock_irqrestore(&rtc_lock, flags); + + if (yrs < 45) + yrs += 30; + if ((yrs += 40) < 70) + yrs += 100; + + return mktime(yrs + 1900, mon, day, hrs, min, sec); +} + +int rtc_mips_set_time(unsigned long tim) +{ + struct rtc_time tm; + unsigned int save_control; + unsigned long flags; + + rtc_time_to_tm(tim, &tm); + + tm.tm_mon += 1; /* tm_mon starts at zero */ + tm.tm_year -= 40; + if (tm.tm_year >= 100) + tm.tm_year -= 100; + + spin_lock_irqsave(&rtc_lock, flags); + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; + + hpc3c0->rtcregs[RTC_YEAR] = BIN2BCD(tm.tm_year); + hpc3c0->rtcregs[RTC_MONTH] = BIN2BCD(tm.tm_mon); + hpc3c0->rtcregs[RTC_DATE] = BIN2BCD(tm.tm_mday); + hpc3c0->rtcregs[RTC_HOURS] = BIN2BCD(tm.tm_hour); + hpc3c0->rtcregs[RTC_MINUTES] = BIN2BCD(tm.tm_min); + hpc3c0->rtcregs[RTC_SECONDS] = BIN2BCD(tm.tm_sec); + hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; + + hpc3c0->rtcregs[RTC_CMD] = save_control; + spin_unlock_irqrestore(&rtc_lock, flags); + + return 0; +} + static unsigned long dosample(void) { u32 ct0, ct1; diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index 1327c2746fb7..8b4e854af925 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -13,12 +13,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -28,6 +28,51 @@ #define TICK_SIZE (tick_nsec / 1000) +#if 0 +static int set_rtc_mmss(unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + struct m48t35_rtc *rtc; + nasid_t nid; + + nid = get_nasid(); + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + + IOC3_BYTEBUS_DEV0); + + rtc->control |= M48T35_RTC_READ; + cmos_minutes = BCD2BIN(rtc->min); + rtc->control &= ~M48T35_RTC_READ; + + /* + * Since we're only adjusting minutes and seconds, don't interfere with + * hour overflow. This avoids messing with unknown time zones but + * requires your RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + real_seconds = BIN2BCD(real_seconds); + real_minutes = BIN2BCD(real_minutes); + rtc->control |= M48T35_RTC_SET; + rtc->sec = real_seconds; + rtc->min = real_minutes; + rtc->control &= ~M48T35_RTC_SET; + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + return retval; +} +#endif + /* Includes for ioc3_init(). */ #include #include @@ -35,6 +80,37 @@ #include #include +unsigned long read_persistent_clock(void) +{ + unsigned int year, month, date, hour, min, sec; + struct m48t35_rtc *rtc; + nasid_t nid; + + nid = get_nasid(); + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + + IOC3_BYTEBUS_DEV0); + + rtc->control |= M48T35_RTC_READ; + sec = rtc->sec; + min = rtc->min; + hour = rtc->hour; + date = rtc->date; + month = rtc->month; + year = rtc->year; + rtc->control &= ~M48T35_RTC_READ; + + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + date = BCD2BIN(date); + month = BCD2BIN(month); + year = BCD2BIN(year); + + year += 1970; + + return mktime(year, month, date, hour, min, sec); +} + static void enable_rt_irq(unsigned int irq) { } @@ -210,7 +286,6 @@ void __cpuinit cpu_time_init(void) void __cpuinit hub_rtc_init(cnodeid_t cnode) { - /* * We only need to initialize the current node. * If this is not the current node then it is a cpuless @@ -226,23 +301,3 @@ void __cpuinit hub_rtc_init(cnodeid_t cnode) LOCAL_HUB_S(PI_RT_PEND_B, 0); } } - -static int __init sgi_ip27_rtc_devinit(void) -{ - struct resource res; - - memset(&res, 0, sizeof(res)); - res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base + - IOC3_BYTEBUS_DEV0); - res.end = res.start + 32767; - res.flags = IORESOURCE_MEM; - - return IS_ERR(platform_device_register_simple("rtc-m48t35", -1, - &res, 1)); -} - -/* - * kludge make this a device_initcall after ioc3 resource conflicts - * are resolved - */ -late_initcall(sgi_ip27_rtc_devinit); diff --git a/trunk/arch/mips/sgi-ip32/ip32-platform.c b/trunk/arch/mips/sgi-ip32/ip32-platform.c index 511e9ff2acfd..3d63721e0e80 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-platform.c +++ b/trunk/arch/mips/sgi-ip32/ip32-platform.c @@ -90,22 +90,6 @@ static __init int sgio2btns_devinit(void) device_initcall(sgio2btns_devinit); -static struct resource sgio2_cmos_rsrc[] = { - { - .start = 0x70, - .end = 0x71, - .flags = IORESOURCE_IO - } -}; - -static __init int sgio2_cmos_devinit(void) -{ - return IS_ERR(platform_device_register_simple("rtc_cmos", -1, - sgio2_cmos_rsrc, 1)); -} - -device_initcall(sgio2_cmos_devinit); - MODULE_AUTHOR("Ralf Baechle "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2"); diff --git a/trunk/arch/mips/sgi-ip32/ip32-setup.c b/trunk/arch/mips/sgi-ip32/ip32-setup.c index c5a5d4a31b4b..1024bf40bd9e 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-setup.c +++ b/trunk/arch/mips/sgi-ip32/ip32-setup.c @@ -62,6 +62,11 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) } #endif +unsigned long read_persistent_clock(void) +{ + return mc146818_get_cmos_time(); +} + /* An arbitrary time; this can be decreased if reliability looks good */ #define WAIT_MS 10 diff --git a/trunk/arch/mips/sibyte/common/sb_tbprof.c b/trunk/arch/mips/sibyte/common/sb_tbprof.c index 637a194e5cd5..66e3e3fb311f 100644 --- a/trunk/arch/mips/sibyte/common/sb_tbprof.c +++ b/trunk/arch/mips/sibyte/common/sb_tbprof.c @@ -576,7 +576,8 @@ static int __init sbprof_tb_init(void) tb_class = tbc; - dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb"); + dev = device_create_drvdata(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), + NULL, "tb"); if (IS_ERR(dev)) { err = PTR_ERR(dev); goto out_class; diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index dd557c9cf001..e856218da90d 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -53,6 +53,9 @@ config QUICKLIST config ARCH_HAS_ILOG2_U32 def_bool y +config ARCH_SUPPORTS_AOUT + def_bool n + # Use the generic interrupt handling code in kernel/irq/ config GENERIC_HARDIRQS def_bool y diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 8313fccced5e..a7d4fd353c2b 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -76,6 +76,9 @@ config IRQ_PER_CPU bool default y +config ARCH_SUPPORTS_AOUT + def_bool y + # unless you want to implement ACPI on PA-RISC ... ;-) config PM bool diff --git a/trunk/arch/parisc/kernel/binfmt_elf32.c b/trunk/arch/parisc/kernel/binfmt_elf32.c index f61692d2b557..ecb10a4f63c6 100644 --- a/trunk/arch/parisc/kernel/binfmt_elf32.c +++ b/trunk/arch/parisc/kernel/binfmt_elf32.c @@ -85,7 +85,7 @@ struct elf_prpsinfo32 * could set a processor dependent flag in the thread_struct. */ -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY(ex, ibcs2) \ set_thread_flag(TIF_32BIT); \ current->thread.map_base = DEFAULT_MAP_BASE32; \ current->thread.task_size = DEFAULT_TASK_SIZE32 \ diff --git a/trunk/arch/parisc/kernel/sys_parisc32.c b/trunk/arch/parisc/kernel/sys_parisc32.c index 0838155b7a88..71efd6a28e2a 100644 --- a/trunk/arch/parisc/kernel/sys_parisc32.c +++ b/trunk/arch/parisc/kernel/sys_parisc32.c @@ -179,6 +179,111 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid, return ret; } +static int +put_compat_timeval(struct compat_timeval __user *u, struct timeval *t) +{ + struct compat_timeval t32; + t32.tv_sec = t->tv_sec; + t32.tv_usec = t->tv_usec; + return copy_to_user(u, &t32, sizeof t32); +} + +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) +{ + long usec; + + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + +asmlinkage int +sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + extern void do_gettimeofday(struct timeval *tv); + + if (tv) { + struct timeval ktv; + do_gettimeofday(&ktv); + if (put_compat_timeval(tv, &ktv)) + return -EFAULT; + } + if (tz) { + extern struct timezone sys_tz; + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + return 0; +} + +asmlinkage +int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_ts32(&kts, tv)) + return -EFAULT; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) +{ + compat_ino_t ino; + int err; + + if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || + !new_valid_dev(stat->rdev)) + return -EOVERFLOW; + + ino = stat->ino; + if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) + return -EOVERFLOW; + + err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); + err |= put_user(ino, &statbuf->st_ino); + err |= put_user(stat->mode, &statbuf->st_mode); + err |= put_user(stat->nlink, &statbuf->st_nlink); + err |= put_user(0, &statbuf->st_reserved1); + err |= put_user(0, &statbuf->st_reserved2); + err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev); + err |= put_user(stat->size, &statbuf->st_size); + err |= put_user(stat->atime.tv_sec, &statbuf->st_atime); + err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); + err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime); + err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); + err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime); + err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); + err |= put_user(stat->blksize, &statbuf->st_blksize); + err |= put_user(stat->blocks, &statbuf->st_blocks); + err |= put_user(0, &statbuf->__unused1); + err |= put_user(0, &statbuf->__unused2); + err |= put_user(0, &statbuf->__unused3); + err |= put_user(0, &statbuf->__unused4); + err |= put_user(0, &statbuf->__unused5); + err |= put_user(0, &statbuf->st_fstype); /* not avail */ + err |= put_user(0, &statbuf->st_realdev); /* not avail */ + err |= put_user(0, &statbuf->st_basemode); /* not avail */ + err |= put_user(0, &statbuf->st_spareshort); + err |= put_user(stat->uid, &statbuf->st_uid); + err |= put_user(stat->gid, &statbuf->st_gid); + err |= put_user(0, &statbuf->st_spare4[0]); + err |= put_user(0, &statbuf->st_spare4[1]); + err |= put_user(0, &statbuf->st_spare4[2]); + + return err; +} + /*** copied from mips64 ***/ /* * Ooo, nasty. We need here to frob 32-bit unsigned longs to diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index c7e59f548817..6b5ac38f5a99 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -149,8 +149,8 @@ ENTRY_COMP(getrlimit) ENTRY_COMP(getrusage) /* struct timeval and timezone are maybe?? consistent wide and narrow */ - ENTRY_COMP(gettimeofday) - ENTRY_COMP(settimeofday) + ENTRY_DIFF(gettimeofday) + ENTRY_DIFF(settimeofday) ENTRY_SAME(getgroups) /* 80 */ ENTRY_SAME(setgroups) /* struct socketaddr... */ diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index c171f5bcf258..587da5e0990f 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -415,11 +415,8 @@ config PPC_64K_PAGES config FORCE_MAX_ZONEORDER int "Maximum zone order" - range 9 64 if PPC_64K_PAGES default "9" if PPC_64K_PAGES - range 13 64 if PPC64 && !PPC_64K_PAGES default "13" if PPC64 && !PPC_64K_PAGES - range 11 64 default "11" help The kernel memory allocator divides physically contiguous memory @@ -809,19 +806,6 @@ config PIN_TLB endmenu if PPC64 -config RELOCATABLE - bool "Build a relocatable kernel" - help - This builds a kernel image that is capable of running anywhere - in the RMA (real memory area) at any 16k-aligned base address. - The kernel is linked as a position-independent executable (PIE) - and contains dynamic relocations which are processed early - in the bootup process. - - One use is for the kexec on panic case where the recovery kernel - must live at a different physical address than the primary - kernel. - config PAGE_OFFSET hex default "0xc000000000000000" diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index 15eb27861fc7..4ebc52a19f0a 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -51,11 +51,6 @@ config FTR_FIXUP_SELFTEST depends on DEBUG_KERNEL default n -config MSI_BITMAP_SELFTEST - bool "Run self-tests of the MSI bitmap code." - depends on DEBUG_KERNEL - default n - config XMON bool "Include xmon kernel debugger" depends on DEBUG_KERNEL diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 24dd1a37f8fb..c6be19e9ceae 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -63,9 +63,7 @@ override CC += -m$(CONFIG_WORD_SIZE) override AR := GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR) endif -LDFLAGS_vmlinux-yy := -Bstatic -LDFLAGS_vmlinux-$(CONFIG_PPC64)$(CONFIG_RELOCATABLE) := -pie -LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-yy) +LDFLAGS_vmlinux := -Bstatic CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none -mcall-aixdesc CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple @@ -104,10 +102,7 @@ endif KBUILD_CFLAGS += $(call cc-option,-mno-altivec) # No SPE instruction when building kernel -# (We use all available options to help semi-broken compilers) KBUILD_CFLAGS += $(call cc-option,-mno-spe) -KBUILD_CFLAGS += $(call cc-option,-mspe=no) -KBUILD_CFLAGS += $(call cc-option,-mabi=no-spe) # Enable unit-at-a-time mode when possible. It shrinks the # kernel considerably. diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index aac1406ccba5..65d1a8454d2c 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -310,11 +310,8 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb $(obj)/vmlinux.strip: vmlinux $(STRIP) -s -R .comment $< -o $@ -# The iseries hypervisor won't take an ET_DYN executable, so this -# changes the type (byte 17) in the file to ET_EXEC (2). $(obj)/zImage.iseries: vmlinux $(STRIP) -s -R .comment $< -o $@ - printf "\x02" | dd of=$@ conv=notrunc bs=1 seek=17 $(obj)/uImage: vmlinux $(wrapperbits) $(call if_changed,wrap,uboot) diff --git a/trunk/arch/powerpc/boot/addnote.c b/trunk/arch/powerpc/boot/addnote.c index dcc9ab2ca823..b1e5611b2ab1 100644 --- a/trunk/arch/powerpc/boot/addnote.c +++ b/trunk/arch/powerpc/boot/addnote.c @@ -11,12 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Usage: addnote zImage [note.elf] - * - * If note.elf is supplied, it is the name of an ELF file that contains - * an RPA note to use instead of the built-in one. Alternatively, the - * note.elf file may be empty, in which case the built-in RPA note is - * used (this is to simplify how this is invoked from the wrapper script). + * Usage: addnote zImage */ #include #include @@ -48,29 +43,27 @@ char rpaname[] = "IBM,RPA-Client-Config"; */ #define N_RPA_DESCR 8 unsigned int rpanote[N_RPA_DESCR] = { - 1, /* lparaffinity */ - 128, /* min_rmo_size */ + 0, /* lparaffinity */ + 64, /* min_rmo_size */ 0, /* min_rmo_percent */ - 46, /* max_pft_size */ + 40, /* max_pft_size */ 1, /* splpar */ -1, /* min_load */ - 1, /* new_mem_def */ - 0, /* ignore_my_client_config */ + 0, /* new_mem_def */ + 1, /* ignore_my_client_config */ }; #define ROUNDUP(len) (((len) + 3) & ~3) unsigned char buf[512]; -unsigned char notebuf[512]; -#define GET_16BE(b, off) (((b)[off] << 8) + ((b)[(off)+1])) -#define GET_32BE(b, off) ((GET_16BE((b), (off)) << 16) + \ - GET_16BE((b), (off)+2)) +#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) +#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) -#define PUT_16BE(b, off, v) ((b)[off] = ((v) >> 8) & 0xff, \ - (b)[(off) + 1] = (v) & 0xff) -#define PUT_32BE(b, off, v) (PUT_16BE((b), (off), (v) >> 16), \ - PUT_16BE((b), (off) + 2, (v))) +#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ + buf[(off) + 1] = (v) & 0xff) +#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ + PUT_16BE((off) + 2, (v))) /* Structure of an ELF file */ #define E_IDENT 0 /* ELF header */ @@ -95,71 +88,15 @@ unsigned char notebuf[512]; unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; -unsigned char *read_rpanote(const char *fname, int *nnp) -{ - int notefd, nr, i; - int ph, ps, np; - int note, notesize; - - notefd = open(fname, O_RDONLY); - if (notefd < 0) { - perror(fname); - exit(1); - } - nr = read(notefd, notebuf, sizeof(notebuf)); - if (nr < 0) { - perror("read note"); - exit(1); - } - if (nr == 0) /* empty file */ - return NULL; - if (nr < E_HSIZE || - memcmp(¬ebuf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0 || - notebuf[E_IDENT+EI_CLASS] != ELFCLASS32 || - notebuf[E_IDENT+EI_DATA] != ELFDATA2MSB) - goto notelf; - close(notefd); - - /* now look for the RPA-note */ - ph = GET_32BE(notebuf, E_PHOFF); - ps = GET_16BE(notebuf, E_PHENTSIZE); - np = GET_16BE(notebuf, E_PHNUM); - if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) - goto notelf; - - for (i = 0; i < np; ++i, ph += ps) { - if (GET_32BE(notebuf, ph + PH_TYPE) != PT_NOTE) - continue; - note = GET_32BE(notebuf, ph + PH_OFFSET); - notesize = GET_32BE(notebuf, ph + PH_FILESZ); - if (notesize < 34 || note + notesize > nr) - continue; - if (GET_32BE(notebuf, note) != strlen(rpaname) + 1 || - GET_32BE(notebuf, note + 8) != 0x12759999 || - strcmp((char *)¬ebuf[note + 12], rpaname) != 0) - continue; - /* looks like an RPA note, return it */ - *nnp = notesize; - return ¬ebuf[note]; - } - /* no RPA note found */ - return NULL; - - notelf: - fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", fname); - exit(1); -} - int main(int ac, char **av) { int fd, n, i; int ph, ps, np; int nnote, nnote2, ns; - unsigned char *rpap; - if (ac != 2 && ac != 3) { - fprintf(stderr, "Usage: %s elf-file [rpanote.elf]\n", av[0]); + if (ac != 2) { + fprintf(stderr, "Usage: %s elf-file\n", av[0]); exit(1); } fd = open(av[1], O_RDWR); @@ -170,7 +107,6 @@ main(int ac, char **av) nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr); nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote); - rpap = NULL; n = read(fd, buf, sizeof(buf)); if (n < 0) { @@ -188,19 +124,16 @@ main(int ac, char **av) exit(1); } - if (ac == 3) - rpap = read_rpanote(av[2], &nnote2); - - ph = GET_32BE(buf, E_PHOFF); - ps = GET_16BE(buf, E_PHENTSIZE); - np = GET_16BE(buf, E_PHNUM); + ph = GET_32BE(E_PHOFF); + ps = GET_16BE(E_PHENTSIZE); + np = GET_16BE(E_PHNUM); if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) goto notelf; if (ph + (np + 2) * ps + nnote + nnote2 > n) goto nospace; for (i = 0; i < np; ++i) { - if (GET_32BE(buf, ph + PH_TYPE) == PT_NOTE) { + if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { fprintf(stderr, "%s already has a note entry\n", av[1]); exit(0); @@ -215,42 +148,37 @@ main(int ac, char **av) /* fill in the program header entry */ ns = ph + 2 * ps; - PUT_32BE(buf, ph + PH_TYPE, PT_NOTE); - PUT_32BE(buf, ph + PH_OFFSET, ns); - PUT_32BE(buf, ph + PH_FILESZ, nnote); + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote); /* fill in the note area we point to */ /* XXX we should probably make this a proper section */ - PUT_32BE(buf, ns, strlen(arch) + 1); - PUT_32BE(buf, ns + 4, N_DESCR * 4); - PUT_32BE(buf, ns + 8, 0x1275); + PUT_32BE(ns, strlen(arch) + 1); + PUT_32BE(ns + 4, N_DESCR * 4); + PUT_32BE(ns + 8, 0x1275); strcpy((char *) &buf[ns + 12], arch); ns += 12 + strlen(arch) + 1; for (i = 0; i < N_DESCR; ++i, ns += 4) - PUT_32BE(buf, ns, descr[i]); + PUT_32BE(ns, descr[i]); /* fill in the second program header entry and the RPA note area */ ph += ps; - PUT_32BE(buf, ph + PH_TYPE, PT_NOTE); - PUT_32BE(buf, ph + PH_OFFSET, ns); - PUT_32BE(buf, ph + PH_FILESZ, nnote2); + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote2); /* fill in the note area we point to */ - if (rpap) { - /* RPA note supplied in file, just copy the whole thing over */ - memcpy(buf + ns, rpap, nnote2); - } else { - PUT_32BE(buf, ns, strlen(rpaname) + 1); - PUT_32BE(buf, ns + 4, sizeof(rpanote)); - PUT_32BE(buf, ns + 8, 0x12759999); - strcpy((char *) &buf[ns + 12], rpaname); - ns += 12 + ROUNDUP(strlen(rpaname) + 1); - for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) - PUT_32BE(buf, ns, rpanote[i]); - } + PUT_32BE(ns, strlen(rpaname) + 1); + PUT_32BE(ns + 4, sizeof(rpanote)); + PUT_32BE(ns + 8, 0x12759999); + strcpy((char *) &buf[ns + 12], rpaname); + ns += 12 + ROUNDUP(strlen(rpaname) + 1); + for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) + PUT_32BE(ns, rpanote[i]); /* Update the number of program headers */ - PUT_16BE(buf, E_PHNUM, np + 2); + PUT_16BE(E_PHNUM, np + 2); /* write back */ lseek(fd, (long) 0, SEEK_SET); diff --git a/trunk/arch/powerpc/boot/dtc-src/Makefile.dtc b/trunk/arch/powerpc/boot/dtc-src/Makefile.dtc index 6ddf9ecac669..d607fdb8df8d 100644 --- a/trunk/arch/powerpc/boot/dtc-src/Makefile.dtc +++ b/trunk/arch/powerpc/boot/dtc-src/Makefile.dtc @@ -5,5 +5,21 @@ # DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \ checks.c -DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c +DTC_EXTRA = dtc.h srcpos.h +DTC_LEXFILES = dtc-lexer.l +DTC_BISONFILES = dtc-parser.y + +DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c) +DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c) +DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h) + +DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS) +DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES) DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o) + +DTC_CLEANFILES = $(DTC_GEN_ALL) + +# We assume the containing Makefile system can do auto-dependencies for most +# things, but we supply the dependencies on generated header files explicitly + +$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES)) diff --git a/trunk/arch/powerpc/boot/dtc-src/checks.c b/trunk/arch/powerpc/boot/dtc-src/checks.c index 95485796f253..2ce961cd414d 100644 --- a/trunk/arch/powerpc/boot/dtc-src/checks.c +++ b/trunk/arch/powerpc/boot/dtc-src/checks.c @@ -242,42 +242,6 @@ static void check_duplicate_property_names(struct check *c, struct node *dt, } NODE_CHECK(duplicate_property_names, NULL, ERROR); -#define LOWERCASE "abcdefghijklmnopqrstuvwxyz" -#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define DIGITS "0123456789" -#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" - -static void check_node_name_chars(struct check *c, struct node *dt, - struct node *node) -{ - int n = strspn(node->name, c->data); - - if (n < strlen(node->name)) - FAIL(c, "Bad character '%c' in node %s", - node->name[n], node->fullpath); -} -NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR); - -static void check_node_name_format(struct check *c, struct node *dt, - struct node *node) -{ - if (strchr(get_unitname(node), '@')) - FAIL(c, "Node %s has multiple '@' characters in name", - node->fullpath); -} -NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars); - -static void check_property_name_chars(struct check *c, struct node *dt, - struct node *node, struct property *prop) -{ - int n = strspn(prop->name, c->data); - - if (n < strlen(prop->name)) - FAIL(c, "Bad character '%c' in property name \"%s\", node %s", - prop->name[n], prop->name, node->fullpath); -} -PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); - static void check_explicit_phandles(struct check *c, struct node *root, struct node *node) { @@ -316,29 +280,16 @@ NODE_CHECK(explicit_phandles, NULL, ERROR); static void check_name_properties(struct check *c, struct node *root, struct node *node) { - struct property **pp, *prop = NULL; - - for (pp = &node->proplist; *pp; pp = &((*pp)->next)) - if (streq((*pp)->name, "name")) { - prop = *pp; - break; - } + struct property *prop; + prop = get_property(node, "name"); if (!prop) return; /* No name property, that's fine */ if ((prop->val.len != node->basenamelen+1) - || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { + || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" " of base node name)", node->fullpath, prop->val.val); - } else { - /* The name property is correct, and therefore redundant. - * Delete it */ - *pp = prop->next; - free(prop->name); - data_free(prop->val); - free(prop); - } } CHECK_IS_STRING(name_is_string, "name", ERROR); NODE_CHECK(name_properties, NULL, ERROR, &name_is_string); @@ -350,23 +301,23 @@ NODE_CHECK(name_properties, NULL, ERROR, &name_is_string); static void fixup_phandle_references(struct check *c, struct node *dt, struct node *node, struct property *prop) { - struct marker *m = prop->val.markers; - struct node *refnode; - cell_t phandle; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); - if (! refnode) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", - m->ref); - continue; - } - - phandle = get_node_phandle(dt, refnode); - *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } + struct marker *m = prop->val.markers; + struct node *refnode; + cell_t phandle; + + for_each_marker_of_type(m, REF_PHANDLE) { + assert(m->offset + sizeof(cell_t) <= prop->val.len); + + refnode = get_node_by_ref(dt, m->ref); + if (! refnode) { + FAIL(c, "Reference to non-existent node or label \"%s\"\n", + m->ref); + continue; + } + + phandle = get_node_phandle(dt, refnode); + *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle); + } } CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR, &duplicate_node_names, &explicit_phandles); @@ -547,7 +498,6 @@ TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN); static struct check *check_table[] = { &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, &name_is_string, &name_properties, &explicit_phandles, &phandle_references, &path_references, @@ -561,7 +511,10 @@ static struct check *check_table[] = { &obsolete_chosen_interrupt_controller, }; -void process_checks(int force, struct boot_info *bi) +int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys); + +void process_checks(int force, struct boot_info *bi, + int checkflag, int outversion, int boot_cpuid_phys) { struct node *dt = bi->dt; int i; @@ -584,4 +537,214 @@ void process_checks(int force, struct boot_info *bi) "output forced\n"); } } + + if (checkflag) { + if (error) { + fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n"); + } else { + if (!check_semantics(bi->dt, outversion, + boot_cpuid_phys)) + fprintf(stderr, "Warning: Input tree has semantic errors\n"); + } + } +} + +/* + * Semantic check functions + */ + +#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__) +#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__) + +#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0) + +#define CHECK_HAVE(node, propname) \ + do { \ + if (! (prop = get_property((node), (propname)))) \ + DO_ERR("Missing \"%s\" property in %s\n", (propname), \ + (node)->fullpath); \ + } while (0); + +#define CHECK_HAVE_WARN(node, propname) \ + do { \ + if (! (prop = get_property((node), (propname)))) \ + WARNMSG("%s has no \"%s\" property\n", \ + (node)->fullpath, (propname)); \ + } while (0) + +#define CHECK_HAVE_STRING(node, propname) \ + do { \ + CHECK_HAVE((node), (propname)); \ + if (prop && !data_is_one_string(prop->val)) \ + DO_ERR("\"%s\" property in %s is not a string\n", \ + (propname), (node)->fullpath); \ + } while (0) + +#define CHECK_HAVE_STREQ(node, propname, value) \ + do { \ + CHECK_HAVE_STRING((node), (propname)); \ + if (prop && !streq(prop->val.val, (value))) \ + DO_ERR("%s has wrong %s, %s (should be %s\n", \ + (node)->fullpath, (propname), \ + prop->val.val, (value)); \ + } while (0) + +#define CHECK_HAVE_ONECELL(node, propname) \ + do { \ + CHECK_HAVE((node), (propname)); \ + if (prop && (prop->val.len != sizeof(cell_t))) \ + DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \ + } while (0) + +#define CHECK_HAVE_WARN_ONECELL(node, propname) \ + do { \ + CHECK_HAVE_WARN((node), (propname)); \ + if (prop && (prop->val.len != sizeof(cell_t))) \ + DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \ + } while (0) + +#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \ + do { \ + struct node *ref; \ + CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \ + if (prop) {\ + cell_t phandle = propval_cell(prop); \ + if ((phandle == 0) || (phandle == -1)) { \ + DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \ + } else { \ + ref = get_node_by_phandle((root), propval_cell(prop)); \ + if (! ref) \ + DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \ + } \ + } \ + } while (0) + +#define CHECK_HAVE_WARN_STRING(node, propname) \ + do { \ + CHECK_HAVE_WARN((node), (propname)); \ + if (prop && !data_is_one_string(prop->val)) \ + DO_ERR("\"%s\" property in %s is not a string\n", \ + (propname), (node)->fullpath); \ + } while (0) + +static int check_root(struct node *root) +{ + struct property *prop; + int ok = 1; + + CHECK_HAVE_STRING(root, "model"); + CHECK_HAVE_WARN(root, "compatible"); + + return ok; +} + +static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys) +{ + struct node *cpus, *cpu; + struct property *prop; + struct node *bootcpu = NULL; + int ok = 1; + + cpus = get_subnode(root, "cpus"); + if (! cpus) { + ERRMSG("Missing /cpus node\n"); + return 0; + } + + if (cpus->addr_cells != 1) + DO_ERR("%s has bad #address-cells value %d (should be 1)\n", + cpus->fullpath, cpus->addr_cells); + if (cpus->size_cells != 0) + DO_ERR("%s has bad #size-cells value %d (should be 0)\n", + cpus->fullpath, cpus->size_cells); + + for_each_child(cpus, cpu) { + CHECK_HAVE_STREQ(cpu, "device_type", "cpu"); + + CHECK_HAVE_ONECELL(cpu, "reg"); + if (prop) { + cell_t unitnum; + char *eptr; + + unitnum = strtol(get_unitname(cpu), &eptr, 16); + if (*eptr) { + WARNMSG("%s has bad format unit name %s (should be CPU number\n", + cpu->fullpath, get_unitname(cpu)); + } else if (unitnum != propval_cell(prop)) { + WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n", + cpu->fullpath, get_unitname(cpu), + propval_cell(prop)); + } + } + +/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */ +/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */ + CHECK_HAVE_ONECELL(cpu, "d-cache-size"); + CHECK_HAVE_ONECELL(cpu, "i-cache-size"); + + CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency"); + CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency"); + + prop = get_property(cpu, "linux,boot-cpu"); + if (prop) { + if (prop->val.len) + WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n", + cpu->fullpath); + if (bootcpu) + DO_ERR("Multiple boot cpus (%s and %s)\n", + bootcpu->fullpath, cpu->fullpath); + else + bootcpu = cpu; + } + } + + if (outversion < 2) { + if (! bootcpu) + WARNMSG("No cpu has \"linux,boot-cpu\" property\n"); + } else { + if (bootcpu) + WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n"); + if (boot_cpuid_phys == 0xfeedbeef) + WARNMSG("physical boot CPU not set. Use -b option to set\n"); + } + + return ok; +} + +static int check_memory(struct node *root) +{ + struct node *mem; + struct property *prop; + int nnodes = 0; + int ok = 1; + + for_each_child(root, mem) { + if (! strneq(mem->name, "memory", mem->basenamelen)) + continue; + + nnodes++; + + CHECK_HAVE_STREQ(mem, "device_type", "memory"); + CHECK_HAVE(mem, "reg"); + } + + if (nnodes == 0) { + ERRMSG("No memory nodes\n"); + return 0; + } + + return ok; +} + +int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys) +{ + int ok = 1; + + ok = ok && check_root(dt); + ok = ok && check_cpus(dt, outversion, boot_cpuid_phys); + ok = ok && check_memory(dt); + if (! ok) + return 0; + + return 1; } diff --git a/trunk/arch/powerpc/boot/dtc-src/data.c b/trunk/arch/powerpc/boot/dtc-src/data.c index dd2e3d39d4c1..a94718c731a9 100644 --- a/trunk/arch/powerpc/boot/dtc-src/data.c +++ b/trunk/arch/powerpc/boot/dtc-src/data.c @@ -32,6 +32,8 @@ void data_free(struct data d) m = nm; } + assert(!d.val || d.asize); + if (d.val) free(d.val); } @@ -41,6 +43,9 @@ struct data data_grow_for(struct data d, int xlen) struct data nd; int newsize; + /* we must start with an allocated datum */ + assert(!d.val || d.asize); + if (xlen == 0) return d; @@ -51,8 +56,11 @@ struct data data_grow_for(struct data d, int xlen) while ((d.len + xlen) > newsize) newsize *= 2; + nd.asize = newsize; nd.val = xrealloc(d.val, newsize); + assert(nd.asize >= (d.len + xlen)); + return nd; } @@ -75,11 +83,16 @@ static char get_oct_char(const char *s, int *i) long val; x[3] = '\0'; - strncpy(x, s + *i, 3); + x[0] = s[(*i)]; + if (x[0]) { + x[1] = s[(*i)+1]; + if (x[1]) + x[2] = s[(*i)+2]; + } val = strtol(x, &endx, 8); - - assert(endx > x); + if ((endx - x) == 0) + fprintf(stderr, "Empty \\nnn escape\n"); (*i) += endx - x; return val; @@ -92,11 +105,13 @@ static char get_hex_char(const char *s, int *i) long val; x[2] = '\0'; - strncpy(x, s + *i, 2); + x[0] = s[(*i)]; + if (x[0]) + x[1] = s[(*i)+1]; val = strtol(x, &endx, 16); - if (!(endx > x)) - die("\\x used with no following hex digits\n"); + if ((endx - x) == 0) + fprintf(stderr, "Empty \\x escape\n"); (*i) += endx - x; return val; @@ -167,29 +182,14 @@ struct data data_copy_escape_string(const char *s, int len) return d; } -struct data data_copy_file(FILE *f, size_t maxlen) +struct data data_copy_file(FILE *f, size_t len) { - struct data d = empty_data; - - while (!feof(f) && (d.len < maxlen)) { - size_t chunksize, ret; - - if (maxlen == -1) - chunksize = 4096; - else - chunksize = maxlen - d.len; - - d = data_grow_for(d, chunksize); - ret = fread(d.val + d.len, 1, chunksize, f); - - if (ferror(f)) - die("Error reading file into data: %s", strerror(errno)); + struct data d; - if (d.len + ret < d.len) - die("Overflow reading file into data\n"); + d = data_grow_for(empty_data, len); - d.len += ret; - } + d.len = len; + fread(d.val, len, 1, f); return d; } @@ -247,7 +247,7 @@ struct data data_merge(struct data d1, struct data d2) struct data data_append_cell(struct data d, cell_t word) { - cell_t beword = cpu_to_fdt32(word); + cell_t beword = cpu_to_be32(word); return data_append_data(d, &beword, sizeof(beword)); } @@ -256,15 +256,15 @@ struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) { struct fdt_reserve_entry bere; - bere.address = cpu_to_fdt64(re->address); - bere.size = cpu_to_fdt64(re->size); + bere.address = cpu_to_be64(re->address); + bere.size = cpu_to_be64(re->size); return data_append_data(d, &bere, sizeof(bere)); } -struct data data_append_addr(struct data d, uint64_t addr) +struct data data_append_addr(struct data d, u64 addr) { - uint64_t beaddr = cpu_to_fdt64(addr); + u64 beaddr = cpu_to_be64(addr); return data_append_data(d, &beaddr, sizeof(beaddr)); } diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.l b/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.l index 44dbfd3f0976..c811b221b31e 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.l +++ b/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.l @@ -28,10 +28,6 @@ PROPNODECHAR [a-zA-Z0-9,._+*#?@-] PATHCHAR ({PROPNODECHAR}|[/]) LABEL [a-zA-Z_][a-zA-Z0-9_]* -STRING \"([^\\"]|\\.)*\" -WS [[:space:]] -COMMENT "/*"([^*]|\*+[^*/])*\*+"/" -LINECOMMENT "//".*\n %{ #include "dtc.h" @@ -56,26 +52,29 @@ static int dts_version; /* = 0 */ DPRINT("\n"); \ BEGIN(V1); \ } - -static void push_input_file(const char *filename); -static int pop_input_file(void); %} %% -<*>"/include/"{WS}*{STRING} { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; - push_input_file(name); +<*>"/include/" BEGIN(INCLUDE); + +\"[^"\n]*\" { + yytext[strlen(yytext) - 1] = 0; + if (!push_input_file(yytext + 1)) { + /* Some unrecoverable error.*/ + exit(1); + } + BEGIN_DEFAULT(); } + <*><> { if (!pop_input_file()) { yyterminate(); } } -<*>{STRING} { - yylloc.file = srcpos_file; +<*>\"([^\\"]|\\.)*\" { + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, @@ -85,7 +84,7 @@ static int pop_input_file(void); } <*>"/dts-v1/" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; @@ -94,7 +93,7 @@ static int pop_input_file(void); } <*>"/memreserve/" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); @@ -102,7 +101,7 @@ static int pop_input_file(void); } <*>{LABEL}: { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); yylval.labelref = strdup(yytext); @@ -111,7 +110,7 @@ static int pop_input_file(void); } [bodh]# { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; if (*yytext == 'b') yylval.cbase = 2; @@ -126,7 +125,7 @@ static int pop_input_file(void); } [0-9a-fA-F]+ { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.literal = strdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); @@ -134,7 +133,7 @@ static int pop_input_file(void); } [0-9]+|0[xX][0-9a-fA-F]+ { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.literal = strdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); @@ -142,7 +141,7 @@ static int pop_input_file(void); } \&{LABEL} { /* label reference */ - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); yylval.labelref = strdup(yytext+1); @@ -150,7 +149,7 @@ static int pop_input_file(void); } "&{/"{PATHCHAR}+\} { /* new-style path reference */ - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); @@ -159,7 +158,7 @@ static int pop_input_file(void); } "&/"{PATHCHAR}+ { /* old-style path reference */ - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); yylval.labelref = strdup(yytext+1); @@ -167,7 +166,7 @@ static int pop_input_file(void); } [0-9a-fA-F]{2} { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); @@ -175,7 +174,7 @@ static int pop_input_file(void); } "]" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); @@ -183,7 +182,7 @@ static int pop_input_file(void); } {PROPNODECHAR}+ { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = strdup(yytext); @@ -191,19 +190,20 @@ static int pop_input_file(void); return DT_PROPNODENAME; } -"/incbin/" { - yylloc.file = srcpos_file; + +<*>[[:space:]]+ /* eat whitespace */ + +<*>"/*"([^*]|\*+[^*/])*\*+"/" { + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; - DPRINT("Binary Include\n"); - return DT_INCBIN; + DPRINT("Comment: %s\n", yytext); + /* eat comments */ } -<*>{WS}+ /* eat whitespace */ -<*>{COMMENT}+ /* eat C-style comments */ -<*>{LINECOMMENT}+ /* eat C++-style comments */ +<*>"//".*\n /* eat line comments */ <*>. { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); @@ -227,13 +227,14 @@ static int pop_input_file(void); */ struct incl_file { - struct dtc_file *file; + int filenum; + FILE *file; YY_BUFFER_STATE yy_prev_buf; int yy_prev_lineno; struct incl_file *prev; }; -static struct incl_file *incl_file_stack; +struct incl_file *incl_file_stack; /* @@ -244,34 +245,36 @@ static struct incl_file *incl_file_stack; static int incl_depth = 0; -static void push_input_file(const char *filename) +int push_input_file(const char *filename) { + FILE *f; struct incl_file *incl_file; - struct dtc_file *newfile; - struct search_path search, *searchptr = NULL; - - assert(filename); - if (incl_depth++ >= MAX_INCLUDE_DEPTH) - die("Includes nested too deeply"); + if (!filename) { + yyerror("No include file name given."); + return 0; + } - if (srcpos_file) { - search.dir = srcpos_file->dir; - search.next = NULL; - search.prev = NULL; - searchptr = &search; + if (incl_depth++ >= MAX_INCLUDE_DEPTH) { + yyerror("Includes nested too deeply"); + return 0; } - newfile = dtc_open_file(filename, searchptr); + f = dtc_open_file(filename); - incl_file = xmalloc(sizeof(struct incl_file)); + incl_file = malloc(sizeof(struct incl_file)); + if (!incl_file) { + yyerror("Can not allocate include file space."); + return 0; + } /* * Save current context. */ incl_file->yy_prev_buf = YY_CURRENT_BUFFER; incl_file->yy_prev_lineno = yylineno; - incl_file->file = srcpos_file; + incl_file->filenum = srcpos_filenum; + incl_file->file = yyin; incl_file->prev = incl_file_stack; incl_file_stack = incl_file; @@ -279,21 +282,23 @@ static void push_input_file(const char *filename) /* * Establish new context. */ - srcpos_file = newfile; + srcpos_filenum = lookup_file_name(filename, 0); yylineno = 1; - yyin = newfile->file; + yyin = f; yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + + return 1; } -static int pop_input_file(void) +int pop_input_file(void) { struct incl_file *incl_file; if (incl_file_stack == 0) return 0; - dtc_close_file(srcpos_file); + fclose(yyin); /* * Pop. @@ -308,13 +313,16 @@ static int pop_input_file(void) yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(incl_file->yy_prev_buf); yylineno = incl_file->yy_prev_lineno; - srcpos_file = incl_file->file; - yyin = incl_file->file ? incl_file->file->file : NULL; + srcpos_filenum = incl_file->filenum; + yyin = incl_file->file; /* * Free old state. */ free(incl_file); + if (YY_CURRENT_BUFFER == 0) + return 0; + return 1; } diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped b/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped index ac392cb040f6..d0f742460f92 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped +++ b/trunk/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped @@ -9,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 34 +#define YY_FLEX_SUBMINOR_VERSION 33 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -31,7 +31,7 @@ /* C99 systems have . Non-C99 systems may or may not. */ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#if __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. @@ -94,12 +94,11 @@ typedef unsigned int flex_uint32_t; #else /* ! __cplusplus */ -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) +#if __STDC__ #define YY_USE_CONST -#endif /* defined (__STDC__) */ +#endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST @@ -195,13 +194,11 @@ extern FILE *yyin, *yyout; /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). - * Given that the standard has decreed that size_t exists since 1989, - * I guess we can afford to depend on it. Manoj. */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; +typedef unsigned int yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE @@ -352,7 +349,7 @@ void yyfree (void * ); /* Begin user sect3 */ -#define yywrap(n) 1 +#define yywrap() 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -392,20 +389,19 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[104] = +static yyconst flex_int16_t yy_accept[94] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 21, 19, 16, 16, 19, 19, 19, 7, 7, 19, - 7, 19, 19, 19, 19, 13, 14, 14, 19, 8, - 8, 16, 0, 2, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 7, 7, 5, 0, 6, 0, 12, - 12, 14, 14, 8, 0, 11, 9, 0, 0, 0, - 0, 18, 0, 0, 0, 0, 8, 0, 17, 0, - 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - - 0, 4, 0 + 21, 19, 16, 16, 19, 19, 19, 8, 8, 19, + 8, 19, 19, 19, 19, 14, 15, 15, 19, 9, + 9, 16, 0, 3, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 8, 8, 6, 0, 7, 0, 2, + 0, 13, 13, 15, 15, 9, 0, 12, 10, 0, + 0, 0, 0, 18, 0, 0, 0, 2, 9, 0, + 17, 0, 0, 0, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 1, 0, 0, + 0, 5, 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -448,126 +444,122 @@ static yyconst flex_int32_t yy_meta[36] = 7, 7, 7, 8, 1 } ; -static yyconst flex_int16_t yy_base[117] = +static yyconst flex_int16_t yy_base[107] = { 0, - 0, 0, 30, 0, 44, 0, 67, 0, 97, 105, - 302, 303, 35, 44, 40, 94, 112, 0, 129, 152, - 296, 295, 159, 0, 176, 303, 0, 116, 95, 165, - 49, 46, 102, 303, 296, 0, 0, 288, 290, 293, - 264, 266, 270, 0, 0, 303, 0, 303, 264, 303, - 0, 0, 195, 101, 0, 0, 0, 0, 284, 125, - 277, 265, 225, 230, 216, 218, 0, 202, 224, 221, - 217, 107, 196, 188, 303, 206, 179, 186, 178, 185, - 183, 162, 161, 150, 169, 160, 145, 125, 303, 303, - 137, 109, 190, 103, 203, 167, 108, 197, 303, 123, - - 29, 303, 303, 215, 221, 226, 229, 234, 240, 246, - 250, 257, 265, 270, 275, 282 + 0, 0, 32, 0, 53, 0, 76, 0, 108, 111, + 280, 288, 37, 39, 33, 36, 106, 0, 123, 146, + 255, 251, 45, 0, 159, 288, 0, 53, 108, 172, + 114, 127, 158, 288, 245, 0, 0, 234, 235, 236, + 197, 195, 199, 0, 0, 288, 0, 288, 160, 288, + 183, 288, 0, 0, 183, 182, 0, 0, 0, 0, + 204, 189, 207, 288, 179, 187, 180, 194, 0, 171, + 288, 196, 178, 174, 288, 169, 169, 177, 165, 153, + 143, 155, 137, 118, 288, 122, 42, 288, 36, 36, + 40, 288, 288, 212, 218, 223, 229, 234, 239, 245, + + 251, 255, 262, 270, 275, 280 } ; -static yyconst flex_int16_t yy_def[117] = +static yyconst flex_int16_t yy_def[107] = { 0, - 103, 1, 1, 3, 3, 5, 103, 7, 3, 3, - 103, 103, 103, 103, 104, 105, 103, 106, 103, 19, - 19, 20, 103, 107, 20, 103, 108, 109, 105, 103, - 103, 103, 104, 103, 104, 110, 111, 103, 112, 113, - 103, 103, 103, 106, 19, 103, 20, 103, 103, 103, - 20, 108, 109, 103, 114, 110, 111, 115, 112, 112, - 113, 103, 103, 103, 103, 103, 114, 115, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 116, 103, 116, 103, 116, - - 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103 + 93, 1, 1, 3, 3, 5, 93, 7, 3, 3, + 93, 93, 93, 93, 94, 95, 93, 96, 93, 19, + 19, 20, 97, 98, 20, 93, 99, 100, 95, 93, + 93, 93, 94, 93, 94, 101, 102, 93, 103, 104, + 93, 93, 93, 96, 19, 93, 20, 93, 97, 93, + 97, 93, 20, 99, 100, 93, 105, 101, 102, 106, + 103, 103, 104, 93, 93, 93, 93, 94, 105, 106, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 93 } ; -static yyconst flex_int16_t yy_nxt[339] = +static yyconst flex_int16_t yy_nxt[324] = { 0, 12, 13, 14, 15, 12, 16, 12, 12, 12, 17, 18, 18, 18, 12, 19, 20, 20, 12, 12, 21, 19, 21, 19, 22, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 12, 12, 12, 32, 32, 102, 23, - 12, 12, 12, 34, 20, 32, 32, 32, 32, 20, - 20, 20, 20, 20, 24, 24, 24, 35, 25, 54, - 54, 54, 26, 25, 25, 25, 25, 12, 13, 14, - 15, 27, 12, 27, 27, 27, 23, 27, 27, 27, - 12, 28, 28, 28, 12, 12, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - - 12, 12, 29, 36, 103, 34, 17, 30, 31, 31, - 29, 54, 54, 54, 17, 30, 31, 31, 39, 35, - 52, 40, 52, 52, 52, 103, 78, 38, 38, 46, - 101, 60, 79, 41, 69, 97, 42, 94, 43, 45, - 45, 45, 46, 45, 47, 47, 93, 92, 45, 45, - 45, 45, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 39, 47, 91, 40, 90, - 99, 47, 47, 47, 47, 54, 54, 54, 89, 88, - 41, 55, 87, 49, 100, 43, 51, 51, 51, 86, - 51, 95, 95, 96, 85, 51, 51, 51, 51, 52, - - 99, 52, 52, 52, 95, 95, 96, 84, 46, 83, - 82, 81, 39, 79, 100, 33, 33, 33, 33, 33, - 33, 33, 33, 37, 80, 77, 37, 37, 37, 44, - 40, 44, 50, 76, 50, 52, 75, 52, 74, 52, - 52, 53, 73, 53, 53, 53, 53, 56, 56, 56, - 72, 56, 56, 57, 71, 57, 57, 59, 59, 59, - 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, - 61, 61, 61, 67, 70, 67, 68, 68, 68, 62, - 68, 68, 98, 98, 98, 98, 98, 98, 98, 98, - 60, 66, 65, 64, 63, 62, 60, 58, 103, 48, - - 48, 103, 11, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103 + 20, 20, 20, 12, 12, 23, 34, 12, 32, 32, + 32, 32, 12, 12, 12, 36, 20, 33, 50, 92, + 35, 20, 20, 20, 20, 20, 15, 54, 91, 54, + 54, 54, 51, 24, 24, 24, 46, 25, 90, 38, + 89, 26, 25, 25, 25, 25, 12, 13, 14, 15, + 27, 12, 27, 27, 27, 17, 27, 27, 27, 12, + 28, 28, 28, 12, 12, 28, 28, 28, 28, 28, + + 28, 28, 28, 28, 28, 28, 28, 28, 28, 12, + 12, 15, 39, 29, 15, 40, 29, 93, 30, 31, + 31, 30, 31, 31, 56, 56, 56, 41, 32, 32, + 42, 88, 43, 45, 45, 45, 46, 45, 47, 47, + 87, 38, 45, 45, 45, 45, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 86, + 47, 34, 33, 50, 85, 47, 47, 47, 47, 53, + 53, 53, 84, 53, 83, 35, 82, 51, 53, 53, + 53, 53, 56, 56, 56, 93, 68, 54, 57, 54, + 54, 54, 56, 56, 56, 62, 46, 34, 71, 81, + + 80, 79, 78, 77, 76, 75, 74, 73, 72, 64, + 62, 35, 33, 33, 33, 33, 33, 33, 33, 33, + 37, 67, 66, 37, 37, 37, 44, 65, 44, 49, + 49, 49, 49, 49, 49, 49, 49, 52, 64, 52, + 54, 62, 54, 60, 54, 54, 55, 93, 55, 55, + 55, 55, 58, 58, 58, 48, 58, 58, 59, 48, + 59, 59, 61, 61, 61, 61, 61, 61, 61, 61, + 63, 63, 63, 63, 63, 63, 63, 63, 69, 93, + 69, 70, 70, 70, 93, 70, 70, 11, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93 } ; -static yyconst flex_int16_t yy_chk[339] = +static yyconst flex_int16_t yy_chk[324] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 13, 13, 101, 3, - 3, 3, 3, 15, 3, 14, 14, 32, 32, 3, - 3, 3, 3, 3, 5, 5, 5, 15, 5, 31, - 31, 31, 5, 5, 5, 5, 5, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 1, 1, 1, 1, 1, 3, 15, 3, 13, 13, + 14, 14, 3, 3, 3, 16, 3, 23, 23, 91, + 15, 3, 3, 3, 3, 3, 5, 28, 90, 28, + 28, 28, 23, 5, 5, 5, 28, 5, 89, 16, + 87, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 9, 16, 29, 33, 9, 9, 9, 9, - 10, 54, 54, 54, 10, 10, 10, 10, 17, 33, - 28, 17, 28, 28, 28, 100, 72, 16, 29, 28, - 97, 60, 72, 17, 60, 94, 17, 92, 17, 19, - 19, 19, 19, 19, 19, 19, 91, 88, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 20, 20, 20, 23, 20, 87, 23, 86, - 96, 20, 20, 20, 20, 30, 30, 30, 85, 84, - 23, 30, 83, 23, 96, 23, 25, 25, 25, 82, - 25, 93, 93, 93, 81, 25, 25, 25, 25, 53, - - 98, 53, 53, 53, 95, 95, 95, 80, 53, 79, - 78, 77, 76, 74, 98, 104, 104, 104, 104, 104, - 104, 104, 104, 105, 73, 71, 105, 105, 105, 106, - 70, 106, 107, 69, 107, 108, 68, 108, 66, 108, - 108, 109, 65, 109, 109, 109, 109, 110, 110, 110, - 64, 110, 110, 111, 63, 111, 111, 112, 112, 112, - 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, - 113, 113, 113, 114, 62, 114, 115, 115, 115, 61, - 115, 115, 116, 116, 116, 116, 116, 116, 116, 116, - 59, 49, 43, 42, 41, 40, 39, 38, 35, 22, - - 21, 11, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 9, 17, 9, 10, 17, 10, 29, 9, 9, + 9, 10, 10, 10, 31, 31, 31, 17, 32, 32, + 17, 86, 17, 19, 19, 19, 19, 19, 19, 19, + 84, 29, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 20, 20, 20, 83, + 20, 33, 49, 49, 82, 20, 20, 20, 20, 25, + 25, 25, 81, 25, 80, 33, 79, 49, 25, 25, + 25, 25, 30, 30, 30, 51, 51, 55, 30, 55, + 55, 55, 56, 56, 56, 62, 55, 68, 62, 78, + + 77, 76, 74, 73, 72, 70, 67, 66, 65, 63, + 61, 68, 94, 94, 94, 94, 94, 94, 94, 94, + 95, 43, 42, 95, 95, 95, 96, 41, 96, 97, + 97, 97, 97, 97, 97, 97, 97, 98, 40, 98, + 99, 39, 99, 38, 99, 99, 100, 35, 100, 100, + 100, 100, 101, 101, 101, 22, 101, 101, 102, 21, + 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, + 104, 104, 104, 104, 104, 104, 104, 104, 105, 11, + 105, 106, 106, 106, 0, 106, 106, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93 } ; /* Table of booleans, true if rule could match eol. */ static yyconst flex_int32_t yy_rule_can_match_eol[21] = { 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, }; static yy_state_type yy_last_accepting_state; @@ -608,7 +600,7 @@ char *yytext; -#line 37 "dtc-lexer.l" +#line 33 "dtc-lexer.l" #include "dtc.h" #include "srcpos.h" #include "dtc-parser.tab.h" @@ -631,10 +623,7 @@ static int dts_version; /* = 0 */ DPRINT("\n"); \ BEGIN(V1); \ } - -static void push_input_file(const char *filename); -static int pop_input_file(void); -#line 638 "dtc-lexer.lex.c" +#line 627 "dtc-lexer.lex.c" #define INITIAL 0 #define INCLUDE 1 @@ -696,7 +685,7 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -707,7 +696,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - int n; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -789,9 +778,9 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 64 "dtc-lexer.l" +#line 57 "dtc-lexer.l" -#line 795 "dtc-lexer.lex.c" +#line 784 "dtc-lexer.lex.c" if ( !(yy_init) ) { @@ -844,13 +833,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 104 ) + if ( yy_current_state >= 94 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 303 ); + while ( yy_base[yy_current_state] != 288 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -885,13 +874,20 @@ do_action: /* This label is used only to access EOF actions. */ goto yy_find_action; case 1: -/* rule 1 can match eol */ YY_RULE_SETUP -#line 65 "dtc-lexer.l" +#line 58 "dtc-lexer.l" +BEGIN(INCLUDE); + YY_BREAK +case 2: +YY_RULE_SETUP +#line 60 "dtc-lexer.l" { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; - push_input_file(name); + yytext[strlen(yytext) - 1] = 0; + if (!push_input_file(yytext + 1)) { + /* Some unrecoverable error.*/ + exit(1); + } + BEGIN_DEFAULT(); } YY_BREAK case YY_STATE_EOF(INITIAL): @@ -899,19 +895,19 @@ case YY_STATE_EOF(INCLUDE): case YY_STATE_EOF(BYTESTRING): case YY_STATE_EOF(PROPNODENAME): case YY_STATE_EOF(V1): -#line 71 "dtc-lexer.l" +#line 70 "dtc-lexer.l" { if (!pop_input_file()) { yyterminate(); } } YY_BREAK -case 2: -/* rule 2 can match eol */ +case 3: +/* rule 3 can match eol */ YY_RULE_SETUP -#line 77 "dtc-lexer.l" +#line 76 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, @@ -920,11 +916,11 @@ YY_RULE_SETUP return DT_STRING; } YY_BREAK -case 3: +case 4: YY_RULE_SETUP -#line 87 "dtc-lexer.l" +#line 86 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; @@ -932,22 +928,22 @@ YY_RULE_SETUP return DT_V1; } YY_BREAK -case 4: +case 5: YY_RULE_SETUP -#line 96 "dtc-lexer.l" +#line 95 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; } YY_BREAK -case 5: +case 6: YY_RULE_SETUP -#line 104 "dtc-lexer.l" +#line 103 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); yylval.labelref = strdup(yytext); @@ -955,11 +951,11 @@ YY_RULE_SETUP return DT_LABEL; } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 113 "dtc-lexer.l" +#line 112 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; if (*yytext == 'b') yylval.cbase = 2; @@ -973,44 +969,44 @@ YY_RULE_SETUP return DT_BASE; } YY_BREAK -case 7: +case 8: YY_RULE_SETUP -#line 128 "dtc-lexer.l" +#line 127 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.literal = strdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LEGACYLITERAL; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP -#line 136 "dtc-lexer.l" +#line 135 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.literal = strdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LITERAL; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP -#line 144 "dtc-lexer.l" +#line 143 "dtc-lexer.l" { /* label reference */ - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); yylval.labelref = strdup(yytext+1); return DT_REF; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 152 "dtc-lexer.l" +#line 151 "dtc-lexer.l" { /* new-style path reference */ - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); @@ -1018,44 +1014,44 @@ YY_RULE_SETUP return DT_REF; } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 161 "dtc-lexer.l" +#line 160 "dtc-lexer.l" { /* old-style path reference */ - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); yylval.labelref = strdup(yytext+1); return DT_REF; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP -#line 169 "dtc-lexer.l" +#line 168 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); return DT_BYTE; } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 177 "dtc-lexer.l" +#line 176 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); return ']'; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP -#line 185 "dtc-lexer.l" +#line 184 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = strdup(yytext); @@ -1063,39 +1059,34 @@ YY_RULE_SETUP return DT_PROPNODENAME; } YY_BREAK -case 15: -YY_RULE_SETUP -#line 194 "dtc-lexer.l" -{ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK case 16: /* rule 16 can match eol */ YY_RULE_SETUP -#line 201 "dtc-lexer.l" +#line 194 "dtc-lexer.l" /* eat whitespace */ YY_BREAK case 17: /* rule 17 can match eol */ YY_RULE_SETUP -#line 202 "dtc-lexer.l" -/* eat C-style comments */ +#line 196 "dtc-lexer.l" +{ + yylloc.filenum = srcpos_filenum; + yylloc.first_line = yylineno; + DPRINT("Comment: %s\n", yytext); + /* eat comments */ + } YY_BREAK case 18: /* rule 18 can match eol */ YY_RULE_SETUP #line 203 "dtc-lexer.l" -/* eat C++-style comments */ +/* eat line comments */ YY_BREAK case 19: YY_RULE_SETUP #line 205 "dtc-lexer.l" { - yylloc.file = srcpos_file; + yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); @@ -1116,7 +1107,7 @@ YY_RULE_SETUP #line 222 "dtc-lexer.l" ECHO; YY_BREAK -#line 1120 "dtc-lexer.lex.c" +#line 1111 "dtc-lexer.lex.c" case YY_END_OF_BUFFER: { @@ -1369,14 +1360,6 @@ static int yy_get_next_buffer (void) else ret_val = EOB_ACT_CONTINUE_SCAN; - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; @@ -1406,7 +1389,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 104 ) + if ( yy_current_state >= 94 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1434,11 +1417,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 104 ) + if ( yy_current_state >= 94 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 103); + yy_is_jam = (yy_current_state == 93); return yy_is_jam ? 0 : yy_current_state; } @@ -1760,9 +1743,7 @@ static void yyensure_buffer_stack (void) (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; @@ -1780,8 +1761,6 @@ static void yyensure_buffer_stack (void) ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); @@ -2093,13 +2072,14 @@ void yyfree (void * ptr ) */ struct incl_file { - struct dtc_file *file; + int filenum; + FILE *file; YY_BUFFER_STATE yy_prev_buf; int yy_prev_lineno; struct incl_file *prev; }; -static struct incl_file *incl_file_stack; +struct incl_file *incl_file_stack; /* @@ -2110,34 +2090,36 @@ static struct incl_file *incl_file_stack; static int incl_depth = 0; -static void push_input_file(const char *filename) +int push_input_file(const char *filename) { + FILE *f; struct incl_file *incl_file; - struct dtc_file *newfile; - struct search_path search, *searchptr = NULL; - assert(filename); - - if (incl_depth++ >= MAX_INCLUDE_DEPTH) - die("Includes nested too deeply"); + if (!filename) { + yyerror("No include file name given."); + return 0; + } - if (srcpos_file) { - search.dir = srcpos_file->dir; - search.next = NULL; - search.prev = NULL; - searchptr = &search; + if (incl_depth++ >= MAX_INCLUDE_DEPTH) { + yyerror("Includes nested too deeply"); + return 0; } - newfile = dtc_open_file(filename, searchptr); + f = dtc_open_file(filename); - incl_file = xmalloc(sizeof(struct incl_file)); + incl_file = malloc(sizeof(struct incl_file)); + if (!incl_file) { + yyerror("Can not allocate include file space."); + return 0; + } /* * Save current context. */ incl_file->yy_prev_buf = YY_CURRENT_BUFFER; incl_file->yy_prev_lineno = yylineno; - incl_file->file = srcpos_file; + incl_file->filenum = srcpos_filenum; + incl_file->file = yyin; incl_file->prev = incl_file_stack; incl_file_stack = incl_file; @@ -2145,21 +2127,23 @@ static void push_input_file(const char *filename) /* * Establish new context. */ - srcpos_file = newfile; + srcpos_filenum = lookup_file_name(filename, 0); yylineno = 1; - yyin = newfile->file; + yyin = f; yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); + + return 1; } -static int pop_input_file(void) +int pop_input_file(void) { struct incl_file *incl_file; if (incl_file_stack == 0) return 0; - dtc_close_file(srcpos_file); + fclose(yyin); /* * Pop. @@ -2174,14 +2158,17 @@ static int pop_input_file(void) yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(incl_file->yy_prev_buf); yylineno = incl_file->yy_prev_lineno; - srcpos_file = incl_file->file; - yyin = incl_file->file ? incl_file->file->file : NULL; + srcpos_filenum = incl_file->filenum; + yyin = incl_file->file; /* * Free old state. */ free(incl_file); + if (YY_CURRENT_BUFFER == 0) + return 0; + return 1; } diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped b/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped index 27129377e5d2..28e6ec0296a1 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped +++ b/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped @@ -75,8 +75,7 @@ DT_BYTE = 264, DT_STRING = 265, DT_LABEL = 266, - DT_REF = 267, - DT_INCBIN = 268 + DT_REF = 267 }; #endif /* Tokens. */ @@ -90,7 +89,6 @@ #define DT_STRING 265 #define DT_LABEL 266 #define DT_REF 267 -#define DT_INCBIN 268 @@ -98,17 +96,14 @@ /* Copy the first part of user declarations. */ #line 23 "dtc-parser.y" -#include - #include "dtc.h" #include "srcpos.h" -extern int yylex(void); +int yylex(void); +unsigned long long eval_literal(const char *s, int base, int bits); extern struct boot_info *the_boot_info; -extern int treesource_error; -static unsigned long long eval_literal(const char *s, int base, int bits); /* Enabling traces. */ @@ -131,16 +126,16 @@ static unsigned long long eval_literal(const char *s, int base, int bits); #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 37 "dtc-parser.y" +#line 34 "dtc-parser.y" { char *propnodename; char *literal; char *labelref; unsigned int cbase; - uint8_t byte; + u8 byte; struct data data; - uint64_t addr; + u64 addr; cell_t cell; struct property *prop; struct property *proplist; @@ -149,7 +144,7 @@ typedef union YYSTYPE struct reserve_info *re; } /* Line 187 of yacc.c. */ -#line 153 "dtc-parser.tab.c" +#line 148 "dtc-parser.tab.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -174,7 +169,7 @@ typedef struct YYLTYPE /* Line 216 of yacc.c. */ -#line 178 "dtc-parser.tab.c" +#line 173 "dtc-parser.tab.c" #ifdef short # undef short @@ -391,20 +386,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 9 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 73 +#define YYLAST 60 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 27 +#define YYNTOKENS 24 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 20 /* YYNRULES -- Number of rules. */ -#define YYNRULES 45 +#define YYNRULES 43 /* YYNRULES -- Number of states. */ -#define YYNSTATES 76 +#define YYNSTATES 67 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 268 +#define YYMAXUTOK 267 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -416,15 +411,15 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 24, 26, 2, 2, 25, 15, 2, 16, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, - 20, 19, 21, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 23, 14, 2, 15, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, + 19, 18, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 22, 2, 23, 2, 2, 2, 2, 2, 2, + 2, 21, 2, 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 17, 2, 18, 2, 2, 2, 2, + 2, 2, 2, 16, 2, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -438,7 +433,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13 + 5, 6, 7, 8, 9, 10, 11, 12 }; #if YYDEBUG @@ -448,39 +443,37 @@ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 8, 11, 12, 15, 21, 22, 25, 27, 34, 36, 38, 41, 47, 48, 51, 57, 61, - 64, 69, 74, 77, 87, 93, 96, 97, 100, 103, - 104, 107, 110, 113, 114, 116, 118, 121, 122, 125, - 128, 129, 132, 135, 139, 140 + 64, 69, 74, 77, 80, 81, 84, 87, 88, 91, + 94, 97, 98, 100, 102, 105, 106, 109, 112, 113, + 116, 119, 123, 124 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 28, 0, -1, 3, 14, 29, 34, -1, 31, 34, - -1, -1, 30, 29, -1, 46, 4, 33, 33, 14, - -1, -1, 32, 31, -1, 30, -1, 46, 4, 33, - 15, 33, 14, -1, 6, -1, 7, -1, 16, 35, - -1, 17, 36, 44, 18, 14, -1, -1, 36, 37, - -1, 46, 5, 19, 38, 14, -1, 46, 5, 14, - -1, 39, 10, -1, 39, 20, 40, 21, -1, 39, - 22, 43, 23, -1, 39, 12, -1, 39, 13, 24, - 10, 25, 33, 25, 33, 26, -1, 39, 13, 24, - 10, 26, -1, 38, 11, -1, -1, 38, 25, -1, - 39, 11, -1, -1, 40, 42, -1, 40, 12, -1, - 40, 11, -1, -1, 8, -1, 6, -1, 41, 7, - -1, -1, 43, 9, -1, 43, 11, -1, -1, 45, - 44, -1, 45, 37, -1, 46, 5, 35, -1, -1, - 11, -1 + 25, 0, -1, 3, 13, 26, 31, -1, 28, 31, + -1, -1, 27, 26, -1, 43, 4, 30, 30, 13, + -1, -1, 29, 28, -1, 27, -1, 43, 4, 30, + 14, 30, 13, -1, 6, -1, 7, -1, 15, 32, + -1, 16, 33, 41, 17, 13, -1, -1, 33, 34, + -1, 43, 5, 18, 35, 13, -1, 43, 5, 13, + -1, 36, 10, -1, 36, 19, 37, 20, -1, 36, + 21, 40, 22, -1, 36, 12, -1, 35, 11, -1, + -1, 35, 23, -1, 36, 11, -1, -1, 37, 39, + -1, 37, 12, -1, 37, 11, -1, -1, 8, -1, + 6, -1, 38, 7, -1, -1, 40, 9, -1, 40, + 11, -1, -1, 42, 41, -1, 42, 34, -1, 43, + 5, 32, -1, -1, 11, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 89, 89, 93, 101, 104, 111, 119, 122, 129, - 133, 140, 144, 151, 158, 166, 169, 176, 180, 187, - 191, 195, 199, 203, 220, 231, 239, 242, 246, 254, - 257, 261, 266, 274, 277, 281, 285, 293, 296, 300, - 308, 311, 315, 323, 331, 334 + 0, 85, 85, 89, 97, 100, 107, 115, 118, 125, + 129, 136, 140, 147, 154, 162, 165, 172, 176, 183, + 187, 191, 195, 199, 207, 210, 214, 222, 225, 229, + 234, 242, 245, 249, 253, 261, 264, 268, 276, 279, + 283, 291, 299, 302 }; #endif @@ -491,12 +484,12 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE", - "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'", - "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','", - "')'", "$accept", "sourcefile", "memreserves", "memreserve", - "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef", - "proplist", "propdef", "propdata", "propdataprefix", "celllist", - "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0 + "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'", + "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile", + "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr", + "devicetree", "nodedef", "proplist", "propdef", "propdata", + "propdataprefix", "celllist", "cellbase", "cellval", "bytestring", + "subnodes", "subnode", "label", 0 }; #endif @@ -506,19 +499,19 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 59, 45, 47, 123, 125, 61, - 60, 62, 91, 93, 40, 44, 41 + 265, 266, 267, 59, 45, 47, 123, 125, 61, 60, + 62, 91, 93, 44 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 27, 28, 28, 29, 29, 30, 31, 31, 32, - 32, 33, 33, 34, 35, 36, 36, 37, 37, 38, - 38, 38, 38, 38, 38, 38, 39, 39, 39, 40, - 40, 40, 40, 41, 41, 42, 42, 43, 43, 43, - 44, 44, 44, 45, 46, 46 + 0, 24, 25, 25, 26, 26, 27, 28, 28, 29, + 29, 30, 30, 31, 32, 33, 33, 34, 34, 35, + 35, 35, 35, 35, 36, 36, 36, 37, 37, 37, + 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, + 41, 42, 43, 43 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -526,9 +519,9 @@ static const yytype_uint8 yyr2[] = { 0, 2, 4, 2, 0, 2, 5, 0, 2, 1, 6, 1, 1, 2, 5, 0, 2, 5, 3, 2, - 4, 4, 2, 9, 5, 2, 0, 2, 2, 0, - 2, 2, 2, 0, 1, 1, 2, 0, 2, 2, - 0, 2, 2, 3, 0, 1 + 4, 4, 2, 2, 0, 2, 2, 0, 2, 2, + 2, 0, 1, 1, 2, 0, 2, 2, 0, 2, + 2, 3, 0, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -536,86 +529,81 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 7, 0, 45, 0, 9, 0, 7, 0, 4, 1, + 7, 0, 43, 0, 9, 0, 7, 0, 4, 1, 0, 3, 8, 0, 0, 4, 0, 15, 13, 11, - 12, 0, 2, 5, 0, 40, 0, 0, 0, 16, - 0, 40, 0, 0, 6, 0, 42, 41, 0, 10, - 14, 18, 26, 43, 0, 0, 25, 17, 27, 19, - 28, 22, 0, 29, 37, 0, 33, 0, 0, 35, - 34, 32, 31, 20, 0, 30, 38, 39, 21, 0, - 24, 36, 0, 0, 0, 23 + 12, 0, 2, 5, 0, 38, 0, 0, 0, 16, + 0, 38, 0, 0, 6, 0, 40, 39, 0, 10, + 14, 18, 24, 41, 0, 0, 23, 17, 25, 19, + 26, 22, 27, 35, 31, 0, 33, 32, 30, 29, + 20, 0, 28, 36, 37, 21, 34 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 3, 14, 4, 5, 6, 27, 11, 18, 25, - 29, 44, 45, 56, 64, 65, 57, 30, 31, 7 + 29, 44, 45, 54, 61, 62, 55, 30, 31, 7 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -14 +#define YYPACT_NINF -13 static const yytype_int8 yypact[] = { - 30, -11, -14, 7, -14, -1, 27, 13, 27, -14, - 8, -14, -14, 40, -1, 27, 35, -14, -14, -14, - -14, 21, -14, -14, 40, 24, 40, 28, 40, -14, - 32, 24, 46, 38, -14, 39, -14, -14, 26, -14, - -14, -14, -14, -14, -9, 10, -14, -14, -14, -14, - -14, -14, 31, -14, -14, 44, -2, 3, 23, -14, - -14, -14, -14, -14, 50, -14, -14, -14, -14, 40, - -14, -14, 33, 40, 36, -14 + 23, 11, -13, 37, -13, -4, 18, 39, 18, -13, + 28, -13, -13, 34, -4, 18, 41, -13, -13, -13, + -13, 25, -13, -13, 34, -3, 34, 33, 34, -13, + 30, -3, 43, 36, -13, 38, -13, -13, 20, -13, + -13, -13, -13, -13, 2, 9, -13, -13, -13, -13, + -13, -13, -13, -13, -2, -6, -13, -13, -13, -13, + -13, 45, -13, -13, -13, -13, -13 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -14, -14, 48, 29, 53, -14, -13, 47, 34, -14, - 37, -14, -14, -14, -14, -14, -14, 42, -14, -7 + -13, -13, 35, 27, 47, -13, -12, 40, 17, -13, + 26, -13, -13, -13, -13, -13, -13, 29, -13, -8 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -45 +#define YYTABLE_NINF -43 static const yytype_int8 yytable[] = { - 21, 16, 46, 8, 59, 47, 60, 9, 16, 61, - 62, 28, 66, 33, 67, 10, 48, 13, 32, 63, - 49, 50, 51, 52, 32, 17, 68, 19, 20, -44, - 53, -44, 54, 1, -44, 2, 26, 15, 2, 24, - 41, 2, 34, 17, 15, 42, 19, 20, 69, 70, - 35, 38, 39, 40, 58, 55, 72, 71, 73, 12, - 74, 22, 75, 23, 0, 0, 0, 0, 36, 0, - 0, 0, 43, 37 + 16, 21, -42, 63, 56, 64, 57, 16, 2, 58, + 59, 10, 28, 46, 33, 47, 65, 32, 60, 49, + 50, 51, -42, 32, 8, 48, 1, -42, 52, 2, + 53, 19, 20, 41, 2, 15, 17, 9, 42, 26, + 19, 20, 15, 13, 17, 24, 34, 35, 38, 39, + 23, 40, 66, 12, 22, 43, 0, 36, 0, 0, + 37 }; static const yytype_int8 yycheck[] = { - 13, 8, 11, 14, 6, 14, 8, 0, 15, 11, - 12, 24, 9, 26, 11, 16, 25, 4, 25, 21, - 10, 11, 12, 13, 31, 17, 23, 6, 7, 5, - 20, 4, 22, 3, 4, 11, 15, 8, 11, 4, - 14, 11, 14, 17, 15, 19, 6, 7, 25, 26, - 18, 5, 14, 14, 10, 24, 69, 7, 25, 6, - 73, 14, 26, 15, -1, -1, -1, -1, 31, -1, - -1, -1, 38, 31 + 8, 13, 5, 9, 6, 11, 8, 15, 11, 11, + 12, 15, 24, 11, 26, 13, 22, 25, 20, 10, + 11, 12, 4, 31, 13, 23, 3, 4, 19, 11, + 21, 6, 7, 13, 11, 8, 16, 0, 18, 14, + 6, 7, 15, 4, 16, 4, 13, 17, 5, 13, + 15, 13, 7, 6, 14, 38, -1, 31, -1, -1, + 31 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 11, 28, 30, 31, 32, 46, 14, 0, - 16, 34, 31, 4, 29, 30, 46, 17, 35, 6, - 7, 33, 34, 29, 4, 36, 15, 33, 33, 37, - 44, 45, 46, 33, 14, 18, 37, 44, 5, 14, - 14, 14, 19, 35, 38, 39, 11, 14, 25, 10, - 11, 12, 13, 20, 22, 24, 40, 43, 10, 6, - 8, 11, 12, 21, 41, 42, 9, 11, 23, 25, - 26, 7, 33, 25, 33, 26 + 0, 3, 11, 25, 27, 28, 29, 43, 13, 0, + 15, 31, 28, 4, 26, 27, 43, 16, 32, 6, + 7, 30, 31, 26, 4, 33, 14, 30, 30, 34, + 41, 42, 43, 30, 13, 17, 34, 41, 5, 13, + 13, 13, 18, 32, 35, 36, 11, 13, 23, 10, + 11, 12, 19, 21, 37, 40, 6, 8, 11, 12, + 20, 38, 39, 9, 11, 22, 7 }; #define yyerrok (yyerrstatus = 0) @@ -1452,323 +1440,289 @@ yyreduce: switch (yyn) { case 2: -#line 90 "dtc-parser.y" +#line 86 "dtc-parser.y" { - the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0); + the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node)); ;} break; case 3: -#line 94 "dtc-parser.y" +#line 90 "dtc-parser.y" { - the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0); + the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node)); ;} break; case 4: -#line 101 "dtc-parser.y" +#line 97 "dtc-parser.y" { (yyval.re) = NULL; ;} break; case 5: -#line 105 "dtc-parser.y" +#line 101 "dtc-parser.y" { (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ;} break; case 6: -#line 112 "dtc-parser.y" +#line 108 "dtc-parser.y" { (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref)); ;} break; case 7: -#line 119 "dtc-parser.y" +#line 115 "dtc-parser.y" { (yyval.re) = NULL; ;} break; case 8: -#line 123 "dtc-parser.y" +#line 119 "dtc-parser.y" { (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ;} break; case 9: -#line 130 "dtc-parser.y" +#line 126 "dtc-parser.y" { (yyval.re) = (yyvsp[(1) - (1)].re); ;} break; case 10: -#line 134 "dtc-parser.y" +#line 130 "dtc-parser.y" { (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref)); ;} break; case 11: -#line 141 "dtc-parser.y" +#line 137 "dtc-parser.y" { (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); ;} break; case 12: -#line 145 "dtc-parser.y" +#line 141 "dtc-parser.y" { (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64); ;} break; case 13: -#line 152 "dtc-parser.y" +#line 148 "dtc-parser.y" { (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL); ;} break; case 14: -#line 159 "dtc-parser.y" +#line 155 "dtc-parser.y" { (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); ;} break; case 15: -#line 166 "dtc-parser.y" +#line 162 "dtc-parser.y" { (yyval.proplist) = NULL; ;} break; case 16: -#line 170 "dtc-parser.y" +#line 166 "dtc-parser.y" { (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); ;} break; case 17: -#line 177 "dtc-parser.y" +#line 173 "dtc-parser.y" { (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref)); ;} break; case 18: -#line 181 "dtc-parser.y" +#line 177 "dtc-parser.y" { (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref)); ;} break; case 19: -#line 188 "dtc-parser.y" +#line 184 "dtc-parser.y" { (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); ;} break; case 20: -#line 192 "dtc-parser.y" +#line 188 "dtc-parser.y" { (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ;} break; case 21: -#line 196 "dtc-parser.y" +#line 192 "dtc-parser.y" { (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ;} break; case 22: -#line 200 "dtc-parser.y" +#line 196 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); ;} break; case 23: -#line 204 "dtc-parser.y" - { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path); - struct data d = empty_data; - - if ((yyvsp[(6) - (9)].addr) != 0) - if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) - yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)(yyvsp[(6) - (9)].addr), - (yyvsp[(4) - (9)].data).val, strerror(errno)); - - d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr)); - - (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); - dtc_close_file(file); - ;} - break; - - case 24: -#line 221 "dtc-parser.y" - { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path); - struct data d = empty_data; - - d = data_copy_file(file->file, -1); - - (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); - dtc_close_file(file); - ;} - break; - - case 25: -#line 232 "dtc-parser.y" +#line 200 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 26: -#line 239 "dtc-parser.y" + case 24: +#line 207 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 27: -#line 243 "dtc-parser.y" + case 25: +#line 211 "dtc-parser.y" { (yyval.data) = (yyvsp[(1) - (2)].data); ;} break; - case 28: -#line 247 "dtc-parser.y" + case 26: +#line 215 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 29: -#line 254 "dtc-parser.y" + case 27: +#line 222 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 30: -#line 258 "dtc-parser.y" + case 28: +#line 226 "dtc-parser.y" { (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); ;} break; - case 31: -#line 262 "dtc-parser.y" + case 29: +#line 230 "dtc-parser.y" { (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, (yyvsp[(2) - (2)].labelref)), -1); ;} break; - case 32: -#line 267 "dtc-parser.y" + case 30: +#line 235 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 33: -#line 274 "dtc-parser.y" + case 31: +#line 242 "dtc-parser.y" { (yyval.cbase) = 16; ;} break; - case 35: -#line 282 "dtc-parser.y" + case 33: +#line 250 "dtc-parser.y" { (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); ;} break; - case 36: -#line 286 "dtc-parser.y" + case 34: +#line 254 "dtc-parser.y" { (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32); ;} break; - case 37: -#line 293 "dtc-parser.y" + case 35: +#line 261 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 38: -#line 297 "dtc-parser.y" + case 36: +#line 265 "dtc-parser.y" { (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); ;} break; - case 39: -#line 301 "dtc-parser.y" + case 37: +#line 269 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 40: -#line 308 "dtc-parser.y" + case 38: +#line 276 "dtc-parser.y" { (yyval.nodelist) = NULL; ;} break; - case 41: -#line 312 "dtc-parser.y" + case 39: +#line 280 "dtc-parser.y" { (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); ;} break; - case 42: -#line 316 "dtc-parser.y" + case 40: +#line 284 "dtc-parser.y" { - yyerror("syntax error: properties must precede subnodes"); + yyerror("syntax error: properties must precede subnodes\n"); YYERROR; ;} break; - case 43: -#line 324 "dtc-parser.y" + case 41: +#line 292 "dtc-parser.y" { (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref)); ;} break; - case 44: -#line 331 "dtc-parser.y" + case 42: +#line 299 "dtc-parser.y" { (yyval.labelref) = NULL; ;} break; - case 45: -#line 335 "dtc-parser.y" + case 43: +#line 303 "dtc-parser.y" { (yyval.labelref) = (yyvsp[(1) - (1)].labelref); ;} @@ -1776,7 +1730,7 @@ yyreduce: /* Line 1267 of yacc.c. */ -#line 1780 "dtc-parser.tab.c" +#line 1734 "dtc-parser.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1996,32 +1950,21 @@ yyreturn: } -#line 340 "dtc-parser.y" +#line 308 "dtc-parser.y" -void yyerrorf(char const *s, ...) +void yyerror (char const *s) { - const char *fname = srcpos_file ? srcpos_file->name : ""; - va_list va; - va_start(va, s); + const char *fname = srcpos_filename_for_num(yylloc.filenum); if (strcmp(fname, "-") == 0) fname = "stdin"; - fprintf(stderr, "%s:%d ", fname, yylloc.first_line); - vfprintf(stderr, s, va); - fprintf(stderr, "\n"); - - treesource_error = 1; - va_end(va); -} - -void yyerror (char const *s) -{ - yyerrorf("%s", s); + fprintf(stderr, "%s:%d %s\n", + fname, yylloc.first_line, s); } -static unsigned long long eval_literal(const char *s, int base, int bits) +unsigned long long eval_literal(const char *s, int base, int bits) { unsigned long long val; char *e; diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped b/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped index ba99100d55c9..4707b029ed25 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped +++ b/trunk/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped @@ -48,8 +48,7 @@ DT_BYTE = 264, DT_STRING = 265, DT_LABEL = 266, - DT_REF = 267, - DT_INCBIN = 268 + DT_REF = 267 }; #endif /* Tokens. */ @@ -63,23 +62,22 @@ #define DT_STRING 265 #define DT_LABEL 266 #define DT_REF 267 -#define DT_INCBIN 268 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 37 "dtc-parser.y" +#line 34 "dtc-parser.y" { char *propnodename; char *literal; char *labelref; unsigned int cbase; - uint8_t byte; + u8 byte; struct data data; - uint64_t addr; + u64 addr; cell_t cell; struct property *prop; struct property *proplist; @@ -88,7 +86,7 @@ typedef union YYSTYPE struct reserve_info *re; } /* Line 1489 of yacc.c. */ -#line 92 "dtc-parser.tab.h" +#line 90 "dtc-parser.tab.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc-parser.y b/trunk/arch/powerpc/boot/dtc-src/dtc-parser.y index b2ab562420ea..002ea7fef184 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc-parser.y +++ b/trunk/arch/powerpc/boot/dtc-src/dtc-parser.y @@ -21,17 +21,14 @@ %locations %{ -#include - #include "dtc.h" #include "srcpos.h" -extern int yylex(void); +int yylex(void); +unsigned long long eval_literal(const char *s, int base, int bits); extern struct boot_info *the_boot_info; -extern int treesource_error; -static unsigned long long eval_literal(const char *s, int base, int bits); %} %union { @@ -39,10 +36,10 @@ static unsigned long long eval_literal(const char *s, int base, int bits); char *literal; char *labelref; unsigned int cbase; - uint8_t byte; + u8 byte; struct data data; - uint64_t addr; + u64 addr; cell_t cell; struct property *prop; struct property *proplist; @@ -61,7 +58,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %token DT_STRING %token DT_LABEL %token DT_REF -%token DT_INCBIN %type propdata %type propdataprefix @@ -88,11 +84,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits); sourcefile: DT_V1 ';' memreserves devicetree { - the_boot_info = build_boot_info($3, $4, 0); + the_boot_info = build_boot_info($3, $4); } | v0_memreserves devicetree { - the_boot_info = build_boot_info($1, $2, 0); + the_boot_info = build_boot_info($1, $2); } ; @@ -200,34 +196,6 @@ propdata: { $$ = data_add_marker($1, REF_PATH, $2); } - | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' - { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file($4.val, &path); - struct data d = empty_data; - - if ($6 != 0) - if (fseek(file->file, $6, SEEK_SET) != 0) - yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)$6, - $4.val, strerror(errno)); - - d = data_copy_file(file->file, $8); - - $$ = data_merge($1, d); - dtc_close_file(file); - } - | propdataprefix DT_INCBIN '(' DT_STRING ')' - { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file($4.val, &path); - struct data d = empty_data; - - d = data_copy_file(file->file, -1); - - $$ = data_merge($1, d); - dtc_close_file(file); - } | propdata DT_LABEL { $$ = data_add_marker($1, LABEL, $2); @@ -314,7 +282,7 @@ subnodes: } | subnode propdef { - yyerror("syntax error: properties must precede subnodes"); + yyerror("syntax error: properties must precede subnodes\n"); YYERROR; } ; @@ -339,29 +307,18 @@ label: %% -void yyerrorf(char const *s, ...) +void yyerror (char const *s) { - const char *fname = srcpos_file ? srcpos_file->name : ""; - va_list va; - va_start(va, s); + const char *fname = srcpos_filename_for_num(yylloc.filenum); if (strcmp(fname, "-") == 0) fname = "stdin"; - fprintf(stderr, "%s:%d ", fname, yylloc.first_line); - vfprintf(stderr, s, va); - fprintf(stderr, "\n"); - - treesource_error = 1; - va_end(va); -} - -void yyerror (char const *s) -{ - yyerrorf("%s", s); + fprintf(stderr, "%s:%d %s\n", + fname, yylloc.first_line, s); } -static unsigned long long eval_literal(const char *s, int base, int bits) +unsigned long long eval_literal(const char *s, int base, int bits) { unsigned long long val; char *e; diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc.c b/trunk/arch/powerpc/boot/dtc-src/dtc.c index d8fd43b4ac1a..01131d7c2d5e 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc.c +++ b/trunk/arch/powerpc/boot/dtc-src/dtc.c @@ -55,7 +55,7 @@ char *join_path(const char *path, const char *name) return str; } -static void fill_fullpaths(struct node *tree, const char *prefix) +void fill_fullpaths(struct node *tree, const char *prefix) { struct node *child; const char *unit; @@ -106,7 +106,7 @@ static void __attribute__ ((noreturn)) usage(void) fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); fprintf(stderr, "\t-v\n"); fprintf(stderr, "\t\tPrint DTC version and exit\n"); - exit(3); + exit(2); } int main(int argc, char *argv[]) @@ -118,9 +118,10 @@ int main(int argc, char *argv[]) int force = 0, check = 0; const char *arg; int opt; + FILE *inf = NULL; FILE *outf = NULL; int outversion = DEFAULT_FDT_VERSION; - long long cmdline_boot_cpuid = -1; + int boot_cpuid_phys = 0xfeedbeef; quiet = 0; reservenum = 0; @@ -160,11 +161,11 @@ int main(int argc, char *argv[]) quiet++; break; case 'b': - cmdline_boot_cpuid = strtoll(optarg, NULL, 0); + boot_cpuid_phys = strtol(optarg, NULL, 0); break; case 'v': - printf("Version: %s\n", DTC_VERSION); - exit(0); + printf("Version: %s\n", DTC_VERSION); + exit(0); case 'h': default: usage(); @@ -179,27 +180,31 @@ int main(int argc, char *argv[]) arg = argv[optind]; /* minsize and padsize are mutually exclusive */ - if (minsize && padsize) + if ((minsize) && (padsize)) { die("Can't set both -p and -S\n"); + } fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", inform, outform, arg); - if (streq(inform, "dts")) + if (streq(inform, "dts")) { bi = dt_from_source(arg); - else if (streq(inform, "fs")) + } else if (streq(inform, "fs")) { bi = dt_from_fs(arg); - else if(streq(inform, "dtb")) - bi = dt_from_blob(arg); - else + } else if(streq(inform, "dtb")) { + inf = dtc_open_file(arg); + bi = dt_from_blob(inf); + } else { die("Unknown input format \"%s\"\n", inform); + } - if (cmdline_boot_cpuid != -1) - bi->boot_cpuid_phys = cmdline_boot_cpuid; + if (inf && (inf != stdin)) + fclose(inf); - fill_fullpaths(bi->dt, ""); - process_checks(force, bi); + if (! bi || ! bi->dt) + die("Couldn't read input tree\n"); + process_checks(force, bi, check, outversion, boot_cpuid_phys); if (streq(outname, "-")) { outf = stdout; @@ -213,9 +218,9 @@ int main(int argc, char *argv[]) if (streq(outform, "dts")) { dt_to_source(outf, bi); } else if (streq(outform, "dtb")) { - dt_to_blob(outf, bi, outversion); + dt_to_blob(outf, bi, outversion, boot_cpuid_phys); } else if (streq(outform, "asm")) { - dt_to_asm(outf, bi, outversion); + dt_to_asm(outf, bi, outversion, boot_cpuid_phys); } else if (streq(outform, "null")) { /* do nothing */ } else { diff --git a/trunk/arch/powerpc/boot/dtc-src/dtc.h b/trunk/arch/powerpc/boot/dtc-src/dtc.h index 08d54c870086..65281777a167 100644 --- a/trunk/arch/powerpc/boot/dtc-src/dtc.h +++ b/trunk/arch/powerpc/boot/dtc-src/dtc.h @@ -30,8 +30,10 @@ #include #include #include +#include +#include +#include -#include #include #define DEFAULT_FDT_VERSION 17 @@ -73,8 +75,25 @@ static inline void *xrealloc(void *p, size_t len) return new; } -typedef uint32_t cell_t; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef u32 cell_t; +#define cpu_to_be16(x) htons(x) +#define be16_to_cpu(x) ntohs(x) + +#define cpu_to_be32(x) htonl(x) +#define be32_to_cpu(x) ntohl(x) + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be64(x) (x) +#define be64_to_cpu(x) (x) +#else +#define cpu_to_be64(x) bswap_64(x) +#define be64_to_cpu(x) bswap_64(x) +#endif #define streq(a, b) (strcmp((a), (b)) == 0) #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) @@ -99,6 +118,7 @@ struct marker { struct data { int len; char *val; + int asize; struct marker *markers; }; @@ -125,7 +145,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, struct data data_merge(struct data d1, struct data d2); struct data data_append_cell(struct data d, cell_t word); struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); -struct data data_append_addr(struct data d, uint64_t addr); +struct data data_append_addr(struct data d, u64 addr); struct data data_append_byte(struct data d, uint8_t byte); struct data data_append_zeroes(struct data d, int len); struct data data_append_align(struct data d, int align); @@ -203,7 +223,7 @@ struct reserve_info { char *label; }; -struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label); +struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label); struct reserve_info *chain_reserve_entry(struct reserve_info *first, struct reserve_info *list); struct reserve_info *add_reserve_entry(struct reserve_info *list, @@ -213,22 +233,24 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, struct boot_info { struct reserve_info *reservelist; struct node *dt; /* the device tree */ - uint32_t boot_cpuid_phys; }; struct boot_info *build_boot_info(struct reserve_info *reservelist, - struct node *tree, uint32_t boot_cpuid_phys); + struct node *tree); /* Checks */ -void process_checks(int force, struct boot_info *bi); +void process_checks(int force, struct boot_info *bi, + int checkflag, int outversion, int boot_cpuid_phys); /* Flattened trees */ -void dt_to_blob(FILE *f, struct boot_info *bi, int version); -void dt_to_asm(FILE *f, struct boot_info *bi, int version); +void dt_to_blob(FILE *f, struct boot_info *bi, int version, + int boot_cpuid_phys); +void dt_to_asm(FILE *f, struct boot_info *bi, int version, + int boot_cpuid_phys); -struct boot_info *dt_from_blob(const char *fname); +struct boot_info *dt_from_blob(FILE *f); /* Tree source */ @@ -242,5 +264,6 @@ struct boot_info *dt_from_fs(const char *dirname); /* misc */ char *join_path(const char *path, const char *name); +void fill_fullpaths(struct node *tree, const char *prefix); #endif /* _DTC_H */ diff --git a/trunk/arch/powerpc/boot/dtc-src/flattree.c b/trunk/arch/powerpc/boot/dtc-src/flattree.c index 76acd28c068d..a7cfb843d334 100644 --- a/trunk/arch/powerpc/boot/dtc-src/flattree.c +++ b/trunk/arch/powerpc/boot/dtc-src/flattree.c @@ -19,7 +19,6 @@ */ #include "dtc.h" -#include "srcpos.h" #define FTF_FULLPATH 0x1 #define FTF_VARALIGN 0x2 @@ -163,18 +162,28 @@ static void asm_emit_data(void *e, struct data d) { FILE *f = e; int off = 0; - struct marker *m = d.markers; + struct marker *m; - for_each_marker_of_type(m, LABEL) - emit_offset_label(f, m->ref, m->offset); + m = d.markers; + while (m) { + if (m->type == LABEL) + emit_offset_label(f, m->ref, m->offset); + m = m->next; + } - while ((d.len - off) >= sizeof(uint32_t)) { + while ((d.len - off) >= sizeof(u32)) { fprintf(f, "\t.long\t0x%x\n", - fdt32_to_cpu(*((uint32_t *)(d.val+off)))); - off += sizeof(uint32_t); + be32_to_cpu(*((u32 *)(d.val+off)))); + off += sizeof(u32); + } + + if ((d.len - off) >= sizeof(u16)) { + fprintf(f, "\t.short\t0x%hx\n", + be16_to_cpu(*((u16 *)(d.val+off)))); + off += sizeof(u16); } - while ((d.len - off) >= 1) { + if ((d.len - off) >= 1) { fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]); off += 1; } @@ -327,28 +336,29 @@ static void make_fdt_header(struct fdt_header *fdt, memset(fdt, 0xff, sizeof(*fdt)); - fdt->magic = cpu_to_fdt32(FDT_MAGIC); - fdt->version = cpu_to_fdt32(vi->version); - fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version); + fdt->magic = cpu_to_be32(FDT_MAGIC); + fdt->version = cpu_to_be32(vi->version); + fdt->last_comp_version = cpu_to_be32(vi->last_comp_version); /* Reserve map should be doubleword aligned */ reserve_off = ALIGN(vi->hdr_size, 8); - fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off); - fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize); - fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize + fdt->off_mem_rsvmap = cpu_to_be32(reserve_off); + fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize); + fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize + dtsize); - fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize); + fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize); if (vi->flags & FTF_BOOTCPUID) - fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys); + fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys); if (vi->flags & FTF_STRTABSIZE) - fdt->size_dt_strings = cpu_to_fdt32(strsize); + fdt->size_dt_strings = cpu_to_be32(strsize); if (vi->flags & FTF_STRUCTSIZE) - fdt->size_dt_struct = cpu_to_fdt32(dtsize); + fdt->size_dt_struct = cpu_to_be32(dtsize); } -void dt_to_blob(FILE *f, struct boot_info *bi, int version) +void dt_to_blob(FILE *f, struct boot_info *bi, int version, + int boot_cpuid_phys) { struct version_info *vi = NULL; int i; @@ -373,26 +383,26 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) /* Make header */ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, - bi->boot_cpuid_phys); + boot_cpuid_phys); /* * If the user asked for more space than is used, adjust the totalsize. */ if (minsize > 0) { - padlen = minsize - fdt32_to_cpu(fdt.totalsize); + padlen = minsize - be32_to_cpu(fdt.totalsize); if ((padlen < 0) && (quiet < 1)) fprintf(stderr, "Warning: blob size %d >= minimum size %d\n", - fdt32_to_cpu(fdt.totalsize), minsize); + be32_to_cpu(fdt.totalsize), minsize); } if (padsize > 0) padlen = padsize; if (padlen > 0) { - int tsize = fdt32_to_cpu(fdt.totalsize); + int tsize = be32_to_cpu(fdt.totalsize); tsize += padlen; - fdt.totalsize = cpu_to_fdt32(tsize); + fdt.totalsize = cpu_to_be32(tsize); } /* @@ -400,7 +410,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) * the reserve buffer, add the reserve map terminating zeroes, * the device tree itself, and finally the strings. */ - blob = data_append_data(blob, &fdt, vi->hdr_size); + blob = data_append_data(blob, &fdt, sizeof(fdt)); blob = data_append_align(blob, 8); blob = data_merge(blob, reservebuf); blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry)); @@ -439,7 +449,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf) } } -void dt_to_asm(FILE *f, struct boot_info *bi, int version) +void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys) { struct version_info *vi = NULL; int i; @@ -479,7 +489,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) if (vi->flags & FTF_BOOTCPUID) fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", - bi->boot_cpuid_phys); + boot_cpuid_phys); if (vi->flags & FTF_STRTABSIZE) fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", @@ -569,15 +579,15 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len) inb->ptr += len; } -static uint32_t flat_read_word(struct inbuf *inb) +static u32 flat_read_word(struct inbuf *inb) { - uint32_t val; + u32 val; assert(((inb->ptr - inb->base) % sizeof(val)) == 0); flat_read_chunk(inb, &val, sizeof(val)); - return fdt32_to_cpu(val); + return be32_to_cpu(val); } static void flat_realign(struct inbuf *inb, int align) @@ -605,7 +615,7 @@ static char *flat_read_string(struct inbuf *inb) inb->ptr += len; - flat_realign(inb, sizeof(uint32_t)); + flat_realign(inb, sizeof(u32)); return str; } @@ -622,7 +632,7 @@ static struct data flat_read_data(struct inbuf *inb, int len) flat_read_chunk(inb, d.val, len); - flat_realign(inb, sizeof(uint32_t)); + flat_realign(inb, sizeof(u32)); return d; } @@ -649,7 +659,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset) static struct property *flat_read_property(struct inbuf *dtbuf, struct inbuf *strbuf, int flags) { - uint32_t proplen, stroff; + u32 proplen, stroff; char *name; struct data val; @@ -683,8 +693,8 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) p = inb->ptr; while (1) { flat_read_chunk(inb, &re, sizeof(re)); - re.address = fdt64_to_cpu(re.address); - re.size = fdt64_to_cpu(re.size); + re.address = be64_to_cpu(re.address); + re.size = be64_to_cpu(re.size); if (re.size == 0) break; @@ -698,37 +708,77 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) static char *nodename_from_path(const char *ppath, const char *cpath) { + const char *lslash; int plen; - plen = strlen(ppath); + lslash = strrchr(cpath, '/'); + if (! lslash) + return NULL; + + plen = lslash - cpath; + + if (streq(cpath, "/") && streq(ppath, "")) + return ""; + + if ((plen == 0) && streq(ppath, "/")) + return strdup(lslash+1); + + if (! strneq(ppath, cpath, plen)) + return NULL; + + return strdup(lslash+1); +} + +static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-"; +static const char UNITCHAR[] = "0123456789abcdef,"; + +static int check_node_name(const char *name) +{ + const char *atpos; + int basenamelen; - if (!strneq(ppath, cpath, plen)) - die("Path \"%s\" is not valid as a child of \"%s\"\n", - cpath, ppath); + atpos = strrchr(name, '@'); - /* root node is a special case */ - if (!streq(ppath, "/")) - plen++; + if (atpos) + basenamelen = atpos - name; + else + basenamelen = strlen(name); + + if (strspn(name, PROPCHAR) < basenamelen) + return -1; - return strdup(cpath + plen); + if (atpos + && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name))) + return -1; + + return basenamelen; } static struct node *unflatten_tree(struct inbuf *dtbuf, struct inbuf *strbuf, - const char *parent_flatname, int flags) + const char *parent_path, int flags) { struct node *node; - char *flatname; - uint32_t val; + u32 val; node = build_node(NULL, NULL); - flatname = flat_read_string(dtbuf); + if (flags & FTF_FULLPATH) { + node->fullpath = flat_read_string(dtbuf); + node->name = nodename_from_path(parent_path, node->fullpath); - if (flags & FTF_FULLPATH) - node->name = nodename_from_path(parent_flatname, flatname); - else - node->name = flatname; + if (! node->name) + die("Path \"%s\" is not valid as a child of \"%s\"\n", + node->fullpath, parent_path); + } else { + node->name = flat_read_string(dtbuf); + node->fullpath = join_path(parent_path, node->name); + } + + node->basenamelen = check_node_name(node->name); + if (node->basenamelen < 0) { + fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name); + } do { struct property *prop; @@ -745,7 +795,8 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, break; case FDT_BEGIN_NODE: - child = unflatten_tree(dtbuf,strbuf, flatname, flags); + child = unflatten_tree(dtbuf,strbuf, node->fullpath, + flags); add_child(node, child); break; @@ -774,11 +825,10 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, } -struct boot_info *dt_from_blob(const char *fname) +struct boot_info *dt_from_blob(FILE *f) { - struct dtc_file *dtcf; - uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; - uint32_t off_dt, off_str, off_mem_rsvmap; + u32 magic, totalsize, version, size_str, size_dt; + u32 off_dt, off_str, off_mem_rsvmap; int rc; char *blob; struct fdt_header *fdt; @@ -788,56 +838,54 @@ struct boot_info *dt_from_blob(const char *fname) int sizeleft; struct reserve_info *reservelist; struct node *tree; - uint32_t val; + u32 val; int flags = 0; - dtcf = dtc_open_file(fname, NULL); - - rc = fread(&magic, sizeof(magic), 1, dtcf->file); - if (ferror(dtcf->file)) + rc = fread(&magic, sizeof(magic), 1, f); + if (ferror(f)) die("Error reading DT blob magic number: %s\n", strerror(errno)); if (rc < 1) { - if (feof(dtcf->file)) + if (feof(f)) die("EOF reading DT blob magic number\n"); else die("Mysterious short read reading magic number\n"); } - magic = fdt32_to_cpu(magic); + magic = be32_to_cpu(magic); if (magic != FDT_MAGIC) die("Blob has incorrect magic number\n"); - rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file); - if (ferror(dtcf->file)) + rc = fread(&totalsize, sizeof(totalsize), 1, f); + if (ferror(f)) die("Error reading DT blob size: %s\n", strerror(errno)); if (rc < 1) { - if (feof(dtcf->file)) + if (feof(f)) die("EOF reading DT blob size\n"); else die("Mysterious short read reading blob size\n"); } - totalsize = fdt32_to_cpu(totalsize); + totalsize = be32_to_cpu(totalsize); if (totalsize < FDT_V1_SIZE) die("DT blob size (%d) is too small\n", totalsize); blob = xmalloc(totalsize); fdt = (struct fdt_header *)blob; - fdt->magic = cpu_to_fdt32(magic); - fdt->totalsize = cpu_to_fdt32(totalsize); + fdt->magic = cpu_to_be32(magic); + fdt->totalsize = cpu_to_be32(totalsize); sizeleft = totalsize - sizeof(magic) - sizeof(totalsize); p = blob + sizeof(magic) + sizeof(totalsize); while (sizeleft) { - if (feof(dtcf->file)) + if (feof(f)) die("EOF before reading %d bytes of DT blob\n", totalsize); - rc = fread(p, 1, sizeleft, dtcf->file); - if (ferror(dtcf->file)) + rc = fread(p, 1, sizeleft, f); + if (ferror(f)) die("Error reading DT blob: %s\n", strerror(errno)); @@ -845,11 +893,19 @@ struct boot_info *dt_from_blob(const char *fname) p += rc; } - off_dt = fdt32_to_cpu(fdt->off_dt_struct); - off_str = fdt32_to_cpu(fdt->off_dt_strings); - off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap); - version = fdt32_to_cpu(fdt->version); - boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys); + off_dt = be32_to_cpu(fdt->off_dt_struct); + off_str = be32_to_cpu(fdt->off_dt_strings); + off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap); + version = be32_to_cpu(fdt->version); + + fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic); + fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize); + fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt); + fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str); + fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap); + fprintf(stderr, "\tversion:\t\t0x%x\n", version ); + fprintf(stderr, "\tlast_comp_version:\t0x%x\n", + be32_to_cpu(fdt->last_comp_version)); if (off_mem_rsvmap >= totalsize) die("Mem Reserve structure offset exceeds total size\n"); @@ -860,17 +916,21 @@ struct boot_info *dt_from_blob(const char *fname) if (off_str > totalsize) die("String table offset exceeds total size\n"); + if (version >= 2) + fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n", + be32_to_cpu(fdt->boot_cpuid_phys)); + + size_str = -1; if (version >= 3) { - uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings); + size_str = be32_to_cpu(fdt->size_dt_strings); + fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str); if (off_str+size_str > totalsize) die("String table extends past total size\n"); - inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str); - } else { - inbuf_init(&strbuf, blob + off_str, blob + totalsize); } if (version >= 17) { - size_dt = fdt32_to_cpu(fdt->size_dt_struct); + size_dt = be32_to_cpu(fdt->size_dt_struct); + fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt); if (off_dt+size_dt > totalsize) die("Structure block extends past total size\n"); } @@ -884,6 +944,10 @@ struct boot_info *dt_from_blob(const char *fname) inbuf_init(&memresvbuf, blob + off_mem_rsvmap, blob + totalsize); inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); + if (size_str >= 0) + inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str); + else + inbuf_init(&strbuf, blob + off_str, blob + totalsize); reservelist = flat_read_mem_reserve(&memresvbuf); @@ -900,7 +964,5 @@ struct boot_info *dt_from_blob(const char *fname) free(blob); - dtc_close_file(dtcf); - - return build_boot_info(reservelist, tree, boot_cpuid_phys); + return build_boot_info(reservelist, tree); } diff --git a/trunk/arch/powerpc/boot/dtc-src/fstree.c b/trunk/arch/powerpc/boot/dtc-src/fstree.c index 766b2694d935..2a160a46998e 100644 --- a/trunk/arch/powerpc/boot/dtc-src/fstree.c +++ b/trunk/arch/powerpc/boot/dtc-src/fstree.c @@ -31,8 +31,8 @@ static struct node *read_fstree(const char *dirname) struct node *tree; d = opendir(dirname); - if (!d) - die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno)); + if (! d) + die("opendir(): %s\n", strerror(errno)); tree = build_node(NULL, NULL); @@ -87,6 +87,8 @@ struct boot_info *dt_from_fs(const char *dirname) tree = read_fstree(dirname); tree = name_node(tree, "", NULL); - return build_boot_info(NULL, tree, 0); + fill_fullpaths(tree, ""); + + return build_boot_info(NULL, tree); } diff --git a/trunk/arch/powerpc/boot/dtc-src/libfdt_env.h b/trunk/arch/powerpc/boot/dtc-src/libfdt_env.h deleted file mode 100644 index 449bf602daf1..000000000000 --- a/trunk/arch/powerpc/boot/dtc-src/libfdt_env.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _LIBFDT_ENV_H -#define _LIBFDT_ENV_H - -#include -#include -#include - -#define _B(n) ((unsigned long long)((uint8_t *)&x)[n]) -static inline uint32_t fdt32_to_cpu(uint32_t x) -{ - return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3); -} -#define cpu_to_fdt32(x) fdt32_to_cpu(x) - -static inline uint64_t fdt64_to_cpu(uint64_t x) -{ - return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32) - | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7); -} -#define cpu_to_fdt64(x) fdt64_to_cpu(x) -#undef _B - -#endif /* _LIBFDT_ENV_H */ diff --git a/trunk/arch/powerpc/boot/dtc-src/livetree.c b/trunk/arch/powerpc/boot/dtc-src/livetree.c index 0ca3de550b3f..6ba0846b4310 100644 --- a/trunk/arch/powerpc/boot/dtc-src/livetree.c +++ b/trunk/arch/powerpc/boot/dtc-src/livetree.c @@ -115,7 +115,6 @@ void add_child(struct node *parent, struct node *child) struct node **p; child->next_sibling = NULL; - child->parent = parent; p = &parent->children; while (*p) @@ -124,8 +123,7 @@ void add_child(struct node *parent, struct node *child) *p = child; } -struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size, - char *label) +struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label) { struct reserve_info *new = xmalloc(sizeof(*new)); @@ -167,14 +165,13 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, } struct boot_info *build_boot_info(struct reserve_info *reservelist, - struct node *tree, uint32_t boot_cpuid_phys) + struct node *tree) { struct boot_info *bi; bi = xmalloc(sizeof(*bi)); bi->reservelist = reservelist; bi->dt = tree; - bi->boot_cpuid_phys = boot_cpuid_phys; return bi; } @@ -205,7 +202,7 @@ struct property *get_property(struct node *node, const char *propname) cell_t propval_cell(struct property *prop) { assert(prop->val.len == sizeof(cell_t)); - return fdt32_to_cpu(*((cell_t *)prop->val.val)); + return be32_to_cpu(*((cell_t *)prop->val.val)); } struct node *get_subnode(struct node *node, const char *nodename) diff --git a/trunk/arch/powerpc/boot/dtc-src/srcpos.c b/trunk/arch/powerpc/boot/dtc-src/srcpos.c index 9641b7628b4d..352b0fe06fde 100644 --- a/trunk/arch/powerpc/boot/dtc-src/srcpos.c +++ b/trunk/arch/powerpc/boot/dtc-src/srcpos.c @@ -20,97 +20,86 @@ #include "dtc.h" #include "srcpos.h" + /* - * Like yylineno, this is the current open file pos. + * Record the complete unique set of opened file names. + * Primarily used to cache source position file names. */ +#define MAX_N_FILE_NAMES (100) -struct dtc_file *srcpos_file; +const char *file_names[MAX_N_FILE_NAMES]; +static int n_file_names = 0; -static int dtc_open_one(struct dtc_file *file, - const char *search, - const char *fname) -{ - char *fullname; +/* + * Like yylineno, this is the current open file pos. + */ - if (search) { - fullname = xmalloc(strlen(search) + strlen(fname) + 2); +int srcpos_filenum = -1; - strcpy(fullname, search); - strcat(fullname, "/"); - strcat(fullname, fname); - } else { - fullname = strdup(fname); - } - file->file = fopen(fullname, "r"); - if (!file->file) { - free(fullname); - return 0; - } - file->name = fullname; - return 1; -} +FILE *dtc_open_file(const char *fname) +{ + FILE *f; + if (lookup_file_name(fname, 1) < 0) + die("Too many files opened\n"); -struct dtc_file *dtc_open_file(const char *fname, - const struct search_path *search) -{ - static const struct search_path default_search = { NULL, NULL, NULL }; + if (streq(fname, "-")) + f = stdin; + else + f = fopen(fname, "r"); - struct dtc_file *file; - const char *slash; + if (! f) + die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); - file = xmalloc(sizeof(struct dtc_file)); + return f; +} - slash = strrchr(fname, '/'); - if (slash) { - char *dir = xmalloc(slash - fname + 1); - memcpy(dir, fname, slash - fname); - dir[slash - fname] = 0; - file->dir = dir; - } else { - file->dir = NULL; - } - if (streq(fname, "-")) { - file->name = "stdin"; - file->file = stdin; - return file; - } +/* + * Locate and optionally add filename fname in the file_names[] array. + * + * If the filename is currently not in the array and the boolean + * add_it is non-zero, an attempt to add the filename will be made. + * + * Returns; + * Index [0..MAX_N_FILE_NAMES) where the filename is kept + * -1 if the name can not be recorded + */ - if (fname[0] == '/') { - file->file = fopen(fname, "r"); - if (!file->file) - goto fail; +int lookup_file_name(const char *fname, int add_it) +{ + int i; - file->name = strdup(fname); - return file; + for (i = 0; i < n_file_names; i++) { + if (strcmp(file_names[i], fname) == 0) + return i; } - if (!search) - search = &default_search; + if (add_it) { + if (n_file_names < MAX_N_FILE_NAMES) { + file_names[n_file_names] = strdup(fname); + return n_file_names++; + } + } - while (search) { - if (dtc_open_one(file, search->dir, fname)) - return file; + return -1; +} - if (errno != ENOENT) - goto fail; - search = search->next; +const char *srcpos_filename_for_num(int filenum) +{ + if (0 <= filenum && filenum < n_file_names) { + return file_names[filenum]; } -fail: - die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); + return 0; } -void dtc_close_file(struct dtc_file *file) -{ - if (fclose(file->file)) - die("Error closing \"%s\": %s\n", file->name, strerror(errno)); - free(file->dir); - free(file); +const char *srcpos_get_filename(void) +{ + return srcpos_filename_for_num(srcpos_filenum); } diff --git a/trunk/arch/powerpc/boot/dtc-src/srcpos.h b/trunk/arch/powerpc/boot/dtc-src/srcpos.h index e17c7c04db8e..ce7ab5ba5b46 100644 --- a/trunk/arch/powerpc/boot/dtc-src/srcpos.h +++ b/trunk/arch/powerpc/boot/dtc-src/srcpos.h @@ -22,21 +22,13 @@ * array of all opened filenames. */ -#include - -struct dtc_file { - char *dir; - const char *name; - FILE *file; -}; - #if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED) typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; - struct dtc_file *file; + int filenum; } YYLTYPE; #define YYLTYPE_IS_DECLARED 1 @@ -56,7 +48,7 @@ typedef struct YYLTYPE { (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - (Current).file = YYRHSLOC (Rhs, N).file; \ + (Current).filenum = YYRHSLOC (Rhs, N).filenum; \ } \ else \ { \ @@ -64,22 +56,20 @@ typedef struct YYLTYPE { YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ - (Current).file = YYRHSLOC (Rhs, 0).file; \ + (Current).filenum = YYRHSLOC (Rhs, 0).filenum; \ } \ while (YYID (0)) extern void yyerror(char const *); -extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2))); -extern struct dtc_file *srcpos_file; +extern int srcpos_filenum; -struct search_path { - const char *dir; /* NULL for current directory */ - struct search_path *prev, *next; -}; +extern int push_input_file(const char *filename); +extern int pop_input_file(void); -extern struct dtc_file *dtc_open_file(const char *fname, - const struct search_path *search); -extern void dtc_close_file(struct dtc_file *file); +extern FILE *dtc_open_file(const char *fname); +extern int lookup_file_name(const char *fname, int add_it); +extern const char *srcpos_filename_for_num(int filenum); +const char *srcpos_get_filename(void); diff --git a/trunk/arch/powerpc/boot/dtc-src/treesource.c b/trunk/arch/powerpc/boot/dtc-src/treesource.c index ebeb6eb27907..a6a776797636 100644 --- a/trunk/arch/powerpc/boot/dtc-src/treesource.c +++ b/trunk/arch/powerpc/boot/dtc-src/treesource.c @@ -23,23 +23,20 @@ extern FILE *yyin; extern int yyparse(void); +extern void yyerror(char const *); struct boot_info *the_boot_info; -int treesource_error; struct boot_info *dt_from_source(const char *fname) { the_boot_info = NULL; - treesource_error = 0; - srcpos_file = dtc_open_file(fname, NULL); - yyin = srcpos_file->file; + push_input_file(fname); if (yyparse() != 0) - die("Unable to parse input tree\n"); + return NULL; - if (treesource_error) - die("Syntax error parsing input tree\n"); + fill_fullpaths(the_boot_info->dt, ""); return the_boot_info; } @@ -147,7 +144,7 @@ static void write_propval_cells(FILE *f, struct data val) m = m->next; } - fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); + fprintf(f, "0x%x", be32_to_cpu(*cp++)); if ((void *)cp >= propend) break; fprintf(f, " "); @@ -176,7 +173,7 @@ static void write_propval_bytes(FILE *f, struct data val) } fprintf(f, "%02hhx", *bp++); - if ((const void *)bp >= propend) + if ((void *)bp >= propend) break; fprintf(f, " "); } diff --git a/trunk/arch/powerpc/boot/dtc-src/version_gen.h b/trunk/arch/powerpc/boot/dtc-src/version_gen.h index 658ff42429d6..6c343031538e 100644 --- a/trunk/arch/powerpc/boot/dtc-src/version_gen.h +++ b/trunk/arch/powerpc/boot/dtc-src/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.2.0" +#define DTC_VERSION "DTC 1.0.0-gd6f9b62f" diff --git a/trunk/arch/powerpc/boot/dts/arches.dts b/trunk/arch/powerpc/boot/dts/arches.dts deleted file mode 100644 index d9113b1e8c1d..000000000000 --- a/trunk/arch/powerpc/boot/dts/arches.dts +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Device Tree Source for AMCC Arches (dual 460GT board) - * - * (C) Copyright 2008 Applied Micro Circuits Corporation - * Victor Gallardo - * Adam Graham - * - * Based on the glacier.dts file - * Stefan Roese - * Copyright 2008 DENX Software Engineering - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/dts-v1/; - -/ { - #address-cells = <2>; - #size-cells = <1>; - model = "amcc,arches"; - compatible = "amcc,arches"; - dcr-parent = <&{/cpus/cpu@0}>; - - aliases { - ethernet0 = &EMAC0; - ethernet1 = &EMAC1; - ethernet2 = &EMAC2; - serial0 = &UART0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - model = "PowerPC,460GT"; - reg = <0x00000000>; - clock-frequency = <0>; /* Filled in by U-Boot */ - timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <32>; - d-cache-line-size = <32>; - i-cache-size = <32768>; - d-cache-size = <32768>; - dcr-controller; - dcr-access-method = "native"; - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ - }; - - UIC0: interrupt-controller0 { - compatible = "ibm,uic-460gt","ibm,uic"; - interrupt-controller; - cell-index = <0>; - dcr-reg = <0x0c0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - }; - - UIC1: interrupt-controller1 { - compatible = "ibm,uic-460gt","ibm,uic"; - interrupt-controller; - cell-index = <1>; - dcr-reg = <0x0d0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - UIC2: interrupt-controller2 { - compatible = "ibm,uic-460gt","ibm,uic"; - interrupt-controller; - cell-index = <2>; - dcr-reg = <0x0e0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - UIC3: interrupt-controller3 { - compatible = "ibm,uic-460gt","ibm,uic"; - interrupt-controller; - cell-index = <3>; - dcr-reg = <0x0f0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - SDR0: sdr { - compatible = "ibm,sdr-460gt"; - dcr-reg = <0x00e 0x002>; - }; - - CPR0: cpr { - compatible = "ibm,cpr-460gt"; - dcr-reg = <0x00c 0x002>; - }; - - plb { - compatible = "ibm,plb-460gt", "ibm,plb4"; - #address-cells = <2>; - #size-cells = <1>; - ranges; - clock-frequency = <0>; /* Filled in by U-Boot */ - - SDRAM0: sdram { - compatible = "ibm,sdram-460gt", "ibm,sdram-405gp"; - dcr-reg = <0x010 0x002>; - }; - - MAL0: mcmal { - compatible = "ibm,mcmal-460gt", "ibm,mcmal2"; - dcr-reg = <0x180 0x062>; - num-tx-chans = <3>; - num-rx-chans = <24>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-parent = <&UIC2>; - interrupts = < /*TXEOB*/ 0x6 0x4 - /*RXEOB*/ 0x7 0x4 - /*SERR*/ 0x3 0x4 - /*TXDE*/ 0x4 0x4 - /*RXDE*/ 0x5 0x4>; - desc-base-addr-high = <0x8>; - }; - - POB0: opb { - compatible = "ibm,opb-460gt", "ibm,opb"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; - clock-frequency = <0>; /* Filled in by U-Boot */ - - EBC0: ebc { - compatible = "ibm,ebc-460gt", "ibm,ebc"; - dcr-reg = <0x012 0x002>; - #address-cells = <2>; - #size-cells = <1>; - clock-frequency = <0>; /* Filled in by U-Boot */ - /* ranges property is supplied by U-Boot */ - interrupts = <0x6 0x4>; - interrupt-parent = <&UIC1>; - }; - - UART0: serial@ef600300 { - device_type = "serial"; - compatible = "ns16550"; - reg = <0xef600300 0x00000008>; - virtual-reg = <0xef600300>; - clock-frequency = <0>; /* Filled in by U-Boot */ - current-speed = <0>; /* Filled in by U-Boot */ - interrupt-parent = <&UIC1>; - interrupts = <0x1 0x4>; - }; - - IIC0: i2c@ef600700 { - compatible = "ibm,iic-460gt", "ibm,iic"; - reg = <0xef600700 0x00000014>; - interrupt-parent = <&UIC0>; - interrupts = <0x2 0x4>; - }; - - IIC1: i2c@ef600800 { - compatible = "ibm,iic-460gt", "ibm,iic"; - reg = <0xef600800 0x00000014>; - interrupt-parent = <&UIC0>; - interrupts = <0x3 0x4>; - }; - - TAH0: emac-tah@ef601350 { - compatible = "ibm,tah-460gt", "ibm,tah"; - reg = <0xef601350 0x00000030>; - }; - - TAH1: emac-tah@ef601450 { - compatible = "ibm,tah-460gt", "ibm,tah"; - reg = <0xef601450 0x00000030>; - }; - - EMAC0: ethernet@ef600e00 { - device_type = "network"; - compatible = "ibm,emac-460gt", "ibm,emac4sync"; - interrupt-parent = <&EMAC0>; - interrupts = <0x0 0x1>; - #interrupt-cells = <1>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = ; - reg = <0xef600e00 0x000000c4>; - local-mac-address = [000000000000]; /* Filled in by U-Boot */ - mal-device = <&MAL0>; - mal-tx-channel = <0>; - mal-rx-channel = <0>; - cell-index = <0>; - max-frame-size = <9000>; - rx-fifo-size = <4096>; - tx-fifo-size = <2048>; - phy-mode = "sgmii"; - phy-map = <0xffffffff>; - gpcs-address = <0x0000000a>; - tah-device = <&TAH0>; - tah-channel = <0>; - has-inverted-stacr-oc; - has-new-stacr-staopc; - }; - - EMAC1: ethernet@ef600f00 { - device_type = "network"; - compatible = "ibm,emac-460gt", "ibm,emac4sync"; - interrupt-parent = <&EMAC1>; - interrupts = <0x0 0x1>; - #interrupt-cells = <1>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = ; - reg = <0xef600f00 0x000000c4>; - local-mac-address = [000000000000]; /* Filled in by U-Boot */ - mal-device = <&MAL0>; - mal-tx-channel = <1>; - mal-rx-channel = <8>; - cell-index = <1>; - max-frame-size = <9000>; - rx-fifo-size = <4096>; - tx-fifo-size = <2048>; - phy-mode = "sgmii"; - phy-map = <0x00000000>; - gpcs-address = <0x0000000b>; - tah-device = <&TAH1>; - tah-channel = <1>; - has-inverted-stacr-oc; - has-new-stacr-staopc; - mdio-device = <&EMAC0>; - }; - - EMAC2: ethernet@ef601100 { - device_type = "network"; - compatible = "ibm,emac-460gt", "ibm,emac4sync"; - interrupt-parent = <&EMAC2>; - interrupts = <0x0 0x1>; - #interrupt-cells = <1>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = ; - reg = <0xef601100 0x000000c4>; - local-mac-address = [000000000000]; /* Filled in by U-Boot */ - mal-device = <&MAL0>; - mal-tx-channel = <2>; - mal-rx-channel = <16>; - cell-index = <2>; - max-frame-size = <9000>; - rx-fifo-size = <4096>; - tx-fifo-size = <2048>; - phy-mode = "sgmii"; - phy-map = <0x00000001>; - gpcs-address = <0x0000000C>; - has-inverted-stacr-oc; - has-new-stacr-staopc; - mdio-device = <&EMAC0>; - }; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts b/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts index 6235fca445de..8b1bb0e41905 100644 --- a/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts +++ b/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts @@ -130,28 +130,24 @@ dma-channel@0 { compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8347-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; diff --git a/trunk/arch/powerpc/boot/dts/gef_sbc610.dts b/trunk/arch/powerpc/boot/dts/gef_sbc610.dts deleted file mode 100644 index 6ed608322ddc..000000000000 --- a/trunk/arch/powerpc/boot/dts/gef_sbc610.dts +++ /dev/null @@ -1,293 +0,0 @@ -/* - * GE Fanuc SBC610 Device Tree Source - * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, 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 - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Based on: SBS CM6 Device Tree Source - * Copyright 2007 SBS Technologies GmbH & Co. KG - * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) - * Copyright 2006 Freescale Semiconductor Inc. - */ - -/* - * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts - */ - -/dts-v1/; - -/ { - model = "GEF_SBC610"; - compatible = "gef,sbc610"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // set by uboot - }; - - localbus@fef05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xf8005000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xe8000000 0x08000000 // Paged Flash 0 - 2 0 0xe0000000 0x08000000 // Paged Flash 1 - 3 0 0xfc100000 0x00020000 // NVRAM - 4 0 0xfc000000 0x00008000 // FPGA - 5 0 0xfc008000 0x00008000 // AFIX FPGA - 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) - 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) - - fpga@4,0 { - compatible = "gef,fpga-regs"; - reg = <0x4 0x0 0x40>; - }; - gef_pic: pic@4,4000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "gef,fpga-pic"; - reg = <0x4 0x4000 0x20>; - interrupts = <0x8 - 0x9>; - interrupt-parent = <&mpic>; - - }; - }; - - soc@fef00000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - compatible = "simple-bus"; - ranges = <0x0 0xfef00000 0x00100000>; - reg = <0xfef00000 0x100000>; // CCSRBAR 1M - bus-frequency = <0>; - - i2c1: i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - eti@6b { - compatible = "dallas,ds1682"; - reg = <0x6b>; - }; - }; - - i2c2: i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x24520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - }; - - enet0: ethernet@24000 { - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy0>; - phy-connection-type = "gmii"; - }; - - enet1: ethernet@26000 { - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy2>; - phy-connection-type = "gmii"; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <0x2a 0x2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <0x1c 0x2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@fef08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef08000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 - 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x18 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 - 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 - 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 - 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x40000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/glacier.dts b/trunk/arch/powerpc/boot/dts/glacier.dts index f3787a27f634..24cf0dba120c 100644 --- a/trunk/arch/powerpc/boot/dts/glacier.dts +++ b/trunk/arch/powerpc/boot/dts/glacier.dts @@ -14,7 +14,7 @@ #address-cells = <2>; #size-cells = <1>; model = "amcc,glacier"; - compatible = "amcc,glacier"; + compatible = "amcc,glacier", "amcc,canyonlands"; dcr-parent = <&{/cpus/cpu@0}>; aliases { diff --git a/trunk/arch/powerpc/boot/dts/mgcoge.dts b/trunk/arch/powerpc/boot/dts/mgcoge.dts deleted file mode 100644 index 633255a97557..000000000000 --- a/trunk/arch/powerpc/boot/dts/mgcoge.dts +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Device Tree for the MGCOGE plattform from keymile - * - * Copyright 2008 DENX Software Engineering GmbH - * Heiko Schocher - * - * 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. - */ - -/dts-v1/; -/ { - model = "MGCOGE"; - compatible = "keymile,mgcoge"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = ð0; - serial0 = &smc2; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8247@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <16384>; - i-cache-size = <16384>; - timebase-frequency = <0>; /* Filled in by U-Boot */ - clock-frequency = <0>; /* Filled in by U-Boot */ - bus-frequency = <0>; /* Filled in by U-Boot */ - }; - }; - - localbus@f0010100 { - compatible = "fsl,mpc8247-localbus", - "fsl,pq2-localbus", - "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - reg = <0xf0010100 0x40>; - - ranges = <0 0 0xfe000000 0x00400000 - 5 0 0x50000000 0x20000000 - >; /* Filled in by U-Boot */ - - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0x0 0x400000>; - #address-cells = <1>; - #size-cells = <1>; - bank-width = <1>; - device-width = <1>; - partition@0 { - label = "u-boot"; - reg = <0 0x40000>; - }; - partition@40000 { - label = "env"; - reg = <0x40000 0x20000>; - }; - partition@60000 { - label = "kernel"; - reg = <0x60000 0x220000>; - }; - partition@280000 { - label = "dtb"; - reg = <0x280000 0x20000>; - }; - }; - - flash@5,0 { - compatible = "cfi-flash"; - reg = <5 0x0 0x2000000>; - #address-cells = <1>; - #size-cells = <1>; - bank-width = <2>; - device-width = <2>; - partition@0 { - label = "ramdisk"; - reg = <0 0x7a0000>; - }; - partition@7a0000 { - label = "user"; - reg = <0x7a0000 0x1860000>; - }; - }; - }; - - memory { - device_type = "memory"; - reg = <0 0>; /* Filled in by U-Boot */ - }; - - soc@f0000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8247-immr", "fsl,pq2-soc", "simple-bus"; - ranges = <0x00000000 0xf0000000 0x00053000>; - - // Temporary until code stops depending on it. - device_type = "soc"; - - cpm@119c0 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - compatible = "fsl,mpc8247-cpm", "fsl,cpm2", - "simple-bus"; - reg = <0x119c0 0x30>; - ranges; - - muram { - compatible = "fsl,cpm-muram"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0 0x10000>; - - data@0 { - compatible = "fsl,cpm-muram-data"; - reg = <0x80 0x1f80 0x9800 0x800>; - }; - }; - - brg@119f0 { - compatible = "fsl,mpc8247-brg", - "fsl,cpm2-brg", - "fsl,cpm-brg"; - reg = <0x119f0 0x10 0x115f0 0x10>; - }; - - /* Monitor port/SMC2 */ - smc2: serial@11a90 { - device_type = "serial"; - compatible = "fsl,mpc8247-smc-uart", - "fsl,cpm2-smc-uart"; - reg = <0x11a90 0x20 0x88fc 0x02>; - interrupts = <5 8>; - interrupt-parent = <&PIC>; - fsl,cpm-brg = <2>; - fsl,cpm-command = <0x21200000>; - current-speed = <0>; /* Filled in by U-Boot */ - }; - - eth0: ethernet@11a60 { - device_type = "network"; - compatible = "fsl,mpc8247-scc-enet", - "fsl,cpm2-scc-enet"; - reg = <0x11a60 0x20 0x8300 0x100 0x11390 1>; - local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */ - interrupts = <43 8>; - interrupt-parent = <&PIC>; - linux,network-index = <0>; - fsl,cpm-command = <0xce00000>; - fixed-link = <0 0 10 0 0>; - }; - - }; - - PIC: interrupt-controller@10c00 { - #interrupt-cells = <2>; - interrupt-controller; - reg = <0x10c00 0x80>; - compatible = "fsl,mpc8247-pic", "fsl,pq2-pic"; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mgsuvd.dts b/trunk/arch/powerpc/boot/dts/mgsuvd.dts deleted file mode 100644 index e4fc53ab42bd..000000000000 --- a/trunk/arch/powerpc/boot/dts/mgsuvd.dts +++ /dev/null @@ -1,163 +0,0 @@ -/* - * MGSUVD Device Tree Source - * - * Copyright 2008 DENX Software Engineering GmbH - * Heiko Schocher - * - * 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. - */ - -/dts-v1/; -/ { - model = "MGSUVD"; - compatible = "keymile,mgsuvd"; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,852@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <16>; - i-cache-line-size = <16>; - d-cache-size = <8192>; - i-cache-size = <8192>; - timebase-frequency = <0>; /* Filled in by u-boot */ - bus-frequency = <0>; /* Filled in by u-boot */ - clock-frequency = <0>; /* Filled in by u-boot */ - interrupts = <15 2>; /* decrementer interrupt */ - interrupt-parent = <&PIC>; - }; - }; - - memory { - device_type = "memory"; - reg = <00000000 0x4000000>; /* Filled in by u-boot */ - }; - - localbus@fff00100 { - compatible = "fsl,mpc852-localbus", "fsl,pq1-localbus", "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - reg = <0xfff00100 0x40>; - - ranges = <0 0 0xf0000000 0x01000000>; /* Filled in by u-boot */ - - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x1000000>; - #address-cells = <1>; - #size-cells = <1>; - bank-width = <1>; - device-width = <1>; - partition@0 { - label = "u-boot"; - reg = <0 0x80000>; - }; - partition@80000 { - label = "env"; - reg = <0x80000 0x20000>; - }; - partition@a0000 { - label = "kernel"; - reg = <0xa0000 0x1e0000>; - }; - partition@280000 { - label = "dtb"; - reg = <0x280000 0x20000>; - }; - partition@2a0000 { - label = "root"; - reg = <0x2a0000 0x500000>; - }; - partition@7a0000 { - label = "user"; - reg = <0x7a0000 0x860000>; - }; - }; - }; - - soc@fff00000 { - compatible = "fsl,mpc852", "fsl,pq1-soc", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - ranges = <0 0xfff00000 0x00004000>; - - PIC: interrupt-controller@0 { - interrupt-controller; - #interrupt-cells = <2>; - reg = <0 24>; - compatible = "fsl,mpc852-pic", "fsl,pq1-pic"; - }; - - cpm@9c0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc852-cpm", "fsl,cpm1", "simple-bus"; - interrupts = <0>; /* cpm error interrupt */ - interrupt-parent = <&CPM_PIC>; - reg = <0x9c0 10>; - ranges; - - muram@2000 { - compatible = "fsl,cpm-muram"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x2000 0x2000>; - - data@0 { - compatible = "fsl,cpm-muram-data"; - reg = <0x800 0x1800>; - }; - }; - - brg@9f0 { - compatible = "fsl,mpc852-brg", - "fsl,cpm1-brg", - "fsl,cpm-brg"; - reg = <0x9f0 0x10>; - clock-frequency = <0>; /* Filled in by u-boot */ - }; - - CPM_PIC: interrupt-controller@930 { - interrupt-controller; - #interrupt-cells = <1>; - interrupts = <5 2 0 2>; - interrupt-parent = <&PIC>; - reg = <0x930 0x20>; - compatible = "fsl,cpm1-pic"; - }; - - /* MON-1 */ - serial@a80 { - device_type = "serial"; - compatible = "fsl,cpm1-smc-uart"; - reg = <0xa80 0x10 0x3fc0 0x40>; - interrupts = <4>; - interrupt-parent = <&CPM_PIC>; - fsl,cpm-brg = <1>; - fsl,cpm-command = <0x0090>; - current-speed = <0>; /* Filled in by u-boot */ - }; - - ethernet@a40 { - device_type = "network"; - compatible = "fsl,mpc866-scc-enet", - "fsl,cpm1-scc-enet"; - reg = <0xa40 0x18 0x3e00 0x100>; - local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by u-boot */ - interrupts = <28>; - interrupt-parent = <&CPM_PIC>; - fsl,cpm-command = <0x80>; - fixed-link = <0 0 10 0 0>; - }; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc5121ads.dts b/trunk/arch/powerpc/boot/dts/mpc5121ads.dts index c2b8dbfab79e..1f9036c317b4 100644 --- a/trunk/arch/powerpc/boot/dts/mpc5121ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc5121ads.dts @@ -403,8 +403,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0x80008500 0x100 /* internal registers */ - 0x80008300 0x8>; /* config space access registers */ + reg = <0x80008500 0x100>; compatible = "fsl,mpc5121-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts b/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts index 747f27676332..2a94ae0dc8b8 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts @@ -176,28 +176,24 @@ dma-channel@0 { compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -363,8 +359,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts b/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts index 7449e54c1a90..f704513fb930 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -144,28 +144,24 @@ dma-channel@0 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -318,8 +314,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts b/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts index e4cc1768f241..fbc930410ff6 100644 --- a/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts @@ -127,28 +127,24 @@ dma-channel@0 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -423,8 +419,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts index 226ff066652b..b157d1885a28 100644 --- a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -105,28 +105,24 @@ dma-channel@0 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8323-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -331,8 +327,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts b/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts index 5cedf373a1d8..700e076ef3f5 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -106,28 +106,24 @@ dma-channel@0 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -254,8 +250,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; @@ -281,8 +276,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008600 0x100 /* internal registers */ - 0xe0008380 0x8>; /* config space access registers */ + reg = <0xe0008600 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts index 81ae1d3e9440..cdd3063258ea 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -104,28 +104,24 @@ dma-channel@0 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -228,8 +224,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008600 0x100 /* internal registers */ - 0xe0008380 0x8>; /* config space access registers */ + reg = <0xe0008600 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts b/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts index 04bfde3ea605..783241c00240 100644 --- a/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts @@ -116,28 +116,24 @@ dma-channel@0 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -315,8 +311,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; @@ -377,8 +372,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008600 0x100 /* internal registers */ - 0xe0008380 0x8>; /* config space access registers */ + reg = <0xe0008600 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts b/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts index 66a12d2631fb..a3b76a709951 100644 --- a/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts @@ -52,26 +52,9 @@ reg = <0x00000000 0x10000000>; }; - localbus@e0005000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus", - "simple-bus"; - reg = <0xe0005000 0xd8>; - ranges = <0 0 0xfe000000 0x02000000 - 1 0 0xf8000000 0x00008000>; - - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x2000000>; - bank-width = <2>; - device-width = <1>; - }; - - bcsr@1,0 { - device_type = "board-control"; - reg = <1 0 0x8000>; - }; + bcsr@f8000000 { + device_type = "board-control"; + reg = <0xf8000000 0x8000>; }; soc8360@e0000000 { @@ -148,28 +131,24 @@ dma-channel@0 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -426,8 +405,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc836x_rdk.dts b/trunk/arch/powerpc/boot/dts/mpc836x_rdk.dts index decadf3d9e98..89c9202f8bd7 100644 --- a/trunk/arch/powerpc/boot/dts/mpc836x_rdk.dts +++ b/trunk/arch/powerpc/boot/dts/mpc836x_rdk.dts @@ -125,28 +125,24 @@ dma-channel@0 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8360-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -387,18 +383,6 @@ device-width = <1>; }; - upm@1,0 { - compatible = "fsl,upm-nand"; - reg = <1 0 1>; - fsl,upm-addr-offset = <16>; - fsl,upm-cmd-offset = <8>; - gpios = <&qe_pio_e 18 0>; - - flash { - compatible = "stm,nand512-a"; - }; - }; - display@2,0 { device_type = "display"; compatible = "fujitsu,MB86277", "fujitsu,mint"; @@ -421,8 +405,7 @@ #interrupt-cells = <1>; device_type = "pci"; compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci"; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000 0x42000000 0 0x80000000 0x80000000 0 0x10000000 0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts index 0484561bd2c0..432782b6d20a 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -136,13 +136,6 @@ interrupts = <14 0x8>; interrupt-parent = <&ipic>; dfsrr; - - rtc@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - interrupts = <19 0x8>; - interrupt-parent = <&ipic>; - }; }; i2c@3100 { @@ -253,28 +246,24 @@ dma-channel@0 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <0x47 8>; }; dma-channel@80 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <0x47 8>; }; dma-channel@100 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <0x47 8>; }; dma-channel@180 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <0x47 8>; }; @@ -385,8 +374,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts index 53191ba67aaa..ed137aa83d5f 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -155,28 +155,24 @@ dma-channel@0 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -319,8 +315,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts index 67a08d2e2ff2..ed32c8ddafe3 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -136,13 +136,6 @@ interrupts = <14 0x8>; interrupt-parent = <&ipic>; dfsrr; - - rtc@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - interrupts = <19 0x8>; - interrupt-parent = <&ipic>; - }; }; i2c@3100 { @@ -177,28 +170,24 @@ dma-channel@0 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -371,8 +360,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts index 4a09153d160c..34a7f2f935e1 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -155,28 +155,24 @@ dma-channel@0 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8378-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -305,8 +301,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts index 323370a2b5ff..f4db9ed4a301 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts @@ -136,13 +136,6 @@ interrupts = <14 0x8>; interrupt-parent = <&ipic>; dfsrr; - - rtc@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - interrupts = <19 0x8>; - interrupt-parent = <&ipic>; - }; }; i2c@3100 { @@ -177,28 +170,24 @@ dma-channel@0 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -399,8 +388,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts index bbd884ac9dc0..e4d7030d50e5 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -155,28 +155,24 @@ dma-channel@0 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8379-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -333,8 +329,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8536ds.dts b/trunk/arch/powerpc/boot/dts/mpc8536ds.dts index 93fdd99901b6..1505d6855eff 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8536ds.dts @@ -91,8 +91,6 @@ rtc@68 { compatible = "dallas,ds3232"; reg = <0x68>; - interrupts = <0 0x1>; - interrupt-parent = <&mpic>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts index f724d72c7b92..584a4f184eb2 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts @@ -207,7 +207,7 @@ reg = <0xe4000 0x100>; }; - ssi@16000 { + i2s@16000 { compatible = "fsl,mpc8610-ssi"; cell-index = <0>; reg = <0x16000 0x100>; @@ -215,8 +215,6 @@ interrupts = <62 2>; fsl,mode = "i2s-slave"; codec-handle = <&cs4270>; - fsl,playback-dma = <&dma00>; - fsl,capture-dma = <&dma01>; }; ssi@16100 { @@ -235,17 +233,17 @@ reg = <0x21300 0x4>; /* DMA general status register */ ranges = <0x0 0x21100 0x200>; - dma00: dma-channel@0 { + dma-channel@0 { compatible = "fsl,mpc8610-dma-channel", - "fsl,ssi-dma-channel"; + "fsl,eloplus-dma-channel"; cell-index = <0>; reg = <0x0 0x80>; interrupt-parent = <&mpic>; interrupts = <20 2>; }; - dma01: dma-channel@1 { + dma-channel@1 { compatible = "fsl,mpc8610-dma-channel", - "fsl,ssi-dma-channel"; + "fsl,eloplus-dma-channel"; cell-index = <1>; reg = <0x80 0x80>; interrupt-parent = <&mpic>; diff --git a/trunk/arch/powerpc/boot/dts/sbc8349.dts b/trunk/arch/powerpc/boot/dts/sbc8349.dts index 0f941f310e44..45f789b56709 100644 --- a/trunk/arch/powerpc/boot/dts/sbc8349.dts +++ b/trunk/arch/powerpc/boot/dts/sbc8349.dts @@ -107,28 +107,24 @@ dma-channel@0 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; - cell-index = <0>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@80 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; - cell-index = <1>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@100 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; - cell-index = <2>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; dma-channel@180 { compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; - cell-index = <3>; interrupt-parent = <&ipic>; interrupts = <71 8>; }; @@ -272,8 +268,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xe0008500 0x100 /* internal registers */ - 0xe0008300 0x8>; /* config space access registers */ + reg = <0xe0008500 0x100>; compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; diff --git a/trunk/arch/powerpc/boot/dts/sequoia.dts b/trunk/arch/powerpc/boot/dts/sequoia.dts index 3b295e8df53f..72d15f075d34 100644 --- a/trunk/arch/powerpc/boot/dts/sequoia.dts +++ b/trunk/arch/powerpc/boot/dts/sequoia.dts @@ -246,22 +246,13 @@ }; IIC0: i2c@ef600700 { - #address-cells = <1>; - #size-cells = <0>; compatible = "ibm,iic-440epx", "ibm,iic"; reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; interrupts = <0x2 0x4>; - - hwmon@48 { - compatible = "adi,ad7414"; - reg = <0x48>; - }; }; IIC1: i2c@ef600800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "ibm,iic-440epx", "ibm,iic"; reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; diff --git a/trunk/arch/powerpc/boot/dts/yosemite.dts b/trunk/arch/powerpc/boot/dts/yosemite.dts index 1fa3cb4c4ebb..e39422aa0d85 100644 --- a/trunk/arch/powerpc/boot/dts/yosemite.dts +++ b/trunk/arch/powerpc/boot/dts/yosemite.dts @@ -15,7 +15,7 @@ #address-cells = <2>; #size-cells = <1>; model = "amcc,yosemite"; - compatible = "amcc,yosemite"; + compatible = "amcc,yosemite","amcc,bamboo"; dcr-parent = <&{/cpus/cpu@0}>; aliases { diff --git a/trunk/arch/powerpc/boot/elf_util.c b/trunk/arch/powerpc/boot/elf_util.c index 1567a0c0f05c..7454aa4cc20c 100644 --- a/trunk/arch/powerpc/boot/elf_util.c +++ b/trunk/arch/powerpc/boot/elf_util.c @@ -27,8 +27,7 @@ int parse_elf64(void *hdr, struct elf_info *info) elf64->e_ident[EI_MAG3] == ELFMAG3 && elf64->e_ident[EI_CLASS] == ELFCLASS64 && elf64->e_ident[EI_DATA] == ELFDATA2MSB && - (elf64->e_type == ET_EXEC || - elf64->e_type == ET_DYN) && + elf64->e_type == ET_EXEC && elf64->e_machine == EM_PPC64)) return 0; @@ -59,8 +58,7 @@ int parse_elf32(void *hdr, struct elf_info *info) elf32->e_ident[EI_MAG3] == ELFMAG3 && elf32->e_ident[EI_CLASS] == ELFCLASS32 && elf32->e_ident[EI_DATA] == ELFDATA2MSB && - (elf32->e_type == ET_EXEC || - elf32->e_type == ET_DYN) && + elf32->e_type == ET_EXEC && elf32->e_machine == EM_PPC)) return 0; diff --git a/trunk/arch/powerpc/boot/libfdt/Makefile.libfdt b/trunk/arch/powerpc/boot/libfdt/Makefile.libfdt index 6c42acfa21ec..82f9c6a8287b 100644 --- a/trunk/arch/powerpc/boot/libfdt/Makefile.libfdt +++ b/trunk/arch/powerpc/boot/libfdt/Makefile.libfdt @@ -3,6 +3,12 @@ # This is not a complete Makefile of itself. Instead, it is designed to # be easily embeddable into other systems of Makefiles. # -LIBFDT_INCLUDES = fdt.h libfdt.h LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c +LIBFDT_INCLUDES = fdt.h libfdt.h +LIBFDT_EXTRA = libfdt_internal.h +LIBFDT_LIB = libfdt/libfdt.a + LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) + +$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS)) + diff --git a/trunk/arch/powerpc/boot/libfdt/fdt.c b/trunk/arch/powerpc/boot/libfdt/fdt.c index 2acaec5923ae..586a36136db2 100644 --- a/trunk/arch/powerpc/boot/libfdt/fdt.c +++ b/trunk/arch/powerpc/boot/libfdt/fdt.c @@ -63,7 +63,7 @@ int fdt_check_header(const void *fdt) return -FDT_ERR_BADVERSION; if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) return -FDT_ERR_BADVERSION; - } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + } else if (fdt_magic(fdt) == SW_MAGIC) { /* Unfinished sequential-write blob */ if (fdt_size_dt_struct(fdt) == 0) return -FDT_ERR_BADSTATE; @@ -76,7 +76,7 @@ int fdt_check_header(const void *fdt) const void *fdt_offset_ptr(const void *fdt, int offset, int len) { - const char *p; + const void *p; if (fdt_version(fdt) >= 0x11) if (((offset + len) < offset) @@ -124,59 +124,11 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) } if (nextoffset) - *nextoffset = FDT_TAGALIGN(offset); + *nextoffset = ALIGN(offset, FDT_TAGSIZE); return tag; } -int _fdt_check_node_offset(const void *fdt, int offset) -{ - if ((offset < 0) || (offset % FDT_TAGSIZE) - || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) - return -FDT_ERR_BADOFFSET; - - return offset; -} - -int fdt_next_node(const void *fdt, int offset, int *depth) -{ - int nextoffset = 0; - uint32_t tag; - - if (offset >= 0) - if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) - return nextoffset; - - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_PROP: - case FDT_NOP: - break; - - case FDT_BEGIN_NODE: - if (depth) - (*depth)++; - break; - - case FDT_END_NODE: - if (depth) - (*depth)--; - break; - - case FDT_END: - return -FDT_ERR_NOTFOUND; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (tag != FDT_BEGIN_NODE); - - return offset; -} - const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; @@ -184,14 +136,17 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) const char *p; for (p = strtab; p <= last; p++) - if (memcmp(p, s, len) == 0) + if (memeq(p, s, len)) return p; return NULL; } int fdt_move(const void *fdt, void *buf, int bufsize) { - FDT_CHECK_HEADER(fdt); + int err = fdt_check_header(fdt); + + if (err) + return err; if (fdt_totalsize(fdt) > bufsize) return -FDT_ERR_NOSPACE; diff --git a/trunk/arch/powerpc/boot/libfdt/fdt_ro.c b/trunk/arch/powerpc/boot/libfdt/fdt_ro.c index 129b532bcc1a..12a37d59f96e 100644 --- a/trunk/arch/powerpc/boot/libfdt/fdt_ro.c +++ b/trunk/arch/powerpc/boot/libfdt/fdt_ro.c @@ -55,10 +55,17 @@ #include "libfdt_internal.h" -static int _fdt_nodename_eq(const void *fdt, int offset, - const char *s, int len) +#define CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = fdt_check_header(fdt)) != 0) \ + return err; \ + } + +static int nodename_eq(const void *fdt, int offset, + const char *s, int len) { - const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); + const char *p = fdt_offset_ptr(fdt, offset, len+1); if (! p) /* short match */ @@ -77,12 +84,12 @@ static int _fdt_nodename_eq(const void *fdt, int offset, const char *fdt_string(const void *fdt, int stroffset) { - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset; } int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { - FDT_CHECK_HEADER(fdt); + CHECK_HEADER(fdt); *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); return 0; @@ -97,24 +104,50 @@ int fdt_num_mem_rsv(const void *fdt) return i; } -int fdt_subnode_offset_namelen(const void *fdt, int offset, +int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, const char *name, int namelen) { - int depth; + int level = 0; + uint32_t tag; + int offset, nextoffset; - FDT_CHECK_HEADER(fdt); + CHECK_HEADER(fdt); - for (depth = 0; - offset >= 0; - offset = fdt_next_node(fdt, offset, &depth)) { - if (depth < 0) - return -FDT_ERR_NOTFOUND; - else if ((depth == 1) - && _fdt_nodename_eq(fdt, offset, name, namelen)) - return offset; - } + tag = fdt_next_tag(fdt, parentoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_END: + return -FDT_ERR_TRUNCATED; + + case FDT_BEGIN_NODE: + level++; + if (level != 1) + continue; + if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen)) + /* Found it! */ + return offset; + break; + + case FDT_END_NODE: + level--; + break; + + case FDT_PROP: + case FDT_NOP: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (level >= 0); - return offset; /* error */ + return -FDT_ERR_NOTFOUND; } int fdt_subnode_offset(const void *fdt, int parentoffset, @@ -129,7 +162,7 @@ int fdt_path_offset(const void *fdt, const char *path) const char *p = path; int offset = 0; - FDT_CHECK_HEADER(fdt); + CHECK_HEADER(fdt); if (*path != '/') return -FDT_ERR_BADPATH; @@ -157,12 +190,16 @@ int fdt_path_offset(const void *fdt, const char *path) const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) { - const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); + const struct fdt_node_header *nh; int err; - if (((err = fdt_check_header(fdt)) != 0) - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) - goto fail; + if ((err = fdt_check_header(fdt)) != 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh)); + if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE)) + goto fail; if (len) *len = strlen(nh->name); @@ -185,11 +222,17 @@ const struct fdt_property *fdt_get_property(const void *fdt, int offset, nextoffset; int err; - if (((err = fdt_check_header(fdt)) != 0) - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) - goto fail; + if ((err = fdt_check_header(fdt)) != 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + if (nodeoffset % FDT_TAGSIZE) + goto fail; + + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + goto fail; - nextoffset = err; do { offset = nextoffset; @@ -210,7 +253,7 @@ const struct fdt_property *fdt_get_property(const void *fdt, if (! prop) goto fail; namestroff = fdt32_to_cpu(prop->nameoff); - if (strcmp(fdt_string(fdt, namestroff), name) == 0) { + if (streq(fdt_string(fdt, namestroff), name)) { /* Found it! */ int len = fdt32_to_cpu(prop->len); prop = fdt_offset_ptr(fdt, offset, @@ -264,91 +307,115 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) { - int pdepth = 0, p = 0; - int offset, depth, namelen; + uint32_t tag; + int p = 0, overflow = 0; + int offset, nextoffset, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + CHECK_HEADER(fdt); + + tag = fdt_next_tag(fdt, 0, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADSTRUCTURE; if (buflen < 2) return -FDT_ERR_NOSPACE; + buf[0] = '/'; + p = 1; - for (offset = 0, depth = 0; - (offset >= 0) && (offset <= nodeoffset); - offset = fdt_next_node(fdt, offset, &depth)) { - if (pdepth < depth) - continue; /* overflowed buffer */ - - while (pdepth > depth) { - do { - p--; - } while (buf[p-1] != '/'); - pdepth--; - } + while (nextoffset <= nodeoffset) { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_END: + return -FDT_ERR_BADOFFSET; - name = fdt_get_name(fdt, offset, &namelen); - if (!name) - return namelen; - if ((p + namelen + 1) <= buflen) { + case FDT_BEGIN_NODE: + name = fdt_get_name(fdt, offset, &namelen); + if (!name) + return namelen; + if (overflow || ((p + namelen + 1) > buflen)) { + overflow++; + break; + } memcpy(buf + p, name, namelen); p += namelen; buf[p++] = '/'; - pdepth++; - } - - if (offset == nodeoffset) { - if (pdepth < (depth + 1)) - return -FDT_ERR_NOSPACE; + break; - if (p > 1) /* special case so that root path is "/", not "" */ + case FDT_END_NODE: + if (overflow) { + overflow--; + break; + } + do { p--; - buf[p] = '\0'; - return p; + } while (buf[p-1] != '/'); + break; + + case FDT_PROP: + case FDT_NOP: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; } } - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (overflow) + return -FDT_ERR_NOSPACE; - return offset; /* error from fdt_next_node() */ + if (p > 1) /* special case so that root path is "/", not "" */ + p--; + buf[p] = '\0'; + return p; } int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int supernodedepth, int *nodedepth) { - int offset, depth; + int level = -1; + uint32_t tag; + int offset, nextoffset = 0; int supernodeoffset = -FDT_ERR_INTERNAL; - FDT_CHECK_HEADER(fdt); + CHECK_HEADER(fdt); if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; - for (offset = 0, depth = 0; - (offset >= 0) && (offset <= nodeoffset); - offset = fdt_next_node(fdt, offset, &depth)) { - if (depth == supernodedepth) - supernodeoffset = offset; + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_END: + return -FDT_ERR_BADOFFSET; + + case FDT_BEGIN_NODE: + level++; + if (level == supernodedepth) + supernodeoffset = offset; + break; + + case FDT_END_NODE: + level--; + break; - if (offset == nodeoffset) { - if (nodedepth) - *nodedepth = depth; + case FDT_PROP: + case FDT_NOP: + break; - if (supernodedepth > depth) - return -FDT_ERR_NOTFOUND; - else - return supernodeoffset; + default: + return -FDT_ERR_BADSTRUCTURE; } - } + } while (offset < nodeoffset); - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (nodedepth) + *nodedepth = level; - return offset; /* error from fdt_next_node() */ + if (supernodedepth > level) + return -FDT_ERR_NOTFOUND; + return supernodeoffset; } int fdt_node_depth(const void *fdt, int nodeoffset) @@ -376,27 +443,51 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const char *propname, const void *propval, int proplen) { - int offset; + uint32_t tag; + int offset, nextoffset; const void *val; int len; - FDT_CHECK_HEADER(fdt); + CHECK_HEADER(fdt); + + if (startoffset >= 0) { + tag = fdt_next_tag(fdt, startoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + } else { + nextoffset = 0; + } /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't * find what we want, we scan over them again making our way * to the next node. Still it's the easiest to implement * approach; performance can come later. */ - for (offset = fdt_next_node(fdt, startoffset, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - val = fdt_getprop(fdt, offset, propname, &len); - if (val && (len == proplen) - && (memcmp(val, propval, len) == 0)) - return offset; - } + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_BEGIN_NODE: + val = fdt_getprop(fdt, offset, propname, &len); + if (val + && (len == proplen) + && (memcmp(val, propval, len) == 0)) + return offset; + break; - return offset; /* error from fdt_next_node() */ + case FDT_PROP: + case FDT_END: + case FDT_END_NODE: + case FDT_NOP: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag != FDT_END); + + return -FDT_ERR_NOTFOUND; } int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) @@ -408,10 +499,10 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) &phandle, sizeof(phandle)); } -int _stringlist_contains(const char *strlist, int listlen, const char *str) +int _stringlist_contains(const void *strlist, int listlen, const char *str) { int len = strlen(str); - const char *p; + const void *p; while (listlen >= len) { if (memcmp(str, strlist, len+1) == 0) @@ -443,24 +534,50 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible) { - int offset, err; + uint32_t tag; + int offset, nextoffset; + int err; + + CHECK_HEADER(fdt); - FDT_CHECK_HEADER(fdt); + if (startoffset >= 0) { + tag = fdt_next_tag(fdt, startoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + } else { + nextoffset = 0; + } /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to * implement approach; performance can come later. */ - for (offset = fdt_next_node(fdt, startoffset, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - err = fdt_node_check_compatible(fdt, offset, compatible); - if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) - return err; - else if (err == 0) - return offset; - } + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_BEGIN_NODE: + err = fdt_node_check_compatible(fdt, offset, + compatible); + if ((err < 0) + && (err != -FDT_ERR_NOTFOUND)) + return err; + else if (err == 0) + return offset; + break; + + case FDT_PROP: + case FDT_END: + case FDT_END_NODE: + case FDT_NOP: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag != FDT_END); - return offset; /* error from fdt_next_node() */ + return -FDT_ERR_NOTFOUND; } diff --git a/trunk/arch/powerpc/boot/libfdt/fdt_rw.c b/trunk/arch/powerpc/boot/libfdt/fdt_rw.c index 8e7ec4cb7bcd..6673f8ec962a 100644 --- a/trunk/arch/powerpc/boot/libfdt/fdt_rw.c +++ b/trunk/arch/powerpc/boot/libfdt/fdt_rw.c @@ -55,10 +55,10 @@ #include "libfdt_internal.h" -static int _fdt_blocks_misordered(const void *fdt, +static int _blocks_misordered(const void *fdt, int mem_rsv_size, int struct_size) { - return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) + return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8)) || (fdt_off_dt_struct(fdt) < (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) || (fdt_off_dt_strings(fdt) < @@ -67,14 +67,16 @@ static int _fdt_blocks_misordered(const void *fdt, (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); } -static int _fdt_rw_check_header(void *fdt) +static int rw_check_header(void *fdt) { - FDT_CHECK_HEADER(fdt); + int err; + if ((err = fdt_check_header(fdt))) + return err; if (fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; - if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), - fdt_size_dt_struct(fdt))) + if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), + fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; if (fdt_version(fdt) > 17) fdt_set_version(fdt, 17); @@ -82,37 +84,36 @@ static int _fdt_rw_check_header(void *fdt) return 0; } -#define FDT_RW_CHECK_HEADER(fdt) \ +#define RW_CHECK_HEADER(fdt) \ { \ int err; \ - if ((err = _fdt_rw_check_header(fdt)) != 0) \ + if ((err = rw_check_header(fdt)) != 0) \ return err; \ } -static inline int _fdt_data_size(void *fdt) +static inline int _blob_data_size(void *fdt) { return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); } -static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) +static int _blob_splice(void *fdt, void *p, int oldlen, int newlen) { - char *p = splicepoint; - char *end = (char *)fdt + _fdt_data_size(fdt); + void *end = fdt + _blob_data_size(fdt); if (((p + oldlen) < p) || ((p + oldlen) > end)) return -FDT_ERR_BADOFFSET; - if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) + if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt))) return -FDT_ERR_NOSPACE; memmove(p + newlen, p + oldlen, end - p - oldlen); return 0; } -static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, - int oldn, int newn) +static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, + int oldn, int newn) { int delta = (newn - oldn) * sizeof(*p); int err; - err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); + err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); if (err) return err; fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); @@ -120,13 +121,13 @@ static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, return 0; } -static int _fdt_splice_struct(void *fdt, void *p, - int oldlen, int newlen) +static int _blob_splice_struct(void *fdt, void *p, + int oldlen, int newlen) { int delta = newlen - oldlen; int err; - if ((err = _fdt_splice(fdt, p, oldlen, newlen))) + if ((err = _blob_splice(fdt, p, oldlen, newlen))) return err; fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); @@ -134,20 +135,19 @@ static int _fdt_splice_struct(void *fdt, void *p, return 0; } -static int _fdt_splice_string(void *fdt, int newlen) +static int _blob_splice_string(void *fdt, int newlen) { - void *p = (char *)fdt - + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); + void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); int err; - if ((err = _fdt_splice(fdt, p, 0, newlen))) + if ((err = _blob_splice(fdt, p, 0, newlen))) return err; fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); return 0; } -static int _fdt_find_add_string(void *fdt, const char *s) +static int _find_add_string(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); const char *p; @@ -161,7 +161,7 @@ static int _fdt_find_add_string(void *fdt, const char *s) return (p - strtab); new = strtab + fdt_size_dt_strings(fdt); - err = _fdt_splice_string(fdt, len); + err = _blob_splice_string(fdt, len); if (err) return err; @@ -174,10 +174,11 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) struct fdt_reserve_entry *re; int err; - FDT_RW_CHECK_HEADER(fdt); + if ((err = rw_check_header(fdt))) + return err; re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); - err = _fdt_splice_mem_rsv(fdt, re, 0, 1); + err = _blob_splice_mem_rsv(fdt, re, 0, 1); if (err) return err; @@ -191,19 +192,19 @@ int fdt_del_mem_rsv(void *fdt, int n) struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); int err; - FDT_RW_CHECK_HEADER(fdt); - + if ((err = rw_check_header(fdt))) + return err; if (n >= fdt_num_mem_rsv(fdt)) return -FDT_ERR_NOTFOUND; - err = _fdt_splice_mem_rsv(fdt, re, 1, 0); + err = _blob_splice_mem_rsv(fdt, re, 1, 0); if (err) return err; return 0; } -static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, - int len, struct fdt_property **prop) +static int _resize_property(void *fdt, int nodeoffset, const char *name, int len, + struct fdt_property **prop) { int oldlen; int err; @@ -212,33 +213,36 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, if (! (*prop)) return oldlen; - if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), - FDT_TAGALIGN(len)))) + if ((err = _blob_splice_struct(fdt, (*prop)->data, + ALIGN(oldlen, FDT_TAGSIZE), + ALIGN(len, FDT_TAGSIZE)))) return err; (*prop)->len = cpu_to_fdt32(len); return 0; } -static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, - int len, struct fdt_property **prop) +static int _add_property(void *fdt, int nodeoffset, const char *name, int len, + struct fdt_property **prop) { + uint32_t tag; int proplen; int nextoffset; int namestroff; int err; - if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) - return nextoffset; + tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; - namestroff = _fdt_find_add_string(fdt, name); + namestroff = _find_add_string(fdt, name); if (namestroff < 0) return namestroff; *prop = _fdt_offset_ptr_w(fdt, nextoffset); - proplen = sizeof(**prop) + FDT_TAGALIGN(len); + proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE); - err = _fdt_splice_struct(fdt, *prop, 0, proplen); + err = _blob_splice_struct(fdt, *prop, 0, proplen); if (err) return err; @@ -248,40 +252,18 @@ static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, return 0; } -int fdt_set_name(void *fdt, int nodeoffset, const char *name) -{ - char *namep; - int oldlen, newlen; - int err; - - FDT_RW_CHECK_HEADER(fdt); - - namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); - if (!namep) - return oldlen; - - newlen = strlen(name); - - err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), - FDT_TAGALIGN(newlen+1)); - if (err) - return err; - - memcpy(namep, name, newlen+1); - return 0; -} - int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len) { struct fdt_property *prop; int err; - FDT_RW_CHECK_HEADER(fdt); + if ((err = rw_check_header(fdt))) + return err; - err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); + err = _resize_property(fdt, nodeoffset, name, len, &prop); if (err == -FDT_ERR_NOTFOUND) - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); + err = _add_property(fdt, nodeoffset, name, len, &prop); if (err) return err; @@ -294,14 +276,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) struct fdt_property *prop; int len, proplen; - FDT_RW_CHECK_HEADER(fdt); + RW_CHECK_HEADER(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &len); if (! prop) return len; - proplen = sizeof(*prop) + FDT_TAGALIGN(len); - return _fdt_splice_struct(fdt, prop, proplen, 0); + proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE); + return _blob_splice_struct(fdt, prop, proplen, 0); } int fdt_add_subnode_namelen(void *fdt, int parentoffset, @@ -314,7 +296,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, uint32_t tag; uint32_t *endtag; - FDT_RW_CHECK_HEADER(fdt); + RW_CHECK_HEADER(fdt); offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); if (offset >= 0) @@ -327,19 +309,19 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, do { offset = nextoffset; tag = fdt_next_tag(fdt, offset, &nextoffset); - } while ((tag == FDT_PROP) || (tag == FDT_NOP)); + } while (tag == FDT_PROP); nh = _fdt_offset_ptr_w(fdt, offset); - nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; + nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE; - err = _fdt_splice_struct(fdt, nh, 0, nodelen); + err = _blob_splice_struct(fdt, nh, 0, nodelen); if (err) return err; nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); - memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); + memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE)); memcpy(nh->name, name, namelen); - endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE); + endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE); *endtag = cpu_to_fdt32(FDT_END_NODE); return offset; @@ -354,36 +336,36 @@ int fdt_del_node(void *fdt, int nodeoffset) { int endoffset; - FDT_RW_CHECK_HEADER(fdt); + RW_CHECK_HEADER(fdt); endoffset = _fdt_node_end_offset(fdt, nodeoffset); if (endoffset < 0) return endoffset; - return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), - endoffset - nodeoffset, 0); + return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), + endoffset - nodeoffset, 0); } -static void _fdt_packblocks(const char *old, char *new, - int mem_rsv_size, int struct_size) +static void _packblocks(const void *fdt, void *buf, + int mem_rsv_size, int struct_size) { int mem_rsv_off, struct_off, strings_off; - mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); + mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8); struct_off = mem_rsv_off + mem_rsv_size; strings_off = struct_off + struct_size; - memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); - fdt_set_off_mem_rsvmap(new, mem_rsv_off); + memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size); + fdt_set_off_mem_rsvmap(buf, mem_rsv_off); - memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); - fdt_set_off_dt_struct(new, struct_off); - fdt_set_size_dt_struct(new, struct_size); + memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size); + fdt_set_off_dt_struct(buf, struct_off); + fdt_set_size_dt_struct(buf, struct_size); - memmove(new + strings_off, old + fdt_off_dt_strings(old), - fdt_size_dt_strings(old)); - fdt_set_off_dt_strings(new, strings_off); - fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); + memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt), + fdt_size_dt_strings(fdt)); + fdt_set_off_dt_strings(buf, strings_off); + fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt)); } int fdt_open_into(const void *fdt, void *buf, int bufsize) @@ -391,11 +373,11 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) int err; int mem_rsv_size, struct_size; int newsize; - const char *fdtstart = fdt; - const char *fdtend = fdtstart + fdt_totalsize(fdt); - char *tmp; + void *tmp; - FDT_CHECK_HEADER(fdt); + err = fdt_check_header(fdt); + if (err) + return err; mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); @@ -408,7 +390,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) ; } - if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { + if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) { /* no further work necessary */ err = fdt_move(fdt, buf, bufsize); if (err) @@ -420,23 +402,22 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) } /* Need to reorder */ - newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size + newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size + struct_size + fdt_size_dt_strings(fdt); if (bufsize < newsize) return -FDT_ERR_NOSPACE; - /* First attempt to build converted tree at beginning of buffer */ - tmp = buf; - /* But if that overlaps with the old tree... */ - if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { - /* Try right after the old tree instead */ - tmp = (char *)(uintptr_t)fdtend; - if ((tmp + newsize) > ((char *)buf + bufsize)) + if (((buf + newsize) <= fdt) + || (buf >= (fdt + fdt_totalsize(fdt)))) { + tmp = buf; + } else { + tmp = (void *)fdt + fdt_totalsize(fdt); + if ((tmp + newsize) > (buf + bufsize)) return -FDT_ERR_NOSPACE; } - _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); + _packblocks(fdt, tmp, mem_rsv_size, struct_size); memmove(buf, tmp, newsize); fdt_set_magic(buf, FDT_MAGIC); @@ -451,13 +432,16 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) int fdt_pack(void *fdt) { int mem_rsv_size; + int err; - FDT_RW_CHECK_HEADER(fdt); + err = rw_check_header(fdt); + if (err) + return err; mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); - _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); - fdt_set_totalsize(fdt, _fdt_data_size(fdt)); + _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); + fdt_set_totalsize(fdt, _blob_data_size(fdt)); return 0; } diff --git a/trunk/arch/powerpc/boot/libfdt/fdt_strerror.c b/trunk/arch/powerpc/boot/libfdt/fdt_strerror.c index e6c3ceee8c58..f9d32ef5360a 100644 --- a/trunk/arch/powerpc/boot/libfdt/fdt_strerror.c +++ b/trunk/arch/powerpc/boot/libfdt/fdt_strerror.c @@ -55,29 +55,29 @@ #include "libfdt_internal.h" -struct fdt_errtabent { +struct errtabent { const char *str; }; -#define FDT_ERRTABENT(val) \ +#define ERRTABENT(val) \ [(val)] = { .str = #val, } -static struct fdt_errtabent fdt_errtable[] = { - FDT_ERRTABENT(FDT_ERR_NOTFOUND), - FDT_ERRTABENT(FDT_ERR_EXISTS), - FDT_ERRTABENT(FDT_ERR_NOSPACE), +static struct errtabent errtable[] = { + ERRTABENT(FDT_ERR_NOTFOUND), + ERRTABENT(FDT_ERR_EXISTS), + ERRTABENT(FDT_ERR_NOSPACE), - FDT_ERRTABENT(FDT_ERR_BADOFFSET), - FDT_ERRTABENT(FDT_ERR_BADPATH), - FDT_ERRTABENT(FDT_ERR_BADSTATE), + ERRTABENT(FDT_ERR_BADOFFSET), + ERRTABENT(FDT_ERR_BADPATH), + ERRTABENT(FDT_ERR_BADSTATE), - FDT_ERRTABENT(FDT_ERR_TRUNCATED), - FDT_ERRTABENT(FDT_ERR_BADMAGIC), - FDT_ERRTABENT(FDT_ERR_BADVERSION), - FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), - FDT_ERRTABENT(FDT_ERR_BADLAYOUT), + ERRTABENT(FDT_ERR_TRUNCATED), + ERRTABENT(FDT_ERR_BADMAGIC), + ERRTABENT(FDT_ERR_BADVERSION), + ERRTABENT(FDT_ERR_BADSTRUCTURE), + ERRTABENT(FDT_ERR_BADLAYOUT), }; -#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) +#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0])) const char *fdt_strerror(int errval) { @@ -85,8 +85,8 @@ const char *fdt_strerror(int errval) return ""; else if (errval == 0) return ""; - else if (errval > -FDT_ERRTABSIZE) { - const char *s = fdt_errtable[-errval].str; + else if (errval > -ERRTABSIZE) { + const char *s = errtable[-errval].str; if (s) return s; diff --git a/trunk/arch/powerpc/boot/libfdt/fdt_sw.c b/trunk/arch/powerpc/boot/libfdt/fdt_sw.c index 698329e0ccaf..dda2de34b2e0 100644 --- a/trunk/arch/powerpc/boot/libfdt/fdt_sw.c +++ b/trunk/arch/powerpc/boot/libfdt/fdt_sw.c @@ -55,22 +55,14 @@ #include "libfdt_internal.h" -static int _fdt_sw_check_header(void *fdt) +static int check_header_sw(void *fdt) { - if (fdt_magic(fdt) != FDT_SW_MAGIC) + if (fdt_magic(fdt) != SW_MAGIC) return -FDT_ERR_BADMAGIC; - /* FIXME: should check more details about the header state */ return 0; } -#define FDT_SW_CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = _fdt_sw_check_header(fdt)) != 0) \ - return err; \ - } - -static void *_fdt_grab_space(void *fdt, int len) +static void *grab_space(void *fdt, int len) { int offset = fdt_size_dt_struct(fdt); int spaceleft; @@ -94,13 +86,13 @@ int fdt_create(void *buf, int bufsize) memset(buf, 0, bufsize); - fdt_set_magic(fdt, FDT_SW_MAGIC); + fdt_set_magic(fdt, SW_MAGIC); fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); fdt_set_totalsize(fdt, bufsize); - fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), - sizeof(struct fdt_reserve_entry))); + fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry))); fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); fdt_set_off_dt_strings(fdt, bufsize); @@ -110,10 +102,11 @@ int fdt_create(void *buf, int bufsize) int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) { struct fdt_reserve_entry *re; + int err = check_header_sw(fdt); int offset; - FDT_SW_CHECK_HEADER(fdt); - + if (err) + return err; if (fdt_size_dt_struct(fdt)) return -FDT_ERR_BADSTATE; @@ -121,7 +114,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) return -FDT_ERR_NOSPACE; - re = (struct fdt_reserve_entry *)((char *)fdt + offset); + re = (struct fdt_reserve_entry *)(fdt + offset); re->address = cpu_to_fdt64(addr); re->size = cpu_to_fdt64(size); @@ -138,11 +131,13 @@ int fdt_finish_reservemap(void *fdt) int fdt_begin_node(void *fdt, const char *name) { struct fdt_node_header *nh; + int err = check_header_sw(fdt); int namelen = strlen(name) + 1; - FDT_SW_CHECK_HEADER(fdt); + if (err) + return err; - nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); + nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE)); if (! nh) return -FDT_ERR_NOSPACE; @@ -154,10 +149,12 @@ int fdt_begin_node(void *fdt, const char *name) int fdt_end_node(void *fdt) { uint32_t *en; + int err = check_header_sw(fdt); - FDT_SW_CHECK_HEADER(fdt); + if (err) + return err; - en = _fdt_grab_space(fdt, FDT_TAGSIZE); + en = grab_space(fdt, FDT_TAGSIZE); if (! en) return -FDT_ERR_NOSPACE; @@ -165,7 +162,7 @@ int fdt_end_node(void *fdt) return 0; } -static int _fdt_find_add_string(void *fdt, const char *s) +static int find_add_string(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_totalsize(fdt); const char *p; @@ -191,15 +188,17 @@ static int _fdt_find_add_string(void *fdt, const char *s) int fdt_property(void *fdt, const char *name, const void *val, int len) { struct fdt_property *prop; + int err = check_header_sw(fdt); int nameoff; - FDT_SW_CHECK_HEADER(fdt); + if (err) + return err; - nameoff = _fdt_find_add_string(fdt, name); + nameoff = find_add_string(fdt, name); if (nameoff == 0) return -FDT_ERR_NOSPACE; - prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); + prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE)); if (! prop) return -FDT_ERR_NOSPACE; @@ -212,16 +211,18 @@ int fdt_property(void *fdt, const char *name, const void *val, int len) int fdt_finish(void *fdt) { + int err = check_header_sw(fdt); char *p = (char *)fdt; uint32_t *end; int oldstroffset, newstroffset; uint32_t tag; int offset, nextoffset; - FDT_SW_CHECK_HEADER(fdt); + if (err) + return err; /* Add terminator */ - end = _fdt_grab_space(fdt, sizeof(*end)); + end = grab_space(fdt, sizeof(*end)); if (! end) return -FDT_ERR_NOSPACE; *end = cpu_to_fdt32(FDT_END); diff --git a/trunk/arch/powerpc/boot/libfdt/fdt_wip.c b/trunk/arch/powerpc/boot/libfdt/fdt_wip.c index a4652c6e787e..88e24b8318f4 100644 --- a/trunk/arch/powerpc/boot/libfdt/fdt_wip.c +++ b/trunk/arch/powerpc/boot/libfdt/fdt_wip.c @@ -72,11 +72,11 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, return 0; } -static void _fdt_nop_region(void *start, int len) +static void nop_region(void *start, int len) { uint32_t *p; - for (p = start; (char *)p < ((char *)start + len); p++) + for (p = start; (void *)p < (start + len); p++) *p = cpu_to_fdt32(FDT_NOP); } @@ -89,7 +89,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) if (! prop) return len; - _fdt_nop_region(prop, len + sizeof(*prop)); + nop_region(prop, len + sizeof(*prop)); return 0; } @@ -139,7 +139,6 @@ int fdt_nop_node(void *fdt, int nodeoffset) if (endoffset < 0) return endoffset; - _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), - endoffset - nodeoffset); + nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset); return 0; } diff --git a/trunk/arch/powerpc/boot/libfdt/libfdt.h b/trunk/arch/powerpc/boot/libfdt/libfdt.h index ce80e4fb41b2..6b2fb92ea357 100644 --- a/trunk/arch/powerpc/boot/libfdt/libfdt.h +++ b/trunk/arch/powerpc/boot/libfdt/libfdt.h @@ -125,17 +125,11 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int checklen); static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) { - return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); + return (void *)fdt_offset_ptr(fdt, offset, checklen); } uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); -/**********************************************************************/ -/* Traversal functions */ -/**********************************************************************/ - -int fdt_next_node(const void *fdt, int offset, int *depth); - /**********************************************************************/ /* General functions */ /**********************************************************************/ @@ -213,7 +207,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize); /**********************************************************************/ /** - * fdt_string - retrieve a string from the strings block of a device tree + * fdt_string - retreive a string from the strings block of a device tree * @fdt: pointer to the device tree blob * @stroffset: offset of the string within the strings block (native endian) * @@ -227,7 +221,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize); const char *fdt_string(const void *fdt, int stroffset); /** - * fdt_num_mem_rsv - retrieve the number of memory reserve map entries + * fdt_num_mem_rsv - retreive the number of memory reserve map entries * @fdt: pointer to the device tree blob * * Returns the number of entries in the device tree blob's memory @@ -240,7 +234,7 @@ const char *fdt_string(const void *fdt, int stroffset); int fdt_num_mem_rsv(const void *fdt); /** - * fdt_get_mem_rsv - retrieve one memory reserve map entry + * fdt_get_mem_rsv - retreive one memory reserve map entry * @fdt: pointer to the device tree blob * @address, @size: pointers to 64-bit variables * @@ -320,7 +314,7 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); int fdt_path_offset(const void *fdt, const char *path); /** - * fdt_get_name - retrieve the name of a given node + * fdt_get_name - retreive the name of a given node * @fdt: pointer to the device tree blob * @nodeoffset: structure block offset of the starting node * @lenp: pointer to an integer variable (will be overwritten) or NULL @@ -352,7 +346,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); * fdt_get_property() retrieves a pointer to the fdt_property * structure within the device tree blob corresponding to the property * named 'name' of the node at offset nodeoffset. If lenp is - * non-NULL, the length of the property value is also returned, in the + * non-NULL, the length of the property value also returned, in the * integer pointed to by lenp. * * returns: @@ -375,8 +369,8 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, const char *name, int *lenp) { - return (struct fdt_property *)(uintptr_t) - fdt_get_property(fdt, nodeoffset, name, lenp); + return (struct fdt_property *)fdt_get_property(fdt, nodeoffset, + name, lenp); } /** @@ -389,7 +383,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, * fdt_getprop() retrieves a pointer to the value of the property * named 'name' of the node at offset nodeoffset (this will be a * pointer to within the device blob itself, not a copy of the value). - * If lenp is non-NULL, the length of the property value is also + * If lenp is non-NULL, the length of the property value also * returned, in the integer pointed to by lenp. * * returns: @@ -411,11 +405,11 @@ const void *fdt_getprop(const void *fdt, int nodeoffset, static inline void *fdt_getprop_w(void *fdt, int nodeoffset, const char *name, int *lenp) { - return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); + return (void *)fdt_getprop(fdt, nodeoffset, name, lenp); } /** - * fdt_get_phandle - retrieve the phandle of a given node + * fdt_get_phandle - retreive the phandle of a given node * @fdt: pointer to the device tree blob * @nodeoffset: structure block offset of the node * @@ -423,7 +417,7 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset, * structure block offset nodeoffset. * * returns: - * the phandle of the node at nodeoffset, on success (!= 0, != -1) + * the phandle of the node at nodeoffset, on succes (!= 0, != -1) * 0, if the node has no phandle, or another error occurs */ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); @@ -522,7 +516,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset); * structure from the start to nodeoffset, *twice*. * * returns: - * structure block offset of the parent of the node at nodeoffset + * stucture block offset of the parent of the node at nodeoffset * (>=0), on success * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_BADMAGIC, @@ -579,7 +573,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, * @fdt: pointer to the device tree blob * @phandle: phandle value * - * fdt_node_offset_by_phandle() returns the offset of the node + * fdt_node_offset_by_prop_value() returns the offset of the node * which has the given phandle value. If there is more than one node * in the tree with the given phandle (an invalid tree), results are * undefined. @@ -661,65 +655,8 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, /* Write-in-place functions */ /**********************************************************************/ -/** - * fdt_setprop_inplace - change a property's value, but not its size - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: pointer to data to replace the property value with - * @len: length of the property value - * - * fdt_setprop_inplace() replaces the value of a given property with - * the data in val, of length len. This function cannot change the - * size of a property, and so will only work if len is equal to the - * current length of the property. - * - * This function will alter only the bytes in the blob which contain - * the given property value, and will not alter or move any other part - * of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, if len is not equal to the property's current length - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, const void *val, int len); - -/** - * fdt_setprop_inplace_cell - change the value of a single-cell property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: cell (32-bit integer) value to replace the property with - * - * fdt_setprop_inplace_cell() replaces the value of a given property - * with the 32-bit integer cell value in val, converting val to - * big-endian if necessary. This function cannot change the size of a - * property, and so will only work if the property already exists and - * has length 4. - * - * This function will alter only the bytes in the blob which contain - * the given property value, and will not alter or move any other part - * of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, const char *name, uint32_t val) { @@ -727,54 +664,7 @@ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); } -/** - * fdt_nop_property - replace a property with nop tags - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to nop - * @name: name of the property to nop - * - * fdt_nop_property() will replace a given property's representation - * in the blob with FDT_NOP tags, effectively removing it from the - * tree. - * - * This function will alter only the bytes in the blob which contain - * the property, and will not alter or move any other part of the - * tree. - * - * returns: - * 0, on success - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_nop_property(void *fdt, int nodeoffset, const char *name); - -/** - * fdt_nop_node - replace a node (subtree) with nop tags - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node to nop - * - * fdt_nop_node() will replace a given node's representation in the - * blob, including all its subnodes, if any, with FDT_NOP tags, - * effectively removing it from the tree. - * - * This function will alter only the bytes in the blob which contain - * the node and its properties and subnodes, and will not alter or - * move any other part of the tree. - * - * returns: - * 0, on success - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_nop_node(void *fdt, int nodeoffset); /**********************************************************************/ @@ -803,268 +693,23 @@ int fdt_finish(void *fdt); int fdt_open_into(const void *fdt, void *buf, int bufsize); int fdt_pack(void *fdt); -/** - * fdt_add_mem_rsv - add one memory reserve map entry - * @fdt: pointer to the device tree blob - * @address, @size: 64-bit values (native endian) - * - * Adds a reserve map entry to the given blob reserving a region at - * address address of length size. - * - * This function will insert data into the reserve map and will - * therefore change the indexes of some entries in the table. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new reservation entry - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); - -/** - * fdt_del_mem_rsv - remove a memory reserve map entry - * @fdt: pointer to the device tree blob - * @n: entry to remove - * - * fdt_del_mem_rsv() removes the n-th memory reserve map entry from - * the blob. - * - * This function will delete data from the reservation table and will - * therefore change the indexes of some entries in the table. - * - * returns: - * 0, on success - * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there - * are less than n+1 reserve map entries) - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_del_mem_rsv(void *fdt, int n); -/** - * fdt_set_name - change the name of a given node - * @fdt: pointer to the device tree blob - * @nodeoffset: structure block offset of a node - * @name: name to give the node - * - * fdt_set_name() replaces the name (including unit address, if any) - * of the given node with the given string. NOTE: this function can't - * efficiently check if the new name is unique amongst the given - * node's siblings; results are undefined if this function is invoked - * with a name equal to one of the given node's siblings. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob - * to contain the new name - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings - */ -int fdt_set_name(void *fdt, int nodeoffset, const char *name); - -/** - * fdt_setprop - create or change a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: pointer to data to set the property value to - * @len: length of the property value - * - * fdt_setprop() sets the value of the named property in the given - * node to the given value and length, creating the property if it - * does not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len); - -/** - * fdt_setprop_cell - set a property to a single cell value - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @val: 32-bit integer value for the property (native endian) - * - * fdt_setprop_cell() sets the value of the named property in the - * given node to the given cell value (converting to big-endian if - * necessary), or creates a new property with that value if it does - * not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, uint32_t val) { val = cpu_to_fdt32(val); return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); } - -/** - * fdt_setprop_string - set a property to a string value - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change - * @name: name of the property to change - * @str: string value for the property - * - * fdt_setprop_string() sets the value of the named property in the - * given node to the given string value (using the length of the - * string to determine the new length of the property), or creates a - * new property with that value if it does not already exist. - * - * This function may insert or delete data from the blob, and will - * therefore change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to - * contain the new property value - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_TRUNCATED, standard meanings - */ #define fdt_setprop_string(fdt, nodeoffset, name, str) \ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) - -/** - * fdt_delprop - delete a property - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to nop - * @name: name of the property to nop - * - * fdt_del_property() will delete the given property. - * - * This function will delete data from the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_NOTFOUND, node does not have the named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_delprop(void *fdt, int nodeoffset, const char *name); - -/** - * fdt_add_subnode_namelen - creates a new node based on substring - * @fdt: pointer to the device tree blob - * @parentoffset: structure block offset of a node - * @name: name of the subnode to locate - * @namelen: number of characters of name to consider - * - * Identical to fdt_add_subnode(), but use only the first namelen - * characters of name as the name of the new node. This is useful for - * creating subnodes based on a portion of a larger string, such as a - * full path. - */ int fdt_add_subnode_namelen(void *fdt, int parentoffset, const char *name, int namelen); - -/** - * fdt_add_subnode - creates a new node - * @fdt: pointer to the device tree blob - * @parentoffset: structure block offset of a node - * @name: name of the subnode to locate - * - * fdt_add_subnode() creates a new node as a subnode of the node at - * structure block offset parentoffset, with the given name (which - * should include the unit address, if any). - * - * This function will insert data into the blob, and will therefore - * change the offsets of some existing nodes. - - * returns: - * structure block offset of the created nodeequested subnode (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist - * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag - * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of - * the given name - * -FDT_ERR_NOSPACE, if there is insufficient free space in the - * blob to contain the new node - * -FDT_ERR_NOSPACE - * -FDT_ERR_BADLAYOUT - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings. - */ int fdt_add_subnode(void *fdt, int parentoffset, const char *name); - -/** - * fdt_del_node - delete a node (subtree) - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node to nop - * - * fdt_del_node() will remove the given node, including all its - * subnodes if any, from the blob. - * - * This function will delete data from the blob, and will therefore - * change the offsets of some existing nodes. - * - * returns: - * 0, on success - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag - * -FDT_ERR_BADLAYOUT, - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, - * -FDT_ERR_TRUNCATED, standard meanings - */ int fdt_del_node(void *fdt, int nodeoffset); /**********************************************************************/ diff --git a/trunk/arch/powerpc/boot/libfdt/libfdt_internal.h b/trunk/arch/powerpc/boot/libfdt/libfdt_internal.h index 46eb93e4af5c..1e60936beb5b 100644 --- a/trunk/arch/powerpc/boot/libfdt/libfdt_internal.h +++ b/trunk/arch/powerpc/boot/libfdt/libfdt_internal.h @@ -52,44 +52,38 @@ */ #include -#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a))) -#define FDT_CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = fdt_check_header(fdt)) != 0) \ - return err; \ - } +#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0) +#define streq(p, q) (strcmp((p), (q)) == 0) uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); -int _fdt_check_node_offset(const void *fdt, int offset); const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); int _fdt_node_end_offset(void *fdt, int nodeoffset); static inline const void *_fdt_offset_ptr(const void *fdt, int offset) { - return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; + return fdt + fdt_off_dt_struct(fdt) + offset; } static inline void *_fdt_offset_ptr_w(void *fdt, int offset) { - return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); + return (void *)_fdt_offset_ptr(fdt, offset); } static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) { const struct fdt_reserve_entry *rsv_table = - (const struct fdt_reserve_entry *) - ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); + fdt + fdt_off_mem_rsvmap(fdt); return rsv_table + n; } static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) { - return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); + return (void *)_fdt_mem_rsv(fdt, n); } -#define FDT_SW_MAGIC (~FDT_MAGIC) +#define SW_MAGIC (~FDT_MAGIC) #endif /* _LIBFDT_INTERNAL_H */ diff --git a/trunk/arch/powerpc/boot/libfdt_env.h b/trunk/arch/powerpc/boot/libfdt_env.h index c89fdb1b80e1..a4b0fc959ece 100644 --- a/trunk/arch/powerpc/boot/libfdt_env.h +++ b/trunk/arch/powerpc/boot/libfdt_env.h @@ -6,7 +6,6 @@ typedef u32 uint32_t; typedef u64 uint64_t; -typedef unsigned long uintptr_t; #define fdt16_to_cpu(x) (x) #define cpu_to_fdt16(x) (x) diff --git a/trunk/arch/powerpc/boot/wrapper b/trunk/arch/powerpc/boot/wrapper index ee0dc41d7c56..965c237c122d 100755 --- a/trunk/arch/powerpc/boot/wrapper +++ b/trunk/arch/powerpc/boot/wrapper @@ -307,9 +307,7 @@ fi # post-processing needed for some platforms case "$platform" in pseries|chrp) - ${CROSS}objcopy -O binary -j .fakeelf "$kernel" "$ofile".rpanote - $objbin/addnote "$ofile" "$ofile".rpanote - rm -r "$ofile".rpanote + $objbin/addnote "$ofile" ;; coff) ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" diff --git a/trunk/arch/powerpc/configs/44x/arches_defconfig b/trunk/arch/powerpc/configs/44x/arches_defconfig deleted file mode 100644 index 70f46078eb6a..000000000000 --- a/trunk/arch/powerpc/configs/44x/arches_defconfig +++ /dev/null @@ -1,767 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc5 -# Wed Oct 1 15:54:57 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -# CONFIG_6xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -CONFIG_44x=y -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -CONFIG_4xx=y -CONFIG_BOOKE=y -CONFIG_PTE_64BIT=y -CONFIG_PHYS_64BIT=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set -CONFIG_PPC_DCR_NATIVE=y -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_PPC_DCR=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -# CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_HAVE_DMA_ATTRS is not set -# CONFIG_USE_GENERIC_SMP_HELPERS is not set -# CONFIG_HAVE_CLK is not set -CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y -CONFIG_PPC4xx_PCI_EXPRESS=y - -# -# Platform support -# -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -# CONFIG_BAMBOO is not set -# CONFIG_EBONY is not set -# CONFIG_SAM440EP is not set -# CONFIG_SEQUOIA is not set -# CONFIG_TAISHAN is not set -# CONFIG_KATMAI is not set -# CONFIG_RAINIER is not set -# CONFIG_WARP is not set -CONFIG_ARCHES=y -# CONFIG_CANYONLANDS is not set -# CONFIG_GLACIER is not set -# CONFIG_YOSEMITE is not set -# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set -CONFIG_PPC44x_SIMPLE=y -CONFIG_460EX=y -# CONFIG_IPIC is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_FSL_ULI1575 is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_MATH_EMULATION is not set -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_PROC_DEVICETREE=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -CONFIG_EXTRA_TARGETS="" -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_4xx_SOC=y -CONFIG_PPC_PCI_CHOICE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -# CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_CONSISTENT_START=0xff100000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set -CONFIG_OF_DEVICE=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=35000 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_XILINX_SYSACE is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_IBM_NEW_EMAC=y -CONFIG_IBM_NEW_EMAC_RXB=256 -CONFIG_IBM_NEW_EMAC_TXB=256 -CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -# CONFIG_IBM_NEW_EMAC_DEBUG is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -CONFIG_IBM_NEW_EMAC_TAH=y -CONFIG_IBM_NEW_EMAC_EMAC4=y -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -# CONFIG_I2C is not set -# CONFIG_SPI is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -# CONFIG_GPIOLIB is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_XMON is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_VIRQ_DEBUG is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/83xx/asp8347_defconfig b/trunk/arch/powerpc/configs/83xx/asp8347_defconfig index 0b1fa20f745c..5e6780a088ce 100644 --- a/trunk/arch/powerpc/configs/83xx/asp8347_defconfig +++ b/trunk/arch/powerpc/configs/83xx/asp8347_defconfig @@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig index b7eae2bdf19c..2028337868b4 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/trunk/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig index b0a27a67d8c7..dd80eb0a87a1 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc832x_mds_defconfig b/trunk/arch/powerpc/configs/83xx/mpc832x_mds_defconfig index ad825bcddd1f..bdf50c8a17e6 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc832x_mds_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc832x_mds_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig b/trunk/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig index 38267501f44d..4eef8c95480e 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/trunk/arch/powerpc/configs/83xx/mpc834x_itx_defconfig index 90aab340e7ff..8d6513931850 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc834x_itx_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc834x_itx_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig b/trunk/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig index 7458a242d251..a8afa39d6f76 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc834x_mds_defconfig b/trunk/arch/powerpc/configs/83xx/mpc834x_mds_defconfig index 1a92798938cf..24c320a36670 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc834x_mds_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc834x_mds_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc836x_mds_defconfig b/trunk/arch/powerpc/configs/83xx/mpc836x_mds_defconfig index 03d8cede0272..e029e9e14622 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc836x_mds_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc836x_mds_defconfig @@ -163,11 +163,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set @@ -383,84 +383,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_OF_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set +# CONFIG_MTD is not set CONFIG_OF_DEVICE=y CONFIG_OF_I2C=y # CONFIG_PARPORT is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/trunk/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig index cdf84177370a..7d674be702fe 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig @@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc837x_mds_defconfig b/trunk/arch/powerpc/configs/83xx/mpc837x_mds_defconfig index 97e02d7a5b09..de472022aa81 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc837x_mds_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc837x_mds_defconfig @@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig b/trunk/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig index 5ac33054ce2c..e8d2d691d26c 100644 --- a/trunk/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig +++ b/trunk/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig @@ -164,11 +164,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/83xx/sbc834x_defconfig b/trunk/arch/powerpc/configs/83xx/sbc834x_defconfig index c359cc2a380e..9245a67da200 100644 --- a/trunk/arch/powerpc/configs/83xx/sbc834x_defconfig +++ b/trunk/arch/powerpc/configs/83xx/sbc834x_defconfig @@ -162,11 +162,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/trunk/arch/powerpc/configs/86xx/gef_sbc610_defconfig deleted file mode 100644 index 312d7afbbe44..000000000000 --- a/trunk/arch/powerpc/configs/86xx/gef_sbc610_defconfig +++ /dev/null @@ -1,1657 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc5 -# Wed Jun 11 12:06:53 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_RELAY=y -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -CONFIG_PPC_86xx=y -# CONFIG_PPC_MPC512x is not set -# CONFIG_PPC_MPC5121 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -# CONFIG_MPC8641_HPCN is not set -# CONFIG_SBC8641D is not set -# CONFIG_MPC8610_HPCD is not set -CONFIG_GEF_SBC610=y -CONFIG_MPC8641=y -# CONFIG_IPIC is not set -CONFIG_MPIC=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_FSL_ULI1575 is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -# CONFIG_SCHED_HRTICK is not set -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -# CONFIG_PREEMPT_RCU is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_IRQ_ALL_CPUS=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_FSL_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIEASPM is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y -CONFIG_PCI_DEBUG=y -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_HAS_RAPIDIO=y -# CONFIG_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IP_VS is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -# CONFIG_NF_CONNTRACK is not set -CONFIG_NETFILTER_XTABLES=m -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -# CONFIG_IP_NF_MATCH_AH is not set -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_ECN=m -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_MH is not set -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -# CONFIG_IP6_NF_TARGET_REJECT is not set -CONFIG_IP6_NF_MANGLE=m -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_RAW=m - -# -# Bridge: Netfilter Configuration -# -# CONFIG_BRIDGE_NF_EBTABLES is not set -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -CONFIG_TIPC=m -# CONFIG_TIPC_ADVANCED is not set -# CONFIG_TIPC_DEBUG is not set -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -# CONFIG_ATM_BR2684_IPFILTER is not set -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m -CONFIG_NET_SCH_PRIO=m -# CONFIG_NET_SCH_RR is not set -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m - -# -# Classification -# -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -# CONFIG_NET_CLS_IND is not set -CONFIG_NET_SCH_FIFO=y - -# -# Network testing -# -CONFIG_NET_PKTGEN=m -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_OF_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -# CONFIG_MTD_CFI_NOSWAP is not set -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -CONFIG_MTD_CFI_LE_BYTE_SWAP=y -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_I2C=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_PMP=y -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_FSL is not set -CONFIG_ATA_SFF=y -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_SCH is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_E1000E_ENABLED is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -# CONFIG_GFAR_NAPI is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -CONFIG_ATM_DRIVERS=y -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E_MAYBE is not set -# CONFIG_ATM_HE is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -# CONFIG_PPP_MPPE is not set -CONFIG_PPPOE=m -CONFIG_PPPOATM=m -# CONFIG_PPPOL2TP is not set -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLHC=m -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_NET_FC is not set -CONFIG_NETCONSOLE=y -# CONFIG_NETCONSOLE_DYNAMIC is not set -CONFIG_NETPOLL=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_TINY_USB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_DS1682=y -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_LM92=y -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_DEVICE_CLASS is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EHCI_FSL is not set -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_MON is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_ATM is not set -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=m -CONFIG_RTC_CLASS=m - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_PPC is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -# CONFIG_SUNRPC_BIND34 is not set -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SAMPLES is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_DEBUGGER=y -# CONFIG_XMON is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -# CONFIG_SECURITY_NETWORK_XFRM is not set -CONFIG_SECURITY_CAPABILITIES=y -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_NULL=m -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=m -CONFIG_CRYPTO_TEST=m - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_WP512=m - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_BLOWFISH=m -# CONFIG_CRYPTO_CAMELLIA is not set -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -CONFIG_CRYPTO_KHAZAD=m -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_LZO is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/ep8248e_defconfig b/trunk/arch/powerpc/configs/ep8248e_defconfig index cd691f770810..ef0c6e800508 100644 --- a/trunk/arch/powerpc/configs/ep8248e_defconfig +++ b/trunk/arch/powerpc/configs/ep8248e_defconfig @@ -150,11 +150,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set CONFIG_PPC_82xx=y diff --git a/trunk/arch/powerpc/configs/mgcoge_defconfig b/trunk/arch/powerpc/configs/mgcoge_defconfig deleted file mode 100644 index cc9eaba8c9c9..000000000000 --- a/trunk/arch/powerpc/configs/mgcoge_defconfig +++ /dev/null @@ -1,900 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc2 -# Thu May 22 08:18:47 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_PPC_MM_SLICES is not set -# CONFIG_SMP is not set -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -# CONFIG_EXPERIMENTAL is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_MODULES is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" -CONFIG_CLASSIC_RCU=y - -# -# Platform support -# -# CONFIG_PPC_MULTIPLATFORM is not set -CONFIG_PPC_82xx=y -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_86xx is not set -# CONFIG_PPC_MPC512x is not set -# CONFIG_PPC_MPC5121 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_MPC8272_ADS is not set -# CONFIG_PQ2FADS is not set -# CONFIG_EP8248E is not set -CONFIG_MGCOGE=y -# CONFIG_PQ2ADS is not set -CONFIG_8260=y -CONFIG_8272=y -# CONFIG_IPIC is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -CONFIG_CPM2=y -CONFIG_PPC_CPM_NEW_BINDING=y -# CONFIG_FSL_ULI1575 is not set -CONFIG_CPM=y - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_FSL_SOC=y -# CONFIG_PCI is not set -# CONFIG_PCI_DOMAINS is not set -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NETFILTER_XTABLES is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -# CONFIG_MTD_BLOCK is not set -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -CONFIG_FIXED_PHY=y -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -CONFIG_FS_ENET=y -CONFIG_FS_ENET_HAS_SCC=y -# CONFIG_FS_ENET_HAS_FCC is not set -# CONFIG_FS_ENET_MDIO_FCC is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -# CONFIG_SERIAL_CPM_SCC1 is not set -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -# CONFIG_SERIAL_CPM_SCC4 is not set -CONFIG_SERIAL_CPM_SMC1=y -CONFIG_SERIAL_CPM_SMC2=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_HFSPLUS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_DETECT_SOFTLOCKUP is not set -# CONFIG_SCHED_DEBUG is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SAMPLES is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUGGER is not set -# CONFIG_KGDB_CONSOLE is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_VIRQ_DEBUG is not set -CONFIG_BDI_SWITCH=y -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_PCBC=y - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_PPC_CLOCK is not set -CONFIG_PPC_LIB_RHEAP=y -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/mgsuvd_defconfig b/trunk/arch/powerpc/configs/mgsuvd_defconfig deleted file mode 100644 index 3cd6ce4be827..000000000000 --- a/trunk/arch/powerpc/configs/mgsuvd_defconfig +++ /dev/null @@ -1,872 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc2 -# Wed May 21 13:30:33 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -# CONFIG_6xx is not set -# CONFIG_PPC_85xx is not set -CONFIG_PPC_8xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_8xx=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -# CONFIG_DEFAULT_UIMAGE is not set -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -# CONFIG_BUG is not set -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -# CONFIG_BASE_FULL is not set -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -# CONFIG_EPOLL is not set -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -# CONFIG_VM_EVENT_COUNTERS is not set -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 -# CONFIG_MODULES is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y - -# -# Platform support -# -# CONFIG_PPC_MPC512x is not set -# CONFIG_PPC_MPC5121 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -CONFIG_CPM1=y -# CONFIG_MPC8XXFADS is not set -# CONFIG_MPC86XADS is not set -# CONFIG_MPC885ADS is not set -# CONFIG_PPC_EP88XC is not set -# CONFIG_PPC_ADDER875 is not set -CONFIG_PPC_MGSUVD=y - -# -# MPC8xx CPM Options -# - -# -# Generic MPC8xx Options -# -CONFIG_8xx_COPYBACK=y -CONFIG_8xx_CPU6=y -CONFIG_8xx_CPU15=y -# CONFIG_NO_UCODE_PATCH is not set -# CONFIG_USB_SOF_UCODE_PATCH is not set -# CONFIG_I2C_SPI_UCODE_PATCH is not set -CONFIG_I2C_SPI_SMC1_UCODE_PATCH=y -CONFIG_UCODE_PATCH=y -# CONFIG_PQ2ADS is not set -# CONFIG_IPIC is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -CONFIG_PPC_CPM_NEW_BINDING=y -# CONFIG_FSL_ULI1575 is not set -CONFIG_CPM=y - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -# CONFIG_SCHED_HRTICK is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_MATH_EMULATION=y -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_FSL_SOC=y -# CONFIG_PCI is not set -# CONFIG_PCI_DOMAINS is not set -# CONFIG_PCI_SYSCALL is not set -# CONFIG_PCI_QSPAN is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_CONSISTENT_START=0xfd000000 -CONFIG_CONSISTENT_SIZE=0x00200000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -CONFIG_FIXED_PHY=y -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -CONFIG_FS_ENET=y -CONFIG_FS_ENET_HAS_SCC=y -# CONFIG_FS_ENET_HAS_FEC is not set -# CONFIG_FS_ENET_MDIO_FEC is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -# CONFIG_SERIAL_CPM_SCC1 is not set -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -# CONFIG_SERIAL_CPM_SCC4 is not set -CONFIG_SERIAL_CPM_SMC1=y -# CONFIG_SERIAL_CPM_SMC2 is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_EDAC is not set -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_SAMPLES is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_VIRQ_DEBUG is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y -# CONFIG_PPC_CLOCK is not set -CONFIG_PPC_LIB_RHEAP=y -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/mpc8272_ads_defconfig b/trunk/arch/powerpc/configs/mpc8272_ads_defconfig index ff6f7c475f47..7c435c84c875 100644 --- a/trunk/arch/powerpc/configs/mpc8272_ads_defconfig +++ b/trunk/arch/powerpc/configs/mpc8272_ads_defconfig @@ -151,11 +151,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set CONFIG_PPC_82xx=y diff --git a/trunk/arch/powerpc/configs/mpc83xx_defconfig b/trunk/arch/powerpc/configs/mpc83xx_defconfig index 991c9bda12a9..916e3df7cc45 100644 --- a/trunk/arch/powerpc/configs/mpc83xx_defconfig +++ b/trunk/arch/powerpc/configs/mpc83xx_defconfig @@ -166,11 +166,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/trunk/arch/powerpc/configs/mpc8610_hpcd_defconfig similarity index 99% rename from trunk/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig rename to trunk/arch/powerpc/configs/mpc8610_hpcd_defconfig index c98c6ee44492..1a9990731eb0 100644 --- a/trunk/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig +++ b/trunk/arch/powerpc/configs/mpc8610_hpcd_defconfig @@ -165,11 +165,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/trunk/arch/powerpc/configs/mpc8641_hpcn_defconfig similarity index 99% rename from trunk/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig rename to trunk/arch/powerpc/configs/mpc8641_hpcn_defconfig index 444ddf98436d..ea09be31b6ea 100644 --- a/trunk/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig +++ b/trunk/arch/powerpc/configs/mpc8641_hpcn_defconfig @@ -167,11 +167,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/configs/mpc86xx_defconfig b/trunk/arch/powerpc/configs/mpc86xx_defconfig deleted file mode 100644 index 9d4be820cf1f..000000000000 --- a/trunk/arch/powerpc/configs/mpc86xx_defconfig +++ /dev/null @@ -1,1646 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc5 -# Tue Sep 23 23:28:38 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -CONFIG_AUDIT=y -# CONFIG_AUDITSYSCALL is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_CLK is not set -CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y -# CONFIG_MPC8xxx_GPIO is not set - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_MPC5121_ADS is not set -# CONFIG_MPC5121_GENERIC is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PQ2ADS is not set -# CONFIG_PPC_83xx is not set -CONFIG_PPC_86xx=y -CONFIG_MPC8641_HPCN=y -CONFIG_SBC8641D=y -CONFIG_MPC8610_HPCD=y -CONFIG_GEF_SBC610=y -CONFIG_MPC8641=y -CONFIG_MPC8610=y -# CONFIG_IPIC is not set -CONFIG_MPIC=y -# CONFIG_MPIC_WEIRD is not set -CONFIG_PPC_I8259=y -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_TAU is not set -CONFIG_FSL_ULI1575=y - -# -# Kernel options -# -CONFIG_HIGHMEM=y -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_SCHED_HRTICK=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -# CONFIG_KEXEC is not set -# CONFIG_IRQ_ALL_CPUS is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -CONFIG_EXTRA_TARGETS="" -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_FSL_PCI=y -CONFIG_PPC_PCI_CHOICE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -# CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_HAS_RAPIDIO=y -# CONFIG_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE=y -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_ARPD=y -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -CONFIG_IPV6_NDISC_NODETYPE=y -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_I2C=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=y -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -CONFIG_SCSI_LOGGING=y -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_PMP=y -CONFIG_SATA_AHCI=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_FSL is not set -CONFIG_ATA_SFF=y -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -CONFIG_PATA_ALI=y -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_SCH is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -CONFIG_VITESSE_PHY=y -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -# CONFIG_MV643XX_ETH is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -CONFIG_NETDEV_10000=y -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGBE is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_NIU is not set -# CONFIG_MLX4_CORE is not set -# CONFIG_TEHUTI is not set -# CONFIG_BNX2X is not set -# CONFIG_SFC is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_XILINX_XPS_PS2 is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -CONFIG_NVRAM=y -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -# CONFIG_I2C_CHARDEV is not set -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -CONFIG_I2C_MPC=y -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_AT24 is not set -CONFIG_SENSORS_EEPROM=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -# CONFIG_GPIOLIB is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -CONFIG_DVB_CORE=m -CONFIG_VIDEO_MEDIA=m - -# -# Multimedia drivers -# -# CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=m -# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_DVB_CAPTURE_DRIVERS=y - -# -# Supported SAA7146 based PCI Adapters -# -# CONFIG_TTPCI_EEPROM is not set -# CONFIG_DVB_BUDGET_CORE is not set - -# -# Supported USB Adapters -# -# CONFIG_DVB_USB is not set -# CONFIG_DVB_TTUSB_BUDGET is not set -# CONFIG_DVB_TTUSB_DEC is not set -# CONFIG_DVB_CINERGYT2 is not set -# CONFIG_DVB_SIANO_SMS1XXX is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -# CONFIG_DVB_B2C2_FLEXCOP is not set - -# -# Supported BT878 Adapters -# - -# -# Supported Pluto2 Adapters -# -# CONFIG_DVB_PLUTO2 is not set - -# -# Supported DVB Frontends -# - -# -# Customise DVB Frontends -# -# CONFIG_DVB_FE_CUSTOMISE is not set - -# -# DVB-S (satellite) frontends -# -# CONFIG_DVB_CX24110 is not set -# CONFIG_DVB_CX24123 is not set -# CONFIG_DVB_MT312 is not set -# CONFIG_DVB_S5H1420 is not set -# CONFIG_DVB_STV0299 is not set -# CONFIG_DVB_TDA8083 is not set -# CONFIG_DVB_TDA10086 is not set -# CONFIG_DVB_VES1X93 is not set -# CONFIG_DVB_TUNER_ITD1000 is not set -# CONFIG_DVB_TDA826X is not set -# CONFIG_DVB_TUA6100 is not set - -# -# DVB-T (terrestrial) frontends -# -# CONFIG_DVB_SP8870 is not set -# CONFIG_DVB_SP887X is not set -# CONFIG_DVB_CX22700 is not set -# CONFIG_DVB_CX22702 is not set -# CONFIG_DVB_DRX397XD is not set -# CONFIG_DVB_L64781 is not set -# CONFIG_DVB_TDA1004X is not set -# CONFIG_DVB_NXT6000 is not set -# CONFIG_DVB_MT352 is not set -# CONFIG_DVB_ZL10353 is not set -# CONFIG_DVB_DIB3000MB is not set -# CONFIG_DVB_DIB3000MC is not set -# CONFIG_DVB_DIB7000M is not set -# CONFIG_DVB_DIB7000P is not set -# CONFIG_DVB_TDA10048 is not set - -# -# DVB-C (cable) frontends -# -# CONFIG_DVB_VES1820 is not set -# CONFIG_DVB_TDA10021 is not set -# CONFIG_DVB_TDA10023 is not set -# CONFIG_DVB_STV0297 is not set - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -# CONFIG_DVB_NXT200X is not set -# CONFIG_DVB_OR51211 is not set -# CONFIG_DVB_OR51132 is not set -# CONFIG_DVB_BCM3510 is not set -# CONFIG_DVB_LGDT330X is not set -# CONFIG_DVB_S5H1409 is not set -# CONFIG_DVB_AU8522 is not set -# CONFIG_DVB_S5H1411 is not set - -# -# Digital terrestrial only tuners/PLL -# -# CONFIG_DVB_PLL is not set -# CONFIG_DVB_TUNER_DIB0070 is not set - -# -# SEC control devices for DVB-S -# -# CONFIG_DVB_LNBP21 is not set -# CONFIG_DVB_ISL6405 is not set -# CONFIG_DVB_ISL6421 is not set -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -# CONFIG_SND_SEQUENCER is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -CONFIG_SND_VMASTER=y -CONFIG_SND_AC97_CODEC=y -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_AC97_POWER_SAVE is not set -CONFIG_SND_PCI=y -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ALS300 is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AW2 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_OXYGEN is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS5530 is not set -# CONFIG_SND_DARLA20 is not set -# CONFIG_SND_GINA20 is not set -# CONFIG_SND_LAYLA20 is not set -# CONFIG_SND_DARLA24 is not set -# CONFIG_SND_GINA24 is not set -# CONFIG_SND_LAYLA24 is not set -# CONFIG_SND_MONA is not set -# CONFIG_SND_MIA is not set -# CONFIG_SND_ECHO3G is not set -# CONFIG_SND_INDIGO is not set -# CONFIG_SND_INDIGOIO is not set -# CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_HIFIER is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -CONFIG_SND_INTEL8X0=y -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_RIPTIDE is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VIRTUOSO is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_YMFPCI is not set -CONFIG_SND_PPC=y -CONFIG_SND_USB=y -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_SOC is not set -# CONFIG_SOUND_PRIME is not set -CONFIG_AC97_BUS=y -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=y - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EHCI_FSL is not set -CONFIG_USB_EHCI_HCD_PPC_OF=y -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_OHCI_HCD_PCI=y -CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y -CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_SIERRA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -CONFIG_RTC_DRV_CMOS=y -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_PPC is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_CRAMFS=y -CONFIG_VXFS_FS=m -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -# CONFIG_ROMFS_FS is not set -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_V4 is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=m -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=m -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_XMON is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=m -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_CRYPTO_DEV_TALITOS is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/pq2fads_defconfig b/trunk/arch/powerpc/configs/pq2fads_defconfig index 7e17862c38b8..b390b7476649 100644 --- a/trunk/arch/powerpc/configs/pq2fads_defconfig +++ b/trunk/arch/powerpc/configs/pq2fads_defconfig @@ -152,11 +152,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set CONFIG_PPC_82xx=y diff --git a/trunk/arch/powerpc/configs/86xx/sbc8641d_defconfig b/trunk/arch/powerpc/configs/sbc8641d_defconfig similarity index 99% rename from trunk/arch/powerpc/configs/86xx/sbc8641d_defconfig rename to trunk/arch/powerpc/configs/sbc8641d_defconfig index d900f8f376cf..f545421f9857 100644 --- a/trunk/arch/powerpc/configs/86xx/sbc8641d_defconfig +++ b/trunk/arch/powerpc/configs/sbc8641d_defconfig @@ -166,11 +166,11 @@ CONFIG_CLASSIC_RCU=y # CONFIG_PPC_MULTIPLATFORM=y CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set +CONFIG_PPC_CHRP=y # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set # CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_PMAC=y # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_82xx is not set diff --git a/trunk/arch/powerpc/include/asm/a.out.h b/trunk/arch/powerpc/include/asm/a.out.h new file mode 100644 index 000000000000..89cead6b176e --- /dev/null +++ b/trunk/arch/powerpc/include/asm/a.out.h @@ -0,0 +1,20 @@ +#ifndef _ASM_POWERPC_A_OUT_H +#define _ASM_POWERPC_A_OUT_H + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#endif /* _ASM_POWERPC_A_OUT_H */ diff --git a/trunk/arch/powerpc/include/asm/cputable.h b/trunk/arch/powerpc/include/asm/cputable.h index 1e94b07a020e..ef8a248dfd55 100644 --- a/trunk/arch/powerpc/include/asm/cputable.h +++ b/trunk/arch/powerpc/include/asm/cputable.h @@ -62,7 +62,6 @@ enum powerpc_pmc_type { PPC_PMC_DEFAULT = 0, PPC_PMC_IBM = 1, PPC_PMC_PA6T = 2, - PPC_PMC_G4 = 3, }; struct pt_regs; @@ -193,7 +192,6 @@ extern const char *powerpc_base_platform; #define CPU_FTR_NO_SLBIE_B LONG_ASM_CONST(0x0008000000000000) #define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000) #define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000) -#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000) #ifndef __ASSEMBLY__ @@ -389,11 +387,10 @@ extern const char *powerpc_base_platform; CPU_FTR_MMCRA | CPU_FTR_CTRL) #define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ - CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ) + CPU_FTR_MMCRA) #define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ - CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \ - CPU_FTR_CP_USE_DCBTZ) + CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA) #define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_MMCRA | CPU_FTR_SMT | \ @@ -414,8 +411,7 @@ extern const char *powerpc_base_platform; #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ - CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \ - CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ) + CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG) #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \ diff --git a/trunk/arch/powerpc/include/asm/dcr-regs.h b/trunk/arch/powerpc/include/asm/dcr-regs.h index 828e3aa1f2fc..f15296cf3598 100644 --- a/trunk/arch/powerpc/include/asm/dcr-regs.h +++ b/trunk/arch/powerpc/include/asm/dcr-regs.h @@ -68,13 +68,6 @@ #define SDR0_UART3 0x0123 #define SDR0_CUST0 0x4000 -/* SDR for 405EZ */ -#define DCRN_SDR_ICINTSTAT 0x4510 -#define ICINTSTAT_ICRX 0x80000000 -#define ICINTSTAT_ICTX0 0x40000000 -#define ICINTSTAT_ICTX1 0x20000000 -#define ICINTSTAT_ICTX 0x60000000 - /* SDRs (460EX/460GT) */ #define SDR0_ETH_CFG 0x4103 #define SDR0_ETH_CFG_ECS 0x00000100 /* EMAC int clk source */ diff --git a/trunk/arch/powerpc/include/asm/device.h b/trunk/arch/powerpc/include/asm/device.h index dfd504caccc1..228ab2a315b9 100644 --- a/trunk/arch/powerpc/include/asm/device.h +++ b/trunk/arch/powerpc/include/asm/device.h @@ -16,6 +16,9 @@ struct dev_archdata { /* DMA operations on that device */ struct dma_mapping_ops *dma_ops; void *dma_data; + + /* NUMA node if applicable */ + int numa_node; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h index fddb229bd74f..c7ca45f97dd2 100644 --- a/trunk/arch/powerpc/include/asm/dma-mapping.h +++ b/trunk/arch/powerpc/include/asm/dma-mapping.h @@ -44,6 +44,8 @@ extern void __dma_sync_page(struct page *page, unsigned long offset, #endif /* ! CONFIG_NOT_COHERENT_CACHE */ +#ifdef CONFIG_PPC64 + static inline unsigned long device_to_mask(struct device *dev) { if (dev->dma_mask && *dev->dma_mask) @@ -74,24 +76,8 @@ struct dma_mapping_ops { struct dma_attrs *attrs); int (*dma_supported)(struct device *dev, u64 mask); int (*set_dma_mask)(struct device *dev, u64 dma_mask); - dma_addr_t (*map_page)(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs); - void (*unmap_page)(struct device *dev, - dma_addr_t dma_address, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs); }; -/* - * Available generic sets of operations - */ -#ifdef CONFIG_PPC64 -extern struct dma_mapping_ops dma_iommu_ops; -#endif -extern struct dma_mapping_ops dma_direct_ops; - static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { /* We don't handle the NULL dev case for ISA for now. We could @@ -99,19 +85,8 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) * only ISA DMA device we support is the floppy and we have a hack * in the floppy driver directly to get a device for us. */ - - if (unlikely(dev == NULL) || dev->archdata.dma_ops == NULL) { -#ifdef CONFIG_PPC64 + if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL)) return NULL; -#else - /* Use default on 32-bit if dma_ops is not set up */ - /* TODO: Long term, we should fix drivers so that dev and - * archdata dma_ops are set up for all buses. - */ - return &dma_direct_ops; -#endif - } - return dev->archdata.dma_ops; } @@ -148,12 +123,6 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -/* - * TODO: map_/unmap_single will ideally go away, to be completely - * replaced by map/unmap_page. Until then, we allow dma_ops to have - * one or the other, or both by checking to see if the specific - * function requested exists; and if not, falling back on the other set. - */ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *cpu_addr, size_t size, @@ -163,14 +132,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->map_single) - return dma_ops->map_single(dev, cpu_addr, size, direction, - attrs); - - return dma_ops->map_page(dev, virt_to_page(cpu_addr), - (unsigned long)cpu_addr % PAGE_SIZE, size, - direction, attrs); + return dma_ops->map_single(dev, cpu_addr, size, direction, attrs); } static inline void dma_unmap_single_attrs(struct device *dev, @@ -182,13 +144,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->unmap_single) { - dma_ops->unmap_single(dev, dma_addr, size, direction, attrs); - return; - } - - dma_ops->unmap_page(dev, dma_addr, size, direction, attrs); + dma_ops->unmap_single(dev, dma_addr, size, direction, attrs); } static inline dma_addr_t dma_map_page_attrs(struct device *dev, @@ -200,13 +156,8 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->map_page) - return dma_ops->map_page(dev, page, offset, size, direction, - attrs); - return dma_ops->map_single(dev, page_address(page) + offset, size, - direction, attrs); + direction, attrs); } static inline void dma_unmap_page_attrs(struct device *dev, @@ -218,12 +169,6 @@ static inline void dma_unmap_page_attrs(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->unmap_page) { - dma_ops->unmap_page(dev, dma_address, size, direction, attrs); - return; - } - dma_ops->unmap_single(dev, dma_address, size, direction, attrs); } @@ -308,6 +253,126 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL); } +/* + * Available generic sets of operations + */ +extern struct dma_mapping_ops dma_iommu_ops; +extern struct dma_mapping_ops dma_direct_ops; + +#else /* CONFIG_PPC64 */ + +#define dma_supported(dev, mask) (1) + +static inline int dma_set_mask(struct device *dev, u64 dma_mask) +{ + if (!dev->dma_mask || !dma_supported(dev, mask)) + return -EIO; + + *dev->dma_mask = dma_mask; + + return 0; +} + +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, + gfp_t gfp) +{ +#ifdef CONFIG_NOT_COHERENT_CACHE + return __dma_alloc_coherent(size, dma_handle, gfp); +#else + void *ret; + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (dev == NULL || dev->coherent_dma_mask < 0xffffffff) + gfp |= GFP_DMA; + + ret = (void *)__get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + + return ret; +#endif +} + +static inline void +dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ +#ifdef CONFIG_NOT_COHERENT_CACHE + __dma_free_coherent(size, vaddr); +#else + free_pages((unsigned long)vaddr, get_order(size)); +#endif +} + +static inline dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + + __dma_sync(ptr, size, direction); + + return virt_to_bus(ptr); +} + +static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, + enum dma_data_direction direction) +{ + /* We do nothing. */ +} + +static inline dma_addr_t +dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + + __dma_sync_page(page, offset, size, direction); + + return page_to_bus(page) + offset; +} + +static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, + size_t size, + enum dma_data_direction direction) +{ + /* We do nothing. */ +} + +static inline int +dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents, + enum dma_data_direction direction) +{ + struct scatterlist *sg; + int i; + + BUG_ON(direction == DMA_NONE); + + for_each_sg(sgl, sg, nents, i) { + BUG_ON(!sg_page(sg)); + __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); + sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset; + } + + return nents; +} + +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nhwentries, + enum dma_data_direction direction) +{ + /* We don't do anything here. */ +} + +#endif /* CONFIG_PPC64 */ + static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) diff --git a/trunk/arch/powerpc/include/asm/elf.h b/trunk/arch/powerpc/include/asm/elf.h index d812929390e4..64c6ee22eefd 100644 --- a/trunk/arch/powerpc/include/asm/elf.h +++ b/trunk/arch/powerpc/include/asm/elf.h @@ -232,7 +232,7 @@ typedef elf_vrregset_t elf_fpxregset_t; #endif /* __powerpc64__ */ #ifdef __powerpc64__ -# define SET_PERSONALITY(ex) \ +# define SET_PERSONALITY(ex, ibcs2) \ do { \ unsigned long new_flags = 0; \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ @@ -256,7 +256,7 @@ do { \ # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \ (exec_stk != EXSTACK_DISABLE_X) : 0) #else -# define SET_PERSONALITY(ex) set_personality(PER_LINUX) +# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) #endif /* __powerpc64__ */ extern int dcache_bsize; diff --git a/trunk/arch/powerpc/include/asm/exception.h b/trunk/arch/powerpc/include/asm/exception.h index d3d4534e3c74..329148b5acc6 100644 --- a/trunk/arch/powerpc/include/asm/exception.h +++ b/trunk/arch/powerpc/include/asm/exception.h @@ -53,8 +53,14 @@ * low halfword of the address, but for Kdump we need the whole low * word. */ +#ifdef CONFIG_CRASH_DUMP #define LOAD_HANDLER(reg, label) \ - addi reg,reg,(label)-_stext; /* virt addr of handler ... */ + oris reg,reg,(label)@h; /* virt addr of handler ... */ \ + ori reg,reg,(label)@l; /* .. and the rest */ +#else +#define LOAD_HANDLER(reg, label) \ + ori reg,reg,(label)@l; /* virt addr of handler ... */ +#endif #define EXCEPTION_PROLOG_1(area) \ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ @@ -66,12 +72,37 @@ std r9,area+EX_R13(r13); \ mfcr r9 +/* + * Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode. + * The firmware calls the registered system_reset_fwnmi and + * machine_check_fwnmi handlers in 32bit mode if the cpu happens to run + * a 32bit application at the time of the event. + * This firmware bug is present on POWER4 and JS20. + */ +#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label) \ + EXCEPTION_PROLOG_1(area); \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ + /* force 64bit mode */ \ + li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \ + rldimi r10,r11,61,0; /* insert into top 3 bits */ \ + /* done 64bit mode */ \ + mfspr r11,SPRN_SRR0; /* save SRR0 */ \ + LOAD_HANDLER(r12,label) \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ + mtspr SPRN_SRR0,r12; \ + mfspr r12,SPRN_SRR1; /* and SRR1 */ \ + mtspr SPRN_SRR1,r10; \ + rfid; \ + b . /* prevent speculative execution */ + #define EXCEPTION_PROLOG_PSERIES(area, label) \ EXCEPTION_PROLOG_1(area); \ - ld r12,PACAKBASE(r13); /* get high part of &label */ \ - ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ mfspr r11,SPRN_SRR0; /* save SRR0 */ \ LOAD_HANDLER(r12,label) \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ mtspr SPRN_SRR0,r12; \ mfspr r12,SPRN_SRR1; /* and SRR1 */ \ mtspr SPRN_SRR1,r10; \ @@ -179,10 +210,11 @@ label##_pSeries: \ std r10,PACA_EXGEN+EX_R13(r13); \ std r11,PACA_EXGEN+EX_R11(r13); \ std r12,PACA_EXGEN+EX_R12(r13); \ - ld r12,PACAKBASE(r13); /* get high part of &label */ \ - ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ mfspr r11,SPRN_SRR0; /* save SRR0 */ \ LOAD_HANDLER(r12,label##_common) \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ mtspr SPRN_SRR0,r12; \ mfspr r12,SPRN_SRR1; /* and SRR1 */ \ mtspr SPRN_SRR1,r10; \ diff --git a/trunk/arch/powerpc/include/asm/fsl_lbc.h b/trunk/arch/powerpc/include/asm/fsl_lbc.h index 63a4f779f531..303f5484c050 100644 --- a/trunk/arch/powerpc/include/asm/fsl_lbc.h +++ b/trunk/arch/powerpc/include/asm/fsl_lbc.h @@ -23,9 +23,9 @@ #ifndef __ASM_FSL_LBC_H #define __ASM_FSL_LBC_H -#include #include -#include +#include +#include struct fsl_lbc_bank { __be32 br; /**< Base Register */ @@ -227,6 +227,9 @@ struct fsl_lbc_regs { u8 res8[0xF00]; }; +extern struct fsl_lbc_regs __iomem *fsl_lbc_regs; +extern spinlock_t fsl_lbc_lock; + /* * FSL UPM routines */ @@ -265,7 +268,44 @@ static inline void fsl_upm_end_pattern(struct fsl_upm *upm) cpu_relax(); } -extern int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, - u32 mar); +/** + * fsl_upm_run_pattern - actually run an UPM pattern + * @upm: pointer to the fsl_upm structure obtained via fsl_upm_find + * @io_base: remapped pointer to where memory access should happen + * @mar: MAR register content during pattern execution + * + * This function triggers dummy write to the memory specified by the io_base, + * thus UPM pattern actually executed. Note that mar usage depends on the + * pre-programmed AMX bits in the UPM RAM. + */ +static inline int fsl_upm_run_pattern(struct fsl_upm *upm, + void __iomem *io_base, u32 mar) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&fsl_lbc_lock, flags); + + out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width)); + + switch (upm->width) { + case 8: + out_8(io_base, 0x0); + break; + case 16: + out_be16(io_base, 0x0); + break; + case 32: + out_be32(io_base, 0x0); + break; + default: + ret = -EINVAL; + break; + } + + spin_unlock_irqrestore(&fsl_lbc_lock, flags); + + return ret; +} #endif /* __ASM_FSL_LBC_H */ diff --git a/trunk/arch/powerpc/include/asm/highmem.h b/trunk/arch/powerpc/include/asm/highmem.h index 91c589520c0a..5d99b6489d56 100644 --- a/trunk/arch/powerpc/include/asm/highmem.h +++ b/trunk/arch/powerpc/include/asm/highmem.h @@ -84,7 +84,7 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(*(kmap_pte-idx))); #endif - __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); + set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); flush_tlb_page(NULL, vaddr); return (void*) vaddr; diff --git a/trunk/arch/powerpc/include/asm/io.h b/trunk/arch/powerpc/include/asm/io.h index 08266d2728b3..77c7fa025e65 100644 --- a/trunk/arch/powerpc/include/asm/io.h +++ b/trunk/arch/powerpc/include/asm/io.h @@ -711,7 +711,7 @@ static inline void * phys_to_virt(unsigned long address) /* * Change "struct page" to physical address. */ -#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) /* We do NOT want virtual merging, it would put too much pressure on * our iommu allocator. Instead, we want drivers to be smart enough diff --git a/trunk/arch/powerpc/include/asm/irq.h b/trunk/arch/powerpc/include/asm/irq.h index 0a5137676e1b..a372f76836c2 100644 --- a/trunk/arch/powerpc/include/asm/irq.h +++ b/trunk/arch/powerpc/include/asm/irq.h @@ -236,27 +236,15 @@ extern unsigned int irq_find_mapping(struct irq_host *host, extern unsigned int irq_create_direct_mapping(struct irq_host *host); /** - * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping. - * @host: host owning this hardware interrupt - * @virq: linux irq number - * @hwirq: hardware irq number in that host space - * - * This is for use by irq controllers that use a radix tree reverse - * mapping for fast lookup. - */ -extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq); - -/** - * irq_radix_revmap_lookup - Find a linux virq from a hw irq number. + * irq_radix_revmap - Find a linux virq from a hw irq number. * @host: host owning this hardware interrupt * @hwirq: hardware irq number in that host space * * This is a fast path, for use by irq controller code that uses radix tree * revmaps */ -extern unsigned int irq_radix_revmap_lookup(struct irq_host *host, - irq_hw_number_t hwirq); +extern unsigned int irq_radix_revmap(struct irq_host *host, + irq_hw_number_t hwirq); /** * irq_linear_revmap - Find a linux virq from a hw irq number. diff --git a/trunk/arch/powerpc/include/asm/machdep.h b/trunk/arch/powerpc/include/asm/machdep.h index 2740c44ff717..893aafd87fde 100644 --- a/trunk/arch/powerpc/include/asm/machdep.h +++ b/trunk/arch/powerpc/include/asm/machdep.h @@ -88,6 +88,8 @@ struct machdep_calls { unsigned long (*tce_get)(struct iommu_table *tbl, long index); void (*tce_flush)(struct iommu_table *tbl); + void (*pci_dma_dev_setup)(struct pci_dev *dev); + void (*pci_dma_bus_setup)(struct pci_bus *bus); void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, unsigned long flags); @@ -99,9 +101,6 @@ struct machdep_calls { #endif #endif /* CONFIG_PPC64 */ - void (*pci_dma_dev_setup)(struct pci_dev *dev); - void (*pci_dma_bus_setup)(struct pci_bus *bus); - int (*probe)(void); void (*setup_arch)(void); /* Optional, may be NULL */ void (*init_early)(void); diff --git a/trunk/arch/powerpc/include/asm/mman.h b/trunk/arch/powerpc/include/asm/mman.h index e7b99bac9f48..9209f755763e 100644 --- a/trunk/arch/powerpc/include/asm/mman.h +++ b/trunk/arch/powerpc/include/asm/mman.h @@ -44,7 +44,7 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot) static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) { - return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0); + return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : 0; } #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) diff --git a/trunk/arch/powerpc/include/asm/mmu-hash64.h b/trunk/arch/powerpc/include/asm/mmu-hash64.h index 5a441742ffba..c2df53c5ceb9 100644 --- a/trunk/arch/powerpc/include/asm/mmu-hash64.h +++ b/trunk/arch/powerpc/include/asm/mmu-hash64.h @@ -437,7 +437,7 @@ typedef struct { }) #endif /* 1 */ -/* This is only valid for addresses >= PAGE_OFFSET */ +/* This is only valid for addresses >= KERNELBASE */ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) { if (ssize == MMU_SEGSIZE_256M) diff --git a/trunk/arch/powerpc/include/asm/mpic.h b/trunk/arch/powerpc/include/asm/mpic.h index 34d9ac433ace..fe566a348a86 100644 --- a/trunk/arch/powerpc/include/asm/mpic.h +++ b/trunk/arch/powerpc/include/asm/mpic.h @@ -5,7 +5,6 @@ #include #include #include -#include /* * Global registers @@ -302,7 +301,8 @@ struct mpic #endif #ifdef CONFIG_PCI_MSI - struct msi_bitmap msi_bitmap; + spinlock_t bitmap_lock; + unsigned long *hwirq_bitmap; #endif #ifdef CONFIG_MPIC_BROKEN_REGREAD diff --git a/trunk/arch/powerpc/include/asm/msi_bitmap.h b/trunk/arch/powerpc/include/asm/msi_bitmap.h deleted file mode 100644 index 97ac3f46ae0d..000000000000 --- a/trunk/arch/powerpc/include/asm/msi_bitmap.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _POWERPC_SYSDEV_MSI_BITMAP_H -#define _POWERPC_SYSDEV_MSI_BITMAP_H - -/* - * Copyright 2008, Michael Ellerman, IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the - * License. - * - */ - -#include -#include - -struct msi_bitmap { - struct device_node *of_node; - unsigned long *bitmap; - spinlock_t lock; - unsigned int irq_count; -}; - -int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num); -void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset, - unsigned int num); -void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq); - -int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp); - -int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count, - struct device_node *of_node); -void msi_bitmap_free(struct msi_bitmap *bmp); - -#endif /* _POWERPC_SYSDEV_MSI_BITMAP_H */ diff --git a/trunk/arch/powerpc/include/asm/of_device.h b/trunk/arch/powerpc/include/asm/of_device.h index a64debf177dc..3c123990ca2e 100644 --- a/trunk/arch/powerpc/include/asm/of_device.h +++ b/trunk/arch/powerpc/include/asm/of_device.h @@ -24,5 +24,8 @@ extern struct of_device *of_device_alloc(struct device_node *np, extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +/* This is just here during the transition */ +#include + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/trunk/arch/powerpc/include/asm/of_platform.h b/trunk/arch/powerpc/include/asm/of_platform.h index 53b46507ffde..18659ef72139 100644 --- a/trunk/arch/powerpc/include/asm/of_platform.h +++ b/trunk/arch/powerpc/include/asm/of_platform.h @@ -11,6 +11,9 @@ * */ +/* This is just here during the transition */ +#include + /* Platform drivers register/unregister */ static inline int of_register_platform_driver(struct of_platform_driver *drv) { diff --git a/trunk/arch/powerpc/include/asm/paca.h b/trunk/arch/powerpc/include/asm/paca.h index 082b3aedf145..6493a395508b 100644 --- a/trunk/arch/powerpc/include/asm/paca.h +++ b/trunk/arch/powerpc/include/asm/paca.h @@ -62,8 +62,6 @@ struct paca_struct { u16 paca_index; /* Logical processor number */ u64 kernel_toc; /* Kernel TOC address */ - u64 kernelbase; /* Base address of kernel */ - u64 kernel_msr; /* MSR while running in kernel */ u64 stab_real; /* Absolute address of segment table */ u64 stab_addr; /* Virtual address of segment table */ void *emergency_sp; /* pointer to emergency stack */ diff --git a/trunk/arch/powerpc/include/asm/page.h b/trunk/arch/powerpc/include/asm/page.h index 64e144505f65..e088545cb3f5 100644 --- a/trunk/arch/powerpc/include/asm/page.h +++ b/trunk/arch/powerpc/include/asm/page.h @@ -71,21 +71,15 @@ #define PAGE_OFFSET ASM_CONST(CONFIG_PAGE_OFFSET) #define LOAD_OFFSET ASM_CONST((CONFIG_KERNEL_START-CONFIG_PHYSICAL_START)) -#if defined(CONFIG_RELOCATABLE) +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_FLATMEM) #ifndef __ASSEMBLY__ extern phys_addr_t memstart_addr; extern phys_addr_t kernstart_addr; #endif #define PHYSICAL_START kernstart_addr -#else -#define PHYSICAL_START ASM_CONST(CONFIG_PHYSICAL_START) -#endif - -#ifdef CONFIG_PPC64 -#define MEMORY_START 0UL -#elif defined(CONFIG_RELOCATABLE) #define MEMORY_START memstart_addr #else +#define PHYSICAL_START ASM_CONST(CONFIG_PHYSICAL_START) #define MEMORY_START (PHYSICAL_START + PAGE_OFFSET - KERNELBASE) #endif @@ -98,8 +92,8 @@ extern phys_addr_t kernstart_addr; #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START)) -#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START) +#define __va(x) ((void *)((unsigned long)(x) - PHYSICAL_START + KERNELBASE)) +#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE) /* * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI, diff --git a/trunk/arch/powerpc/include/asm/page_32.h b/trunk/arch/powerpc/include/asm/page_32.h index d77072a32cc6..ebfae530a379 100644 --- a/trunk/arch/powerpc/include/asm/page_32.h +++ b/trunk/arch/powerpc/include/asm/page_32.h @@ -13,16 +13,10 @@ #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES #endif -#ifdef CONFIG_PTE_64BIT -#define PTE_FLAGS_OFFSET 4 /* offset of PTE flags, in bytes */ -#else -#define PTE_FLAGS_OFFSET 0 -#endif - #ifndef __ASSEMBLY__ /* * The basic type of a PTE - 64 bits for those CPUs with > 32 bit - * physical addressing. + * physical addressing. For now this just the IBM PPC440. */ #ifdef CONFIG_PTE_64BIT typedef unsigned long long pte_basic_t; diff --git a/trunk/arch/powerpc/include/asm/pci.h b/trunk/arch/powerpc/include/asm/pci.h index 0e52c7828ea4..a05a942b1c25 100644 --- a/trunk/arch/powerpc/include/asm/pci.h +++ b/trunk/arch/powerpc/include/asm/pci.h @@ -60,14 +60,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } -#ifdef CONFIG_PCI -extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops); -extern struct dma_mapping_ops *get_pci_dma_ops(void); -#else /* CONFIG_PCI */ -#define set_pci_dma_ops(d) -#define get_pci_dma_ops() NULL -#endif - #ifdef CONFIG_PPC64 /* @@ -78,6 +70,9 @@ extern struct dma_mapping_ops *get_pci_dma_ops(void); #define PCI_DISABLE_MWI #ifdef CONFIG_PCI +extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops); +extern struct dma_mapping_ops *get_pci_dma_ops(void); + static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -94,6 +89,9 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_MULTIPLE; *strategy_parameter = cacheline_size; } +#else /* CONFIG_PCI */ +#define set_pci_dma_ops(d) +#define get_pci_dma_ops() NULL #endif #else /* 32-bit */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h index 6ab7c67cb5ab..6fe39e327047 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h @@ -261,7 +261,6 @@ extern int icache_44x_need_flush; #define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */ #define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ #define _PAGE_DIRTY 0x00000010 /* S: Page dirty */ -#define _PAGE_SPECIAL 0x00000020 /* S: Special page */ #define _PAGE_USER 0x00000040 /* S: User page */ #define _PAGE_ENDIAN 0x00000080 /* H: E bit */ #define _PAGE_GUARDED 0x00000100 /* H: G bit */ @@ -277,7 +276,6 @@ extern int icache_44x_need_flush; /* ERPN in a PTE never gets cleared, ignore it */ #define _PTE_NONE_MASK 0xffffffff00000000ULL -#define __HAVE_ARCH_PTE_SPECIAL #elif defined(CONFIG_FSL_BOOKE) /* @@ -307,7 +305,6 @@ extern int icache_44x_need_flush; #define _PAGE_COHERENT 0x00100 /* H: M bit */ #define _PAGE_NO_CACHE 0x00200 /* H: I bit */ #define _PAGE_WRITETHRU 0x00400 /* H: W bit */ -#define _PAGE_SPECIAL 0x00800 /* S: Special page */ #ifdef CONFIG_PTE_64BIT /* ERPN in a PTE never gets cleared, ignore it */ @@ -318,8 +315,6 @@ extern int icache_44x_need_flush; #define _PMD_PRESENT_MASK (PAGE_MASK) #define _PMD_BAD (~PAGE_MASK) -#define __HAVE_ARCH_PTE_SPECIAL - #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ #define _PAGE_PRESENT 0x0001 /* Page is valid */ @@ -367,14 +362,8 @@ extern int icache_44x_need_flush; #define _PAGE_ACCESSED 0x100 /* R: page referenced */ #define _PAGE_EXEC 0x200 /* software: i-cache coherency required */ #define _PAGE_RW 0x400 /* software: user write access allowed */ -#define _PAGE_SPECIAL 0x800 /* software: Special page */ -#ifdef CONFIG_PTE_64BIT -/* We never clear the high word of the pte */ -#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE) -#else #define _PTE_NONE_MASK _PAGE_HASHPTE -#endif #define _PMD_PRESENT 0 #define _PMD_PRESENT_MASK (PAGE_MASK) @@ -383,8 +372,6 @@ extern int icache_44x_need_flush; /* Hash table based platforms need atomic updates of the linux PTE */ #define PTE_ATOMIC_UPDATES 1 -#define __HAVE_ARCH_PTE_SPECIAL - #endif /* @@ -417,9 +404,6 @@ extern int icache_44x_need_flush; #ifndef _PAGE_WRITETHRU #define _PAGE_WRITETHRU 0 #endif -#ifndef _PAGE_SPECIAL -#define _PAGE_SPECIAL 0 -#endif #ifndef _PMD_PRESENT_MASK #define _PMD_PRESENT_MASK _PMD_PRESENT #endif @@ -431,11 +415,11 @@ extern int icache_44x_need_flush; #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ - _PAGE_WRITETHRU | _PAGE_ENDIAN | \ - _PAGE_USER | _PAGE_ACCESSED | \ - _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \ - _PAGE_EXEC | _PAGE_HWEXEC) +#define PAGE_PROT_BITS __pgprot(_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU | _PAGE_ENDIAN | \ + _PAGE_USER | _PAGE_ACCESSED | \ + _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \ + _PAGE_EXEC | _PAGE_HWEXEC) /* * Note: the _PAGE_COHERENT bit automatically gets set in the hardware * PTE if CONFIG_SMP is defined (hash_page does this); there is no need @@ -533,8 +517,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); #define pte_none(pte) ((pte_val(pte) & ~_PTE_NONE_MASK) == 0) #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) -#define pte_clear(mm, addr, ptep) \ - do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0) +#define pte_clear(mm,addr,ptep) do { set_pte_at((mm), (addr), (ptep), __pte(0)); } while (0) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) @@ -550,7 +533,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } +static inline int pte_special(pte_t pte) { return 0; } static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } @@ -569,10 +552,10 @@ static inline pte_t pte_mkdirty(pte_t pte) { static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } static inline pte_t pte_mkspecial(pte_t pte) { - pte_val(pte) |= _PAGE_SPECIAL; return pte; } -static inline pgprot_t pte_pgprot(pte_t pte) + return pte; } +static inline unsigned long pte_pgprot(pte_t pte) { - return __pgprot(pte_val(pte) & PAGE_PROT_BITS); + return __pgprot(pte_val(pte)) & PAGE_PROT_BITS; } static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) @@ -592,10 +575,6 @@ extern int flush_hash_pages(unsigned context, unsigned long va, extern void add_hash_page(unsigned context, unsigned long va, unsigned long pmdval); -/* Flush an entry from the TLB/hash table */ -extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, - unsigned long address); - /* * Atomic PTE updates. * @@ -633,6 +612,9 @@ static inline unsigned long pte_update(pte_t *p, return old; } #else /* CONFIG_PTE_64BIT */ +/* TODO: Change that to only modify the low word and move set_pte_at() + * out of line + */ static inline unsigned long long pte_update(pte_t *p, unsigned long clr, unsigned long set) @@ -670,36 +652,14 @@ static inline unsigned long long pte_update(pte_t *p, * On machines which use an MMU hash table we avoid changing the * _PAGE_HASHPTE bit. */ - -static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { -#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) - pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); -#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) #if _PAGE_HASHPTE != 0 - if (pte_val(*ptep) & _PAGE_HASHPTE) - flush_hash_entry(mm, ptep, addr); -#endif - __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ - eieio\n\ - stw%U0%X0 %L2,%1" - : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) - : "r" (pte) : "memory"); + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); #else - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); -#endif -} - -static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte) -{ -#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) - WARN_ON(pte_present(*ptep)); + *ptep = pte; #endif - __set_pte_at(mm, addr, ptep, pte); } /* diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64.h b/trunk/arch/powerpc/include/asm/pgtable-ppc64.h index 4c0a8c62859d..4597c491e9b5 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc64.h @@ -117,10 +117,10 @@ #define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE) #define HAVE_PAGE_AGP -#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | \ - _PAGE_NO_CACHE | _PAGE_WRITETHRU | \ - _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC) +#define PAGE_PROT_BITS __pgprot(_PAGE_GUARDED | _PAGE_COHERENT | \ + _PAGE_NO_CACHE | _PAGE_WRITETHRU | \ + _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC) /* PTEIDX nibble */ #define _PTEIDX_SECONDARY 0x8 #define _PTEIDX_GROUP_IX 0x7 @@ -264,9 +264,9 @@ static inline pte_t pte_mkhuge(pte_t pte) { return pte; } static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; return pte; } -static inline pgprot_t pte_pgprot(pte_t pte) +static inline unsigned long pte_pgprot(pte_t pte) { - return __pgprot(pte_val(pte) & PAGE_PROT_BITS); + return __pgprot(pte_val(pte)) & PAGE_PROT_BITS; } /* Atomic PTE updates */ diff --git a/trunk/arch/powerpc/include/asm/ppc_asm.h b/trunk/arch/powerpc/include/asm/ppc_asm.h index c4a029ccb4d3..0966899d974b 100644 --- a/trunk/arch/powerpc/include/asm/ppc_asm.h +++ b/trunk/arch/powerpc/include/asm/ppc_asm.h @@ -268,7 +268,7 @@ GLUE(.,name): * Loads the value of the constant expression 'expr' into register 'rn' * using immediate instructions only. Use this when it's important not * to reference other data (i.e. on ppc64 when the TOC pointer is not - * valid) and when 'expr' is a constant or absolute address. + * valid). * * LOAD_REG_ADDR(rn, name) * Loads the address of label 'name' into register 'rn'. Use this when diff --git a/trunk/arch/powerpc/include/asm/reg_booke.h b/trunk/arch/powerpc/include/asm/reg_booke.h index 67453766bff1..be980f4ee495 100644 --- a/trunk/arch/powerpc/include/asm/reg_booke.h +++ b/trunk/arch/powerpc/include/asm/reg_booke.h @@ -109,7 +109,6 @@ #define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */ #define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */ #define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */ -#define SPRN_MMUCSR0 0x3F4 /* MMU Control and Status Register 0 */ #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */ #define SPRN_L2CSR0 0x3F9 /* L2 Data Cache Control and Status Register 0 */ @@ -411,12 +410,6 @@ #define L2CSR0_L2LOA 0x00000080 /* L2 Cache Lock Overflow Allocate */ #define L2CSR0_L2LO 0x00000020 /* L2 Cache Lock Overflow */ -/* Bit definitions for MMUCSR0 */ -#define MMUCSR0_TLB1FI 0x00000002 /* TLB1 Flash invalidate */ -#define MMUCSR0_TLB0FI 0x00000004 /* TLB0 Flash invalidate */ -#define MMUCSR0_TLB2FI 0x00000040 /* TLB2 Flash invalidate */ -#define MMUCSR0_TLB3FI 0x00000020 /* TLB3 Flash invalidate */ - /* Bit definitions for SGR. */ #define SGR_NORMAL 0 /* Speculative fetching allowed. */ #define SGR_GUARDED 1 /* Speculative fetching disallowed. */ diff --git a/trunk/arch/powerpc/include/asm/sections.h b/trunk/arch/powerpc/include/asm/sections.h index 6fbce725c710..07956f3e7844 100644 --- a/trunk/arch/powerpc/include/asm/sections.h +++ b/trunk/arch/powerpc/include/asm/sections.h @@ -18,12 +18,6 @@ static inline int in_kernel_text(unsigned long addr) return 0; } -static inline int overlaps_kernel_text(unsigned long start, unsigned long end) -{ - return start < (unsigned long)__init_end && - (unsigned long)_stext < end; -} - #undef dereference_function_descriptor static inline void *dereference_function_descriptor(void *ptr) { diff --git a/trunk/arch/powerpc/include/asm/smp.h b/trunk/arch/powerpc/include/asm/smp.h index 1866cec4f967..4d28e1e4521b 100644 --- a/trunk/arch/powerpc/include/asm/smp.h +++ b/trunk/arch/powerpc/include/asm/smp.h @@ -56,16 +56,9 @@ extern int smp_hw_index[]; #define raw_smp_processor_id() (current_thread_info()->cpu) #define hard_smp_processor_id() (smp_hw_index[smp_processor_id()]) - -static inline int get_hard_smp_processor_id(int cpu) -{ - return smp_hw_index[cpu]; -} - -static inline void set_hard_smp_processor_id(int cpu, int phys) -{ - smp_hw_index[cpu] = phys; -} +#define get_hard_smp_processor_id(cpu) (smp_hw_index[(cpu)]) +#define set_hard_smp_processor_id(cpu, phys)\ + (smp_hw_index[(cpu)] = (phys)) #endif DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); @@ -93,21 +86,15 @@ extern void __cpu_die(unsigned int cpu); #else /* for UP */ -#define hard_smp_processor_id() get_hard_smp_processor_id(0) +#define hard_smp_processor_id() 0 #define smp_setup_cpu_maps() #endif /* CONFIG_SMP */ #ifdef CONFIG_PPC64 -static inline int get_hard_smp_processor_id(int cpu) -{ - return paca[cpu].hw_cpu_id; -} - -static inline void set_hard_smp_processor_id(int cpu, int phys) -{ - paca[cpu].hw_cpu_id = phys; -} +#define get_hard_smp_processor_id(CPU) (paca[(CPU)].hw_cpu_id) +#define set_hard_smp_processor_id(CPU, VAL) \ + do { (paca[(CPU)].hw_cpu_id = (VAL)); } while (0) extern void smp_release_cpus(void); @@ -115,17 +102,10 @@ extern void smp_release_cpus(void); /* 32-bit */ #ifndef CONFIG_SMP extern int boot_cpuid_phys; -static inline int get_hard_smp_processor_id(int cpu) -{ - return boot_cpuid_phys; -} - -static inline void set_hard_smp_processor_id(int cpu, int phys) -{ - boot_cpuid_phys = phys; -} -#endif /* !CONFIG_SMP */ -#endif /* !CONFIG_PPC64 */ +#define get_hard_smp_processor_id(cpu) boot_cpuid_phys +#define set_hard_smp_processor_id(cpu, phys) +#endif +#endif extern int smt_enabled_at_boot; diff --git a/trunk/arch/powerpc/include/asm/statfs.h b/trunk/arch/powerpc/include/asm/statfs.h index 5244834583a4..67024026c10d 100644 --- a/trunk/arch/powerpc/include/asm/statfs.h +++ b/trunk/arch/powerpc/include/asm/statfs.h @@ -1,6 +1,60 @@ #ifndef _ASM_POWERPC_STATFS_H #define _ASM_POWERPC_STATFS_H +/* For ppc32 we just use the generic definitions, not so simple on ppc64 */ + +#ifndef __powerpc64__ #include +#else + +#ifndef __KERNEL_STRICT_NAMES +#include +typedef __kernel_fsid_t fsid_t; +#endif + +/* + * We're already 64-bit, so duplicate the definition + */ +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; + +struct statfs64 { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +}; +#endif /* ! __powerpc64__ */ #endif diff --git a/trunk/arch/powerpc/include/asm/systbl.h b/trunk/arch/powerpc/include/asm/systbl.h index 803def236654..f6cc7a43b4fa 100644 --- a/trunk/arch/powerpc/include/asm/systbl.h +++ b/trunk/arch/powerpc/include/asm/systbl.h @@ -32,7 +32,7 @@ COMPAT_SYS_SPU(stime) COMPAT_SYS(ptrace) SYSCALL_SPU(alarm) OLDSYS(fstat) -SYSCALL(pause) +COMPAT_SYS(pause) COMPAT_SYS(utime) SYSCALL(ni_syscall) SYSCALL(ni_syscall) diff --git a/trunk/arch/powerpc/include/asm/tlbflush.h b/trunk/arch/powerpc/include/asm/tlbflush.h index a2c6bfd85fb7..361cd5c7a32b 100644 --- a/trunk/arch/powerpc/include/asm/tlbflush.h +++ b/trunk/arch/powerpc/include/asm/tlbflush.h @@ -29,9 +29,6 @@ #include extern void _tlbie(unsigned long address, unsigned int pid); -extern void _tlbil_all(void); -extern void _tlbil_pid(unsigned int pid); -extern void _tlbil_va(unsigned long address, unsigned int pid); #if defined(CONFIG_40x) || defined(CONFIG_8xx) #define _tlbia() asm volatile ("tlbia; sync" : : : "memory") @@ -41,31 +38,31 @@ extern void _tlbia(void); static inline void flush_tlb_mm(struct mm_struct *mm) { - _tlbil_pid(mm->context.id); + _tlbia(); } static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { - _tlbil_va(vmaddr, vma ? vma->vm_mm->context.id : 0); + _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0); } static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long vmaddr) { - flush_tlb_page(vma, vmaddr); + _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0); } static inline void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - _tlbil_pid(vma->vm_mm->context.id); + _tlbia(); } static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) { - _tlbil_pid(0); + _tlbia(); } #elif defined(CONFIG_PPC32) diff --git a/trunk/arch/powerpc/include/asm/types.h b/trunk/arch/powerpc/include/asm/types.h index a9a9262e84a3..d3374bc865ba 100644 --- a/trunk/arch/powerpc/include/asm/types.h +++ b/trunk/arch/powerpc/include/asm/types.h @@ -55,7 +55,7 @@ typedef u64 phys_addr_t; typedef u32 phys_addr_t; #endif -#if defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT) +#ifdef __powerpc64__ typedef u64 dma_addr_t; #else typedef u32 dma_addr_t; diff --git a/trunk/arch/powerpc/kernel/.gitignore b/trunk/arch/powerpc/kernel/.gitignore deleted file mode 100644 index c5f676c3c224..000000000000 --- a/trunk/arch/powerpc/kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vmlinux.lds diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index fdb58253fa5b..946daea780f1 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -28,14 +28,13 @@ endif obj-y := cputable.o ptrace.o syscalls.o \ irq.o align.o signal_32.o pmc.o vdso.o \ init_task.o process.o systbl.o idle.o \ - signal.o sysfs.o + signal.o obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o cpu_setup_ppc970.o \ cpu_setup_pa6t.o \ - firmware.o nvram_64.o -obj64-$(CONFIG_RELOCATABLE) += reloc_64.o + firmware.o sysfs.o nvram_64.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_PPC_970_NAP) += idle_power4.o @@ -70,10 +69,10 @@ extra-$(CONFIG_8xx) := head_8xx.o extra-y += vmlinux.lds obj-y += time.o prom.o traps.o setup-common.o \ - udbg.o misc.o io.o dma.o \ + udbg.o misc.o io.o \ misc_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o -obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o +obj-$(CONFIG_PPC64) += dma_64.o iommu.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 09febc582584..92768d3006f7 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -122,8 +122,6 @@ int main(void) DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); - DEFINE(PACAKBASE, offsetof(struct paca_struct, kernelbase)); - DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); @@ -352,7 +350,6 @@ int main(void) #endif DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); - DEFINE(PTE_SIZE, sizeof(pte_t)); #ifdef CONFIG_KVM DEFINE(TLBE_BYTES, sizeof(struct tlbe)); diff --git a/trunk/arch/powerpc/kernel/btext.c b/trunk/arch/powerpc/kernel/btext.c index 26e58630ed7b..d8f0329b1344 100644 --- a/trunk/arch/powerpc/kernel/btext.c +++ b/trunk/arch/powerpc/kernel/btext.c @@ -442,26 +442,28 @@ void btext_drawtext(const char *c, unsigned int len) void btext_drawhex(unsigned long v) { + char *hex_table = "0123456789abcdef"; + if (!boot_text_mapped) return; #ifdef CONFIG_PPC64 - btext_drawchar(hex_asc_hi(v >> 56)); - btext_drawchar(hex_asc_lo(v >> 56)); - btext_drawchar(hex_asc_hi(v >> 48)); - btext_drawchar(hex_asc_lo(v >> 48)); - btext_drawchar(hex_asc_hi(v >> 40)); - btext_drawchar(hex_asc_lo(v >> 40)); - btext_drawchar(hex_asc_hi(v >> 32)); - btext_drawchar(hex_asc_lo(v >> 32)); + btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]); #endif - btext_drawchar(hex_asc_hi(v >> 24)); - btext_drawchar(hex_asc_lo(v >> 24)); - btext_drawchar(hex_asc_hi(v >> 16)); - btext_drawchar(hex_asc_lo(v >> 16)); - btext_drawchar(hex_asc_hi(v >> 8)); - btext_drawchar(hex_asc_lo(v >> 8)); - btext_drawchar(hex_asc_hi(v)); - btext_drawchar(hex_asc_lo(v)); + btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]); btext_drawchar(' '); } diff --git a/trunk/arch/powerpc/kernel/cpu_setup_ppc970.S b/trunk/arch/powerpc/kernel/cpu_setup_ppc970.S index 27f2507279d8..bf118c385752 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_ppc970.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_ppc970.S @@ -110,7 +110,7 @@ load_hids: isync /* Save away cpu state */ - LOAD_REG_ADDR(r5,cpu_state_storage) + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) /* Save HID0,1,4 and 5 */ mfspr r3,SPRN_HID0 @@ -134,7 +134,7 @@ _GLOBAL(__restore_cpu_ppc970) rldicl. r0,r0,4,63 beqlr - LOAD_REG_ADDR(r5,cpu_state_storage) + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) /* Before accessing memory, we make sure rm_ci is clear */ li r0,0 mfspr r3,SPRN_HID4 diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index e70d0483fb4e..25c273c761d1 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -610,7 +610,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750cx, .machine_check = machine_check_generic, .platform = "ppc750", @@ -624,7 +623,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750cx, .machine_check = machine_check_generic, .platform = "ppc750", @@ -638,7 +636,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750cx, .machine_check = machine_check_generic, .platform = "ppc750", @@ -652,7 +649,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", @@ -666,7 +662,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", @@ -680,7 +675,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", @@ -694,7 +688,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", @@ -708,7 +701,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750fx, .machine_check = machine_check_generic, .platform = "ppc750", @@ -722,7 +714,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750fx, .machine_check = machine_check_generic, .platform = "ppc750", @@ -736,7 +727,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_IBM, .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", @@ -751,7 +741,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_7400, .machine_check = machine_check_generic, .platform = "ppc7400", @@ -766,7 +755,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_7400, .machine_check = machine_check_generic, .platform = "ppc7400", @@ -781,7 +769,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_7410, .machine_check = machine_check_generic, .platform = "ppc7400", @@ -796,7 +783,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -813,7 +799,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -830,7 +815,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -847,7 +831,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -864,7 +847,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -881,7 +863,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -898,7 +879,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -915,7 +895,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -931,7 +910,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -948,7 +926,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, @@ -965,7 +942,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .pmc_type = PPC_PMC_G4, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", .oprofile_type = PPC_OPROFILE_G4, diff --git a/trunk/arch/powerpc/kernel/dma.c b/trunk/arch/powerpc/kernel/dma.c deleted file mode 100644 index 1562daf8839a..000000000000 --- a/trunk/arch/powerpc/kernel/dma.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation - * - * Provide default implementations of the DMA mapping callbacks for - * directly mapped busses. - */ - -#include -#include -#include -#include - -/* - * Generic direct DMA implementation - * - * This implementation supports a per-device offset that can be applied if - * the address at which memory is visible to devices is not 0. Platform code - * can set archdata.dma_data to an unsigned long holding the offset. By - * default the offset is PCI_DRAM_OFFSET. - */ - -static unsigned long get_dma_direct_offset(struct device *dev) -{ - if (dev) - return (unsigned long)dev->archdata.dma_data; - - return PCI_DRAM_OFFSET; -} - -void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - void *ret; -#ifdef CONFIG_NOT_COHERENT_CACHE - ret = __dma_alloc_coherent(size, dma_handle, flag); - if (ret == NULL) - return NULL; - *dma_handle += get_dma_direct_offset(dev); - return ret; -#else - struct page *page; - int node = dev_to_node(dev); - - /* ignore region specifiers */ - flag &= ~(__GFP_HIGHMEM); - - page = alloc_pages_node(node, flag, get_order(size)); - if (page == NULL) - return NULL; - ret = page_address(page); - memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); - - return ret; -#endif -} - -void dma_direct_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ -#ifdef CONFIG_NOT_COHERENT_CACHE - __dma_free_coherent(size, vaddr); -#else - free_pages((unsigned long)vaddr, get_order(size)); -#endif -} - -static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs) -{ - struct scatterlist *sg; - int i; - - for_each_sg(sgl, sg, nents, i) { - sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); - sg->dma_length = sg->length; - } - - return nents; -} - -static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs) -{ -} - -static int dma_direct_dma_supported(struct device *dev, u64 mask) -{ -#ifdef CONFIG_PPC64 - /* Could be improved to check for memory though it better be - * done via some global so platforms can set the limit in case - * they have limited DMA windows - */ - return mask >= DMA_32BIT_MASK; -#else - return 1; -#endif -} - -static inline dma_addr_t dma_direct_map_page(struct device *dev, - struct page *page, - unsigned long offset, - size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - BUG_ON(dir == DMA_NONE); - __dma_sync_page(page, offset, size, dir); - return page_to_phys(page) + offset + get_dma_direct_offset(dev); -} - -static inline void dma_direct_unmap_page(struct device *dev, - dma_addr_t dma_address, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) -{ -} - -struct dma_mapping_ops dma_direct_ops = { - .alloc_coherent = dma_direct_alloc_coherent, - .free_coherent = dma_direct_free_coherent, - .map_sg = dma_direct_map_sg, - .unmap_sg = dma_direct_unmap_sg, - .dma_supported = dma_direct_dma_supported, - .map_page = dma_direct_map_page, - .unmap_page = dma_direct_unmap_page, -}; -EXPORT_SYMBOL(dma_direct_ops); diff --git a/trunk/arch/powerpc/kernel/dma-iommu.c b/trunk/arch/powerpc/kernel/dma_64.c similarity index 53% rename from trunk/arch/powerpc/kernel/dma-iommu.c rename to trunk/arch/powerpc/kernel/dma_64.c index 49248f89ce23..ae5708e3a312 100644 --- a/trunk/arch/powerpc/kernel/dma-iommu.c +++ b/trunk/arch/powerpc/kernel/dma_64.c @@ -2,10 +2,14 @@ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation * * Provide default implementations of the DMA mapping callbacks for - * busses using the iommu infrastructure + * directly mapped busses and busses using the iommu infrastructure */ +#include +#include +#include #include +#include /* * Generic iommu implementation @@ -20,7 +24,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, { return iommu_alloc_coherent(dev, dev->archdata.dma_data, size, dma_handle, device_to_mask(dev), flag, - dev_to_node(dev)); + dev->archdata.numa_node); } static void dma_iommu_free_coherent(struct device *dev, size_t size, @@ -101,3 +105,96 @@ struct dma_mapping_ops dma_iommu_ops = { .dma_supported = dma_iommu_dma_supported, }; EXPORT_SYMBOL(dma_iommu_ops); + +/* + * Generic direct DMA implementation + * + * This implementation supports a per-device offset that can be applied if + * the address at which memory is visible to devices is not 0. Platform code + * can set archdata.dma_data to an unsigned long holding the offset. By + * default the offset is zero. + */ + +static unsigned long get_dma_direct_offset(struct device *dev) +{ + return (unsigned long)dev->archdata.dma_data; +} + +static void *dma_direct_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + struct page *page; + void *ret; + int node = dev->archdata.numa_node; + + page = alloc_pages_node(node, flag, get_order(size)); + if (page == NULL) + return NULL; + ret = page_address(page); + memset(ret, 0, size); + *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); + + return ret; +} + +static void dma_direct_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + +static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr, + size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + return virt_to_abs(ptr) + get_dma_direct_offset(dev); +} + +static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ +} + +static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sgl, sg, nents, i) { + sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); + sg->dma_length = sg->length; + } + + return nents; +} + +static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) +{ +} + +static int dma_direct_dma_supported(struct device *dev, u64 mask) +{ + /* Could be improved to check for memory though it better be + * done via some global so platforms can set the limit in case + * they have limited DMA windows + */ + return mask >= DMA_32BIT_MASK; +} + +struct dma_mapping_ops dma_direct_ops = { + .alloc_coherent = dma_direct_alloc_coherent, + .free_coherent = dma_direct_free_coherent, + .map_single = dma_direct_map_single, + .unmap_single = dma_direct_unmap_single, + .map_sg = dma_direct_map_sg, + .unmap_sg = dma_direct_unmap_sg, + .dma_supported = dma_direct_dma_supported, +}; +EXPORT_SYMBOL(dma_direct_ops); diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index fd8b4bae9b04..2d802e97097c 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -512,12 +512,31 @@ _GLOBAL(ret_from_except_lite) #endif restore: -BEGIN_FW_FTR_SECTION ld r5,SOFTE(r1) -FW_FTR_SECTION_ELSE - b iseries_check_pending_irqs -ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) -2: +#ifdef CONFIG_PPC_ISERIES +BEGIN_FW_FTR_SECTION + cmpdi 0,r5,0 + beq 4f + /* Check for pending interrupts (iSeries) */ + ld r3,PACALPPACAPTR(r13) + ld r3,LPPACAANYINT(r3) + cmpdi r3,0 + beq+ 4f /* skip do_IRQ if no interrupts */ + + li r3,0 + stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */ +#ifdef CONFIG_TRACE_IRQFLAGS + bl .trace_hardirqs_off + mfmsr r10 +#endif + ori r10,r10,MSR_EE + mtmsrd r10 /* hard-enable again */ + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_IRQ + b .ret_from_except_lite /* loop back and handle more */ +4: +END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) +#endif TRACE_AND_RESTORE_IRQ(r5); /* extract EE bit and use it to restore paca->hard_enabled */ @@ -573,30 +592,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) rfid b . /* prevent speculative execution */ -iseries_check_pending_irqs: -#ifdef CONFIG_PPC_ISERIES - ld r5,SOFTE(r1) - cmpdi 0,r5,0 - beq 2b - /* Check for pending interrupts (iSeries) */ - ld r3,PACALPPACAPTR(r13) - ld r3,LPPACAANYINT(r3) - cmpdi r3,0 - beq+ 2b /* skip do_IRQ if no interrupts */ - - li r3,0 - stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */ -#ifdef CONFIG_TRACE_IRQFLAGS - bl .trace_hardirqs_off - mfmsr r10 -#endif - ori r10,r10,MSR_EE - mtmsrd r10 /* hard-enable again */ - addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_IRQ - b .ret_from_except_lite /* loop back and handle more */ -#endif - do_work: #ifdef CONFIG_PREEMPT andi. r0,r3,MSR_PR /* Returning to user mode? */ @@ -690,6 +685,10 @@ _GLOBAL(enter_rtas) std r7,_DAR(r1) mfdsisr r8 std r8,_DSISR(r1) + mfsrr0 r9 + std r9,_SRR0(r1) + mfsrr1 r10 + std r10,_SRR1(r1) /* Temporary workaround to clear CR until RTAS can be modified to * ignore all bits. @@ -750,10 +749,6 @@ _STATIC(rtas_return_loc) mfspr r4,SPRN_SPRG3 /* Get PACA */ clrldi r4,r4,2 /* convert to realmode address */ - bcl 20,31,$+4 -0: mflr r3 - ld r3,(1f-0b)(r3) /* get &.rtas_restore_regs */ - mfmsr r6 li r0,MSR_RI andc r6,r6,r0 @@ -761,6 +756,7 @@ _STATIC(rtas_return_loc) mtmsrd r6 ld r1,PACAR1(r4) /* Restore our SP */ + LOAD_REG_IMMEDIATE(r3,.rtas_restore_regs) ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ mtspr SPRN_SRR0,r3 @@ -768,9 +764,6 @@ _STATIC(rtas_return_loc) rfid b . /* prevent speculative execution */ - .align 3 -1: .llong .rtas_restore_regs - _STATIC(rtas_restore_regs) /* relocation is on at this point */ REST_GPR(2, r1) /* Restore the TOC */ @@ -790,6 +783,10 @@ _STATIC(rtas_restore_regs) mtdar r7 ld r8,_DSISR(r1) mtdsisr r8 + ld r9,_SRR0(r1) + mtsrr0 r9 + ld r10,_SRR1(r1) + mtsrr1 r10 addi r1,r1,RTAS_FRAME_SIZE /* Unstack our frame */ ld r0,16(r1) /* get return address */ diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index 0c326823c6d4..8bb657519299 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -110,12 +110,6 @@ __start: #ifdef CONFIG_PPC_MULTIPLATFORM cmpwi 0,r5,0 beq 1f - - /* find out where we are now */ - bcl 20,31,$+4 -0: mflr r8 /* r8 = runtime addr here */ - addis r8,r8,(_stext - 0b)@ha - addi r8,r8,(_stext - 0b)@l /* current runtime base addr */ bl prom_init trap #endif @@ -375,13 +369,13 @@ i##n: \ DataAccess: EXCEPTION_PROLOG mfspr r10,SPRN_DSISR - stw r10,_DSISR(r11) andis. r0,r10,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ mfspr r4,SPRN_DAR /* into the hash table */ rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ bl hash_page -1: lwz r5,_DSISR(r11) /* get DSISR value */ +1: stw r10,_DSISR(r11) + mr r5,r10 mfspr r4,SPRN_DAR EXC_XFER_EE_LITE(0x300, handle_page_fault) diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 84856bee33a5..cc8fb474d520 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -82,11 +82,7 @@ END_FTR_SECTION(0, 1) /* Catch branch to 0 in real mode */ trap - /* Secondary processors spin on this value until it becomes nonzero. - * When it does it contains the real address of the descriptor - * of the function that the cpu should jump to to continue - * initialization. - */ + /* Secondary processors spin on this value until it goes to 1. */ .globl __secondary_hold_spinloop __secondary_hold_spinloop: .llong 0x0 @@ -113,11 +109,8 @@ __secondary_hold_acknowledge: * before the bulk of the kernel has been relocated. This code * is relocated to physical address 0x60 before prom_init is run. * All of it must fit below the first exception vector at 0x100. - * Use .globl here not _GLOBAL because we want __secondary_hold - * to be the actual text address, not a descriptor. */ - .globl __secondary_hold -__secondary_hold: +_GLOBAL(__secondary_hold) mfmsr r24 ori r24,r24,MSR_RI mtmsrd r24 /* RI on */ @@ -128,16 +121,16 @@ __secondary_hold: /* Tell the master cpu we're here */ /* Relocation is off & we are located at an address less */ /* than 0x100, so only need to grab low order offset. */ - std r24,__secondary_hold_acknowledge-_stext(0) + std r24,__secondary_hold_acknowledge@l(0) sync /* All secondary cpus wait here until told to start. */ -100: ld r4,__secondary_hold_spinloop-_stext(0) - cmpdi 0,r4,0 - beq 100b +100: ld r4,__secondary_hold_spinloop@l(0) + cmpdi 0,r4,1 + bne 100b #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) - ld r4,0(r4) /* deref function descriptor */ + LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init) mtctr r4 mr r3,r24 bctr @@ -154,10 +147,6 @@ exception_marker: /* * This is the start of the interrupt handlers for pSeries * This code runs with relocation off. - * Code from here to __end_interrupts gets copied down to real - * address 0x100 when we are running a relocatable kernel. - * Therefore any relative branches in this section must only - * branch to labels in this section. */ . = 0x100 .globl __start_interrupts @@ -211,20 +200,7 @@ data_access_slb_pSeries: mfspr r10,SPRN_SPRG1 std r10,PACA_EXSLB+EX_R13(r13) mfspr r12,SPRN_SRR1 /* and SRR1 */ -#ifndef CONFIG_RELOCATABLE - b .slb_miss_realmode -#else - /* - * We can't just use a direct branch to .slb_miss_realmode - * because the distance from here to there depends on where - * the kernel ends up being put. - */ - mfctr r11 - ld r10,PACAKBASE(r13) - LOAD_HANDLER(r10, .slb_miss_realmode) - mtctr r10 - bctr -#endif + b .slb_miss_realmode /* Rel. branch works in real mode */ STD_EXCEPTION_PSERIES(0x400, instruction_access) @@ -249,15 +225,7 @@ instruction_access_slb_pSeries: mfspr r10,SPRN_SPRG1 std r10,PACA_EXSLB+EX_R13(r13) mfspr r12,SPRN_SRR1 /* and SRR1 */ -#ifndef CONFIG_RELOCATABLE - b .slb_miss_realmode -#else - mfctr r11 - ld r10,PACAKBASE(r13) - LOAD_HANDLER(r10, .slb_miss_realmode) - mtctr r10 - bctr -#endif + b .slb_miss_realmode /* Rel. branch works in real mode */ MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt) STD_EXCEPTION_PSERIES(0x600, alignment) @@ -276,12 +244,14 @@ BEGIN_FTR_SECTION beq- 1f END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) mr r9,r13 + mfmsr r10 mfspr r13,SPRN_SPRG3 mfspr r11,SPRN_SRR0 - ld r12,PACAKBASE(r13) - ld r10,PACAKMSR(r13) - LOAD_HANDLER(r12, system_call_entry) + clrrdi r12,r13,32 + oris r12,r12,system_call_common@h + ori r12,r12,system_call_common@l mtspr SPRN_SRR0,r12 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI mfspr r12,SPRN_SRR1 mtspr SPRN_SRR1,r10 rfid @@ -355,32 +325,16 @@ do_stab_bolted_pSeries: mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) -#ifdef CONFIG_PPC_PSERIES -/* - * Vectors for the FWNMI option. Share common code. - */ - .globl system_reset_fwnmi - .align 7 -system_reset_fwnmi: - HMT_MEDIUM - mtspr SPRN_SPRG1,r13 /* save r13 */ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - - .globl machine_check_fwnmi - .align 7 -machine_check_fwnmi: - HMT_MEDIUM - mtspr SPRN_SPRG1,r13 /* save r13 */ - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) - -#endif /* CONFIG_PPC_PSERIES */ - -#ifdef __DISABLED__ /* + * We have some room here we use that to put + * the peries slb miss user trampoline code so it's reasonably + * away from slb_miss_user_common to avoid problems with rfid + * * This is used for when the SLB miss handler has to go virtual, * which doesn't happen for now anymore but will once we re-implement * dynamic VSIDs for shared page tables */ +#ifdef __DISABLED__ slb_miss_user_pseries: std r10,PACA_EXGEN+EX_R10(r13) std r11,PACA_EXGEN+EX_R11(r13) @@ -403,17 +357,25 @@ slb_miss_user_pseries: b . /* prevent spec. execution */ #endif /* __DISABLED__ */ - .align 7 - .globl __end_interrupts -__end_interrupts: - +#ifdef CONFIG_PPC_PSERIES /* - * Code from here down to __end_handlers is invoked from the - * exception prologs above. Because the prologs assemble the - * addresses of these handlers using the LOAD_HANDLER macro, - * which uses an addi instruction, these handlers must be in - * the first 32k of the kernel image. + * Vectors for the FWNMI option. Share common code. */ + .globl system_reset_fwnmi + .align 7 +system_reset_fwnmi: + HMT_MEDIUM + mtspr SPRN_SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXGEN, system_reset_common) + + .globl machine_check_fwnmi + .align 7 +machine_check_fwnmi: + HMT_MEDIUM + mtspr SPRN_SPRG1,r13 /* save r13 */ + EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common) + +#endif /* CONFIG_PPC_PSERIES */ /*** Common interrupt handlers ***/ @@ -452,10 +414,6 @@ machine_check_common: STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception) #endif /* CONFIG_CBE_RAS */ - .align 7 -system_call_entry: - b system_call_common - /* * Here we have detected that the kernel stack pointer is bad. * R9 contains the saved CR, r13 points to the paca, @@ -498,6 +456,65 @@ bad_stack: bl .kernel_bad_stack b 1b +/* + * Return from an exception with minimal checks. + * The caller is assumed to have done EXCEPTION_PROLOG_COMMON. + * If interrupts have been enabled, or anything has been + * done that might have changed the scheduling status of + * any task or sent any task a signal, you should use + * ret_from_except or ret_from_except_lite instead of this. + */ +fast_exc_return_irq: /* restores irq state too */ + ld r3,SOFTE(r1) + TRACE_AND_RESTORE_IRQ(r3); + ld r12,_MSR(r1) + rldicl r4,r12,49,63 /* get MSR_EE to LSB */ + stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ + b 1f + + .globl fast_exception_return +fast_exception_return: + ld r12,_MSR(r1) +1: ld r11,_NIP(r1) + andi. r3,r12,MSR_RI /* check if RI is set */ + beq- unrecov_fer + +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + andi. r3,r12,MSR_PR + beq 2f + ACCOUNT_CPU_USER_EXIT(r3, r4) +2: +#endif + + ld r3,_CCR(r1) + ld r4,_LINK(r1) + ld r5,_CTR(r1) + ld r6,_XER(r1) + mtcr r3 + mtlr r4 + mtctr r5 + mtxer r6 + REST_GPR(0, r1) + REST_8GPRS(2, r1) + + mfmsr r10 + rldicl r10,r10,48,1 /* clear EE */ + rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */ + mtmsrd r10,1 + + mtspr SPRN_SRR1,r12 + mtspr SPRN_SRR0,r11 + REST_4GPRS(10, r1) + ld r1,GPR1(r1) + rfid + b . /* prevent speculative execution */ + +unrecov_fer: + bl .save_nvgprs +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl .unrecoverable_exception + b 1b + /* * Here r13 points to the paca, r9 contains the saved CR, * SRR0 and SRR1 are saved in r11 and r12, @@ -599,9 +616,6 @@ unrecov_user_slb: */ _GLOBAL(slb_miss_realmode) mflr r10 -#ifdef CONFIG_RELOCATABLE - mtctr r11 -#endif stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ @@ -652,10 +666,11 @@ BEGIN_FW_FTR_SECTION END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif /* CONFIG_PPC_ISERIES */ mfspr r11,SPRN_SRR0 - ld r10,PACAKBASE(r13) + clrrdi r10,r13,32 LOAD_HANDLER(r10,unrecov_slb) mtspr SPRN_SRR0,r10 - ld r10,PACAKMSR(r13) + mfmsr r10 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI mtspr SPRN_SRR1,r10 rfid b . @@ -751,85 +766,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) bl .altivec_unavailable_exception b .ret_from_except - .align 7 - .globl vsx_unavailable_common -vsx_unavailable_common: - EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN) -#ifdef CONFIG_VSX -BEGIN_FTR_SECTION - bne .load_up_vsx -1: -END_FTR_SECTION_IFSET(CPU_FTR_VSX) -#endif - bl .save_nvgprs - addi r3,r1,STACK_FRAME_OVERHEAD - ENABLE_INTS - bl .vsx_unavailable_exception - b .ret_from_except - - .align 7 - .globl __end_handlers -__end_handlers: - -/* - * Return from an exception with minimal checks. - * The caller is assumed to have done EXCEPTION_PROLOG_COMMON. - * If interrupts have been enabled, or anything has been - * done that might have changed the scheduling status of - * any task or sent any task a signal, you should use - * ret_from_except or ret_from_except_lite instead of this. - */ -fast_exc_return_irq: /* restores irq state too */ - ld r3,SOFTE(r1) - TRACE_AND_RESTORE_IRQ(r3); - ld r12,_MSR(r1) - rldicl r4,r12,49,63 /* get MSR_EE to LSB */ - stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ - b 1f - - .globl fast_exception_return -fast_exception_return: - ld r12,_MSR(r1) -1: ld r11,_NIP(r1) - andi. r3,r12,MSR_RI /* check if RI is set */ - beq- unrecov_fer - -#ifdef CONFIG_VIRT_CPU_ACCOUNTING - andi. r3,r12,MSR_PR - beq 2f - ACCOUNT_CPU_USER_EXIT(r3, r4) -2: -#endif - - ld r3,_CCR(r1) - ld r4,_LINK(r1) - ld r5,_CTR(r1) - ld r6,_XER(r1) - mtcr r3 - mtlr r4 - mtctr r5 - mtxer r6 - REST_GPR(0, r1) - REST_8GPRS(2, r1) - - mfmsr r10 - rldicl r10,r10,48,1 /* clear EE */ - rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */ - mtmsrd r10,1 - - mtspr SPRN_SRR1,r12 - mtspr SPRN_SRR0,r11 - REST_4GPRS(10, r1) - ld r1,GPR1(r1) - rfid - b . /* prevent speculative execution */ - -unrecov_fer: - bl .save_nvgprs -1: addi r3,r1,STACK_FRAME_OVERHEAD - bl .unrecoverable_exception - b 1b - #ifdef CONFIG_ALTIVEC /* * load_up_altivec(unused, unused, tsk) @@ -904,6 +840,22 @@ _STATIC(load_up_altivec) blr #endif /* CONFIG_ALTIVEC */ + .align 7 + .globl vsx_unavailable_common +vsx_unavailable_common: + EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN) +#ifdef CONFIG_VSX +BEGIN_FTR_SECTION + bne .load_up_vsx +1: +END_FTR_SECTION_IFSET(CPU_FTR_VSX) +#endif + bl .save_nvgprs + addi r3,r1,STACK_FRAME_OVERHEAD + ENABLE_INTS + bl .vsx_unavailable_exception + b .ret_from_except + #ifdef CONFIG_VSX /* * load_up_vsx(unused, unused, tsk) @@ -1223,14 +1175,11 @@ _GLOBAL(generic_secondary_smp_init) /* turn on 64-bit mode */ bl .enable_64b_mode - /* get the TOC pointer (real address) */ - bl .relative_toc - /* Set up a paca value for this processor. Since we have the * physical cpu id in r24, we need to search the pacas to find * which logical id maps to our physical one. */ - LOAD_REG_ADDR(r13, paca) /* Get base vaddr of paca array */ + LOAD_REG_IMMEDIATE(r13, paca) /* Get base vaddr of paca array */ li r5,0 /* logical cpu id */ 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ cmpw r6,r24 /* Compare to our id */ @@ -1259,7 +1208,7 @@ _GLOBAL(generic_secondary_smp_init) sync /* order paca.run and cur_cpu_spec */ /* See if we need to call a cpu state restore handler */ - LOAD_REG_ADDR(r23, cur_cpu_spec) + LOAD_REG_IMMEDIATE(r23, cur_cpu_spec) ld r23,0(r23) ld r23,CPU_SPEC_RESTORE(r23) cmpdi 0,r23,0 @@ -1275,15 +1224,10 @@ _GLOBAL(generic_secondary_smp_init) b __secondary_start #endif -/* - * Turn the MMU off. - * Assumes we're mapped EA == RA if the MMU is on. - */ _STATIC(__mmu_off) mfmsr r3 andi. r0,r3,MSR_IR|MSR_DR beqlr - mflr r4 andc r3,r3,r0 mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r3 @@ -1304,18 +1248,6 @@ _STATIC(__mmu_off) * */ _GLOBAL(__start_initialization_multiplatform) - /* Make sure we are running in 64 bits mode */ - bl .enable_64b_mode - - /* Get TOC pointer (current runtime address) */ - bl .relative_toc - - /* find out where we are now */ - bcl 20,31,$+4 -0: mflr r26 /* r26 = runtime addr here */ - addis r26,r26,(_stext - 0b)@ha - addi r26,r26,(_stext - 0b)@l /* current runtime base addr */ - /* * Are we booted from a PROM Of-type client-interface ? */ @@ -1327,6 +1259,9 @@ _GLOBAL(__start_initialization_multiplatform) mr r31,r3 mr r30,r4 + /* Make sure we are running in 64 bits mode */ + bl .enable_64b_mode + /* Setup some critical 970 SPRs before switching MMU off */ mfspr r0,SPRN_PVR srwi r0,r0,16 @@ -1341,7 +1276,9 @@ _GLOBAL(__start_initialization_multiplatform) 1: bl .__cpu_preinit_ppc970 2: - /* Switch off MMU if not already off */ + /* Switch off MMU if not already */ + LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) + add r4,r4,r30 bl .__mmu_off b .__after_prom_start @@ -1356,15 +1293,22 @@ _INIT_STATIC(__boot_from_prom) /* * Align the stack to 16-byte boundary * Depending on the size and layout of the ELF sections in the initial - * boot binary, the stack pointer may be unaligned on PowerMac + * boot binary, the stack pointer will be unalignet on PowerMac */ rldicr r1,r1,0,59 -#ifdef CONFIG_RELOCATABLE - /* Relocate code for where we are now */ - mr r3,r26 - bl .relocate -#endif + /* Make sure we are running in 64 bits mode */ + bl .enable_64b_mode + + /* put a relocation offset into r3 */ + bl .reloc_offset + + LOAD_REG_IMMEDIATE(r2,__toc_start) + addi r2,r2,0x4000 + addi r2,r2,0x4000 + + /* Relocate the TOC from a virt addr to a real addr */ + add r2,r2,r3 /* Restore parameters */ mr r3,r31 @@ -1374,51 +1318,60 @@ _INIT_STATIC(__boot_from_prom) mr r7,r27 /* Do all of the interaction with OF client interface */ - mr r8,r26 bl .prom_init /* We never return */ trap _STATIC(__after_prom_start) -#ifdef CONFIG_RELOCATABLE - /* process relocations for the final address of the kernel */ - lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ - sldi r25,r25,32 - mr r3,r25 - bl .relocate -#endif /* - * We need to run with _stext at physical address PHYSICAL_START. + * We need to run with __start at physical address PHYSICAL_START. * This will leave some code in the first 256B of * real memory, which are reserved for software use. + * The remainder of the first page is loaded with the fixed + * interrupt vectors. The next two pages are filled with + * unknown exception placeholders. * * Note: This process overwrites the OF exception vectors. + * r26 == relocation offset + * r27 == KERNELBASE */ - li r3,0 /* target addr */ - mr. r4,r26 /* In some cases the loader may */ - beq 9f /* have already put us at zero */ - lis r5,(copy_to_here - _stext)@ha - addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ + bl .reloc_offset + mr r26,r3 + LOAD_REG_IMMEDIATE(r27, KERNELBASE) + + LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */ + + // XXX FIXME: Use phys returned by OF (r30) + add r4,r27,r26 /* source addr */ + /* current address of _start */ + /* i.e. where we are running */ + /* the source addr */ + + cmpdi r4,0 /* In some cases the loader may */ + bne 1f + b .start_here_multiplatform /* have already put us at zero */ + /* so we can skip the copy. */ +1: LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ + sub r5,r5,r27 + li r6,0x100 /* Start offset, the first 0x100 */ /* bytes were copied earlier. */ bl .copy_and_flush /* copy the first n bytes */ /* this includes the code being */ /* executed here. */ - addis r8,r3,(4f - _stext)@ha /* Jump to the copy of this code */ - addi r8,r8,(4f - _stext)@l /* that we just made */ - mtctr r8 + + LOAD_REG_IMMEDIATE(r0, 4f) /* Jump to the copy of this code */ + mtctr r0 /* that we just made/relocated */ bctr -4: /* Now copy the rest of the kernel up to _end */ - addis r5,r26,(p_end - _stext)@ha - ld r5,(p_end - _stext)@l(r5) /* get _end */ +4: LOAD_REG_IMMEDIATE(r5,klimit) + add r5,r5,r26 + ld r5,0(r5) /* get the value of klimit */ + sub r5,r5,r27 bl .copy_and_flush /* copy the rest */ - -9: b .start_here_multiplatform - -p_end: .llong _end - _stext + b .start_here_multiplatform /* * Copy routine used to copy the kernel to start at physical address 0 @@ -1483,9 +1436,6 @@ _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ bl .enable_64b_mode - /* get TOC pointer (real address) */ - bl .relative_toc - /* Copy some CPU settings from CPU 0 */ bl .__restore_cpu_ppc970 @@ -1495,10 +1445,10 @@ _GLOBAL(pmac_secondary_start) mtmsrd r3 /* RI on */ /* Set up a paca value for this processor. */ - LOAD_REG_ADDR(r4,paca) /* Get base vaddr of paca array */ - mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ + LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ + mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r4 /* for this processor. */ - mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ + mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) @@ -1526,6 +1476,9 @@ __secondary_start: /* Set thread priority to MEDIUM */ HMT_MEDIUM + /* Load TOC */ + ld r2,PACATOC(r13) + /* Do early setup for that CPU (stab, slb, hash table pointer) */ bl .early_setup_secondary @@ -1562,11 +1515,9 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) /* * Running with relocation on at this point. All we want to do is - * zero the stack back-chain pointer and get the TOC virtual address - * before going into C code. + * zero the stack back-chain pointer before going into C code. */ _GLOBAL(start_secondary_prolog) - ld r2,PACATOC(r13) li r3,0 std r3,0(r1) /* Zero the stack frame pointer */ bl .start_secondary @@ -1578,46 +1529,34 @@ _GLOBAL(start_secondary_prolog) */ _GLOBAL(enable_64b_mode) mfmsr r11 /* grab the current MSR */ - li r12,(MSR_SF | MSR_ISF)@highest - sldi r12,r12,48 + li r12,1 + rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) + or r11,r11,r12 + li r12,1 + rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) or r11,r11,r12 mtmsrd r11 isync blr -/* - * This puts the TOC pointer into r2, offset by 0x8000 (as expected - * by the toolchain). It computes the correct value for wherever we - * are running at the moment, using position-independent code. - */ -_GLOBAL(relative_toc) - mflr r0 - bcl 20,31,$+4 -0: mflr r9 - ld r2,(p_toc - 0b)(r9) - add r2,r2,r9 - mtlr r0 - blr - -p_toc: .llong __toc_start + 0x8000 - 0b - /* * This is where the main kernel code starts. */ _INIT_STATIC(start_here_multiplatform) - /* set up the TOC (real address) */ - bl .relative_toc + /* get a new offset, now that the kernel has moved. */ + bl .reloc_offset + mr r26,r3 /* Clear out the BSS. It may have been done in prom_init, * already but that's irrelevant since prom_init will soon * be detached from the kernel completely. Besides, we need * to clear it now for kexec-style entry. */ - LOAD_REG_ADDR(r11,__bss_stop) - LOAD_REG_ADDR(r8,__bss_start) + LOAD_REG_IMMEDIATE(r11,__bss_stop) + LOAD_REG_IMMEDIATE(r8,__bss_start) sub r11,r11,r8 /* bss size */ addi r11,r11,7 /* round up to an even double word */ - srdi. r11,r11,3 /* shift right by 3 */ + rldicl. r11,r11,61,3 /* shift right by 3 */ beq 4f addi r8,r8,-8 li r0,0 @@ -1630,35 +1569,35 @@ _INIT_STATIC(start_here_multiplatform) ori r6,r6,MSR_RI mtmsrd r6 /* RI on */ -#ifdef CONFIG_RELOCATABLE - /* Save the physical address we're running at in kernstart_addr */ - LOAD_REG_ADDR(r4, kernstart_addr) - clrldi r0,r25,2 - std r0,0(r4) -#endif - - /* The following gets the stack set up with the regs */ + /* The following gets the stack and TOC set up with the regs */ /* pointing to the real addr of the kernel stack. This is */ /* all done to support the C function call below which sets */ /* up the htab. This is done because we have relocated the */ /* kernel but are still running in real mode. */ - LOAD_REG_ADDR(r3,init_thread_union) + LOAD_REG_IMMEDIATE(r3,init_thread_union) + add r3,r3,r26 - /* set up a stack pointer */ + /* set up a stack pointer (physical address) */ addi r1,r3,THREAD_SIZE li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) + /* set up the TOC (physical address) */ + LOAD_REG_IMMEDIATE(r2,__toc_start) + addi r2,r2,0x4000 + addi r2,r2,0x4000 + add r2,r2,r26 + /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ /* Restore parameters passed from prom_init/kexec */ mr r3,r31 - bl .early_setup /* also sets r13 and SPRG3 */ + bl .early_setup - LOAD_REG_ADDR(r3, .start_here_common) - ld r4,PACAKMSR(r13) + LOAD_REG_IMMEDIATE(r3, .start_here_common) + LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 rfid @@ -1667,10 +1606,20 @@ _INIT_STATIC(start_here_multiplatform) /* This is where all platforms converge execution */ _INIT_GLOBAL(start_here_common) /* relocation is on at this point */ - std r1,PACAKSAVE(r13) - /* Load the TOC (virtual address) */ + /* The following code sets up the SP and TOC now that we are */ + /* running with translation enabled. */ + + LOAD_REG_IMMEDIATE(r3,init_thread_union) + + /* set up the stack */ + addi r1,r3,THREAD_SIZE + li r0,0 + stdu r0,-STACK_FRAME_OVERHEAD(r1) + + /* Load the TOC */ ld r2,PACATOC(r13) + std r1,PACAKSAVE(r13) bl .setup_system diff --git a/trunk/arch/powerpc/kernel/head_fsl_booke.S b/trunk/arch/powerpc/kernel/head_fsl_booke.S index 590304c24dad..3cb52fa0eda3 100644 --- a/trunk/arch/powerpc/kernel/head_fsl_booke.S +++ b/trunk/arch/powerpc/kernel/head_fsl_booke.S @@ -422,6 +422,7 @@ skpinv: addi r6,r6,1 /* Increment */ * r12 is pointer to the pte */ #ifdef CONFIG_PTE_64BIT +#define PTE_FLAGS_OFFSET 4 #define FIND_PTE \ rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ @@ -430,6 +431,7 @@ skpinv: addi r6,r6,1 /* Increment */ rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ lwz r11, 4(r12); /* Get pte entry */ #else +#define PTE_FLAGS_OFFSET 0 #define FIND_PTE \ rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ lwz r11, 0(r11); /* Get L1 entry */ \ @@ -577,19 +579,13 @@ interrupt_base: FIND_PTE andc. r13,r13,r11 /* Check permission */ + bne 2f /* Bail if permission mismach */ #ifdef CONFIG_PTE_64BIT -#ifdef CONFIG_SMP - subf r10,r11,r12 /* create false data dep */ - lwzx r13,r11,r10 /* Get upper pte bits */ -#else - lwz r13,0(r12) /* Get upper pte bits */ -#endif + lwz r13, 0(r12) #endif - bne 2f /* Bail if permission/valid mismach */ - - /* Jump to common tlb load */ + /* Jump to common tlb load */ b finish_tlb_load 2: /* The bailout. Restore registers to pre-exception conditions @@ -644,18 +640,12 @@ interrupt_base: FIND_PTE andc. r13,r13,r11 /* Check permission */ + bne 2f /* Bail if permission mismach */ #ifdef CONFIG_PTE_64BIT -#ifdef CONFIG_SMP - subf r10,r11,r12 /* create false data dep */ - lwzx r13,r11,r10 /* Get upper pte bits */ -#else - lwz r13,0(r12) /* Get upper pte bits */ -#endif + lwz r13, 0(r12) #endif - bne 2f /* Bail if permission mismach */ - /* Jump to common TLB load point */ b finish_tlb_load @@ -712,7 +702,7 @@ interrupt_base: /* * Both the instruction and data TLB miss get to this * point to load the TLB. - * r10 - available to use + * r10 - EA of fault * r11 - TLB (info from Linux PTE) * r12 - available to use * r13 - upper bits of PTE (if PTE_64BIT) or available to use diff --git a/trunk/arch/powerpc/kernel/iommu.c b/trunk/arch/powerpc/kernel/iommu.c index ea1ba89f9c90..550a19399bfa 100644 --- a/trunk/arch/powerpc/kernel/iommu.c +++ b/trunk/arch/powerpc/kernel/iommu.c @@ -51,6 +51,17 @@ static int protect4gb = 1; static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); +static inline unsigned long iommu_num_pages(unsigned long vaddr, + unsigned long slen) +{ + unsigned long npages; + + npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK); + npages >>= IOMMU_PAGE_SHIFT; + + return npages; +} + static int __init setup_protect4gb(char *str) { if (strcmp(str, "on") == 0) @@ -314,7 +325,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, } /* Allocate iommu entries for that segment */ vaddr = (unsigned long) sg_virt(s); - npages = iommu_num_pages(vaddr, slen, IOMMU_PAGE_SIZE); + npages = iommu_num_pages(vaddr, slen); align = 0; if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE && (vaddr & ~PAGE_MASK) == 0) @@ -407,8 +418,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, unsigned long vaddr, npages; vaddr = s->dma_address & IOMMU_PAGE_MASK; - npages = iommu_num_pages(s->dma_address, s->dma_length, - IOMMU_PAGE_SIZE); + npages = iommu_num_pages(s->dma_address, s->dma_length); __iommu_free(tbl, vaddr, npages); s->dma_address = DMA_ERROR_CODE; s->dma_length = 0; @@ -442,8 +452,7 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, if (sg->dma_length == 0) break; - npages = iommu_num_pages(dma_handle, sg->dma_length, - IOMMU_PAGE_SIZE); + npages = iommu_num_pages(dma_handle, sg->dma_length); __iommu_free(tbl, dma_handle, npages); sg = sg_next(sg); } @@ -575,7 +584,7 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, BUG_ON(direction == DMA_NONE); uaddr = (unsigned long)vaddr; - npages = iommu_num_pages(uaddr, size, IOMMU_PAGE_SIZE); + npages = iommu_num_pages(uaddr, size); if (tbl) { align = 0; @@ -608,7 +617,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, BUG_ON(direction == DMA_NONE); if (tbl) { - npages = iommu_num_pages(dma_handle, size, IOMMU_PAGE_SIZE); + npages = iommu_num_pages(dma_handle, size); iommu_free(tbl, dma_handle, npages); } } diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index ac222d0ab12e..d972decf0324 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -439,8 +439,8 @@ void do_softirq(void) static LIST_HEAD(irq_hosts); static DEFINE_SPINLOCK(irq_big_lock); -static unsigned int revmap_trees_allocated; -static DEFINE_MUTEX(revmap_trees_mutex); +static DEFINE_PER_CPU(unsigned int, irq_radix_reader); +static unsigned int irq_radix_writer; struct irq_map_entry irq_map[NR_IRQS]; static unsigned int irq_virq_count = NR_IRQS; static struct irq_host *irq_default_host; @@ -583,6 +583,57 @@ void irq_set_virq_count(unsigned int count) irq_virq_count = count; } +/* radix tree not lockless safe ! we use a brlock-type mecanism + * for now, until we can use a lockless radix tree + */ +static void irq_radix_wrlock(unsigned long *flags) +{ + unsigned int cpu, ok; + + spin_lock_irqsave(&irq_big_lock, *flags); + irq_radix_writer = 1; + smp_mb(); + do { + barrier(); + ok = 1; + for_each_possible_cpu(cpu) { + if (per_cpu(irq_radix_reader, cpu)) { + ok = 0; + break; + } + } + if (!ok) + cpu_relax(); + } while(!ok); +} + +static void irq_radix_wrunlock(unsigned long flags) +{ + smp_wmb(); + irq_radix_writer = 0; + spin_unlock_irqrestore(&irq_big_lock, flags); +} + +static void irq_radix_rdlock(unsigned long *flags) +{ + local_irq_save(*flags); + __get_cpu_var(irq_radix_reader) = 1; + smp_mb(); + if (likely(irq_radix_writer == 0)) + return; + __get_cpu_var(irq_radix_reader) = 0; + smp_wmb(); + spin_lock(&irq_big_lock); + __get_cpu_var(irq_radix_reader) = 1; + spin_unlock(&irq_big_lock); +} + +static void irq_radix_rdunlock(unsigned long flags) +{ + __get_cpu_var(irq_radix_reader) = 0; + local_irq_restore(flags); +} + static int irq_setup_virq(struct irq_host *host, unsigned int virq, irq_hw_number_t hwirq) { @@ -737,6 +788,7 @@ void irq_dispose_mapping(unsigned int virq) { struct irq_host *host; irq_hw_number_t hwirq; + unsigned long flags; if (virq == NO_IRQ) return; @@ -769,16 +821,12 @@ void irq_dispose_mapping(unsigned int virq) host->revmap_data.linear.revmap[hwirq] = NO_IRQ; break; case IRQ_HOST_MAP_TREE: - /* - * Check if radix tree allocated yet, if not then nothing to - * remove. - */ - smp_rmb(); - if (revmap_trees_allocated < 1) + /* Check if radix tree allocated yet */ + if (host->revmap_data.tree.gfp_mask == 0) break; - mutex_lock(&revmap_trees_mutex); + irq_radix_wrlock(&flags); radix_tree_delete(&host->revmap_data.tree, hwirq); - mutex_unlock(&revmap_trees_mutex); + irq_radix_wrunlock(flags); break; } @@ -827,62 +875,43 @@ unsigned int irq_find_mapping(struct irq_host *host, EXPORT_SYMBOL_GPL(irq_find_mapping); -unsigned int irq_radix_revmap_lookup(struct irq_host *host, - irq_hw_number_t hwirq) +unsigned int irq_radix_revmap(struct irq_host *host, + irq_hw_number_t hwirq) { + struct radix_tree_root *tree; struct irq_map_entry *ptr; unsigned int virq; + unsigned long flags; WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE); - /* - * Check if the radix tree exists and has bee initialized. - * If not, we fallback to slow mode + /* Check if the radix tree exist yet. We test the value of + * the gfp_mask for that. Sneaky but saves another int in the + * structure. If not, we fallback to slow mode */ - if (revmap_trees_allocated < 2) + tree = &host->revmap_data.tree; + if (tree->gfp_mask == 0) return irq_find_mapping(host, hwirq); /* Now try to resolve */ - /* - * No rcu_read_lock(ing) needed, the ptr returned can't go under us - * as it's referencing an entry in the static irq_map table. - */ - ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq); + irq_radix_rdlock(&flags); + ptr = radix_tree_lookup(tree, hwirq); + irq_radix_rdunlock(flags); - /* - * If found in radix tree, then fine. - * Else fallback to linear lookup - this should not happen in practice - * as it means that we failed to insert the node in the radix tree. - */ - if (ptr) + /* Found it, return */ + if (ptr) { virq = ptr - irq_map; - else - virq = irq_find_mapping(host, hwirq); - - return virq; -} - -void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq) -{ - - WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE); - - /* - * Check if the radix tree exists yet. - * If not, then the irq will be inserted into the tree when it gets - * initialized. - */ - smp_rmb(); - if (revmap_trees_allocated < 1) - return; + return virq; + } + /* If not there, try to insert it */ + virq = irq_find_mapping(host, hwirq); if (virq != NO_IRQ) { - mutex_lock(&revmap_trees_mutex); - radix_tree_insert(&host->revmap_data.tree, hwirq, - &irq_map[virq]); - mutex_unlock(&revmap_trees_mutex); + irq_radix_wrlock(&flags); + radix_tree_insert(tree, hwirq, &irq_map[virq]); + irq_radix_wrunlock(flags); } + return virq; } unsigned int irq_linear_revmap(struct irq_host *host, @@ -991,44 +1020,14 @@ void irq_early_init(void) static int irq_late_init(void) { struct irq_host *h; - unsigned int i; + unsigned long flags; - /* - * No mutual exclusion with respect to accessors of the tree is needed - * here as the synchronization is done via the state variable - * revmap_trees_allocated. - */ + irq_radix_wrlock(&flags); list_for_each_entry(h, &irq_hosts, link) { if (h->revmap_type == IRQ_HOST_MAP_TREE) - INIT_RADIX_TREE(&h->revmap_data.tree, GFP_KERNEL); - } - - /* - * Make sure the radix trees inits are visible before setting - * the flag - */ - smp_wmb(); - revmap_trees_allocated = 1; - - /* - * Insert the reverse mapping for those interrupts already present - * in irq_map[]. - */ - mutex_lock(&revmap_trees_mutex); - for (i = 0; i < irq_virq_count; i++) { - if (irq_map[i].host && - (irq_map[i].host->revmap_type == IRQ_HOST_MAP_TREE)) - radix_tree_insert(&irq_map[i].host->revmap_data.tree, - irq_map[i].hwirq, &irq_map[i]); + INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); } - mutex_unlock(&revmap_trees_mutex); - - /* - * Make sure the radix trees insertions are visible before setting - * the flag - */ - smp_wmb(); - revmap_trees_allocated = 2; + irq_radix_wrunlock(flags); return 0; } diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index d051e8cbcd03..b3eef30b5131 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -510,10 +510,10 @@ static ssize_t update_ppp(u64 *entitlement, u8 *weight) return -EINVAL; pr_debug("%s: current_entitled = %lu, current_weight = %u\n", - __func__, ppp_data.entitlement, ppp_data.weight); + __FUNCTION__, ppp_data.entitlement, ppp_data.weight); pr_debug("%s: new_entitled = %lu, new_weight = %u\n", - __func__, new_entitled, new_weight); + __FUNCTION__, new_entitled, new_weight); retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight); return retval; @@ -556,10 +556,10 @@ static ssize_t update_mpp(u64 *entitlement, u8 *weight) return -EINVAL; pr_debug("%s: current_entitled = %lu, current_weight = %u\n", - __func__, mpp_data.entitled_mem, mpp_data.mem_weight); + __FUNCTION__, mpp_data.entitled_mem, mpp_data.mem_weight); pr_debug("%s: new_entitled = %lu, new_weight = %u\n", - __func__, new_entitled, new_weight); + __FUNCTION__, new_entitled, new_weight); rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight); return rc; diff --git a/trunk/arch/powerpc/kernel/misc.S b/trunk/arch/powerpc/kernel/misc.S index 2d29752cbe16..85cb6f340846 100644 --- a/trunk/arch/powerpc/kernel/misc.S +++ b/trunk/arch/powerpc/kernel/misc.S @@ -31,14 +31,11 @@ _GLOBAL(reloc_offset) mflr r0 bl 1f 1: mflr r3 - PPC_LL r4,(2f-1b)(r3) + LOAD_REG_IMMEDIATE(r4,1b) subf r3,r4,r3 mtlr r0 blr - .align 3 -2: PPC_LONG 1b - /* * add_reloc_offset(x) returns x + reloc_offset(). */ @@ -46,15 +43,12 @@ _GLOBAL(add_reloc_offset) mflr r0 bl 1f 1: mflr r5 - PPC_LL r4,(2f-1b)(r5) + LOAD_REG_IMMEDIATE(r4,1b) subf r5,r4,r5 add r3,r3,r5 mtlr r0 blr - .align 3 -2: PPC_LONG 1b - _GLOBAL(kernel_execve) li r0,__NR_execve sc diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 6a9b4bf0d173..7a6dfbca7682 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -274,10 +274,6 @@ _GLOBAL(real_writeb) /* * Flush MMU TLB */ -#ifndef CONFIG_FSL_BOOKE -_GLOBAL(_tlbil_all) -_GLOBAL(_tlbil_pid) -#endif _GLOBAL(_tlbia) #if defined(CONFIG_40x) sync /* Flush to memory before changing mapping */ @@ -348,9 +344,6 @@ _GLOBAL(_tlbia) /* * Flush MMU TLB for a particular address */ -#ifndef CONFIG_FSL_BOOKE -_GLOBAL(_tlbil_va) -#endif _GLOBAL(_tlbie) #if defined(CONFIG_40x) /* We run the search with interrupts disabled because we have to change @@ -443,53 +436,6 @@ _GLOBAL(_tlbie) #endif /* ! CONFIG_40x */ blr -#if defined(CONFIG_FSL_BOOKE) -/* - * Flush MMU TLB, but only on the local processor (no broadcast) - */ -_GLOBAL(_tlbil_all) -#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ - MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) - li r3,(MMUCSR0_TLBFI)@l - mtspr SPRN_MMUCSR0, r3 -1: - mfspr r3,SPRN_MMUCSR0 - andi. r3,r3,MMUCSR0_TLBFI@l - bne 1b - blr - -/* - * Flush MMU TLB for a particular process id, but only on the local processor - * (no broadcast) - */ -_GLOBAL(_tlbil_pid) -/* we currently do an invalidate all since we don't have per pid invalidate */ - li r3,(MMUCSR0_TLBFI)@l - mtspr SPRN_MMUCSR0, r3 -1: - mfspr r3,SPRN_MMUCSR0 - andi. r3,r3,MMUCSR0_TLBFI@l - bne 1b - blr - -/* - * Flush MMU TLB for a particular address, but only on the local processor - * (no broadcast) - */ -_GLOBAL(_tlbil_va) - slwi r4,r4,16 - mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ - tlbsx 0,r3 - mfspr r4,SPRN_MAS1 /* check valid */ - andis. r3,r4,MAS1_VALID@h - beqlr - rlwinm r4,r4,0,1,31 - mtspr SPRN_MAS1,r4 - tlbwe - blr -#endif /* CONFIG_FSL_BOOKE */ - - /* * Flush instruction cache. * This is a no-op on the 601. @@ -900,10 +846,8 @@ _GLOBAL(kernel_thread) li r4,0 /* new sp (unused) */ li r0,__NR_clone sc - bns+ 1f /* did system call indicate error? */ - neg r3,r3 /* if so, make return code negative */ -1: cmpwi 0,r3,0 /* parent or child? */ - bne 2f /* return if parent */ + cmpwi 0,r3,0 /* parent or child? */ + bne 1f /* return if parent */ li r0,0 /* make top-level stack frame */ stwu r0,-16(r1) mtlr r30 /* fn addr in lr */ @@ -913,7 +857,7 @@ _GLOBAL(kernel_thread) li r0,__NR_exit /* exit if function returns */ li r3,0 sc -2: lwz r30,8(r1) +1: lwz r30,8(r1) lwz r31,12(r1) addi r1,r1,16 blr diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 3053fe5c62f2..4dd70cf7bb4e 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -426,10 +426,8 @@ _GLOBAL(kernel_thread) li r4,0 /* new sp (unused) */ li r0,__NR_clone sc - bns+ 1f /* did system call indicate error? */ - neg r3,r3 /* if so, make return code negative */ -1: cmpdi 0,r3,0 /* parent or child? */ - bne 2f /* return if parent */ + cmpdi 0,r3,0 /* parent or child? */ + bne 1f /* return if parent */ li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) ld r2,8(r29) @@ -440,7 +438,7 @@ _GLOBAL(kernel_thread) li r0,__NR_exit /* exit after child exits */ li r3,0 sc -2: addi r1,r1,STACK_FRAME_OVERHEAD +1: addi r1,r1,STACK_FRAME_OVERHEAD ld r29,-24(r1) ld r30,-16(r1) blr diff --git a/trunk/arch/powerpc/kernel/of_device.c b/trunk/arch/powerpc/kernel/of_device.c index 93ae5b169f41..e9be908f199b 100644 --- a/trunk/arch/powerpc/kernel/of_device.c +++ b/trunk/arch/powerpc/kernel/of_device.c @@ -78,7 +78,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; - set_dev_node(&dev->dev, of_node_to_nid(np)); + dev->dev.archdata.numa_node = of_node_to_nid(np); if (bus_id) strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index 48a347133f41..c9bf17eec31b 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -12,7 +12,6 @@ #include #include -#include /* This symbol is provided by the linker - let it fill in the paca * field correctly */ @@ -80,8 +79,6 @@ void __init initialise_pacas(void) new_paca->lock_token = 0x8000; new_paca->paca_index = cpu; new_paca->kernel_toc = kernel_toc; - new_paca->kernelbase = (unsigned long) _stext; - new_paca->kernel_msr = MSR_KERNEL; new_paca->hw_cpu_id = 0xffff; new_paca->slb_shadow_ptr = &slb_shadow[cpu]; new_paca->__current = &init_task; diff --git a/trunk/arch/powerpc/kernel/pci-common.c b/trunk/arch/powerpc/kernel/pci-common.c index 01ce8c38bae6..ea0c61e09b76 100644 --- a/trunk/arch/powerpc/kernel/pci-common.c +++ b/trunk/arch/powerpc/kernel/pci-common.c @@ -56,34 +56,6 @@ resource_size_t isa_mem_base; /* Default PCI flags is 0 */ unsigned int ppc_pci_flags; -static struct dma_mapping_ops *pci_dma_ops; - -void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) -{ - pci_dma_ops = dma_ops; -} - -struct dma_mapping_ops *get_pci_dma_ops(void) -{ - return pci_dma_ops; -} -EXPORT_SYMBOL(get_pci_dma_ops); - -int pci_set_dma_mask(struct pci_dev *dev, u64 mask) -{ - return dma_set_mask(&dev->dev, mask); -} - -int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) -{ - int rc; - - rc = dma_set_mask(&dev->dev, mask); - dev->dev.coherent_dma_mask = dev->dma_mask; - - return rc; -} - struct pci_controller *pcibios_alloc_controller(struct device_node *dev) { struct pci_controller *phb; @@ -208,26 +180,6 @@ char __devinit *pcibios_setup(char *str) return str; } -void __devinit pcibios_setup_new_device(struct pci_dev *dev) -{ - struct dev_archdata *sd = &dev->dev.archdata; - - sd->of_node = pci_device_to_OF_node(dev); - - DBG("PCI: device %s OF node: %s\n", pci_name(dev), - sd->of_node ? sd->of_node->full_name : ""); - - sd->dma_ops = pci_dma_ops; -#ifdef CONFIG_PPC32 - sd->dma_data = (void *)PCI_DRAM_OFFSET; -#endif - set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); - - if (ppc_md.pci_dma_dev_setup) - ppc_md.pci_dma_dev_setup(dev); -} -EXPORT_SYMBOL(pcibios_setup_new_device); - /* * Reads the interrupt pin to determine if interrupt is use by card. * If the interrupt is used, then gets the interrupt line from the @@ -419,7 +371,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, struct pci_dev *pdev = NULL; struct resource *found = NULL; unsigned long prot = pgprot_val(protection); - resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; + unsigned long offset = pfn << PAGE_SHIFT; int i; if (page_is_ram(pfn)) @@ -470,8 +422,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - resource_size_t offset = - ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -780,6 +731,11 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) res->start = (res->start + offset) & mask; res->end = (res->end + offset) & mask; + + pr_debug("PCI:%s %016llx-%016llx\n", + pci_name(dev), + (unsigned long long)res->start, + (unsigned long long)res->end); } @@ -825,11 +781,6 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) (unsigned int)res->flags); fixup_resource(res, dev); - - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); } /* Call machine specific resource fixup */ @@ -838,127 +789,58 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); -/* This function tries to figure out if a bridge resource has been initialized - * by the firmware or not. It doesn't have to be absolutely bullet proof, but - * things go more smoothly when it gets it right. It should covers cases such - * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges - */ -static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus, - struct resource *res) +static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) { struct pci_controller *hose = pci_bus_to_host(bus); - struct pci_dev *dev = bus->self; - resource_size_t offset; - u16 command; - int i; - - /* We don't do anything if PCI_PROBE_ONLY is set */ - if (ppc_pci_flags & PPC_PCI_PROBE_ONLY) - return 0; - - /* Job is a bit different between memory and IO */ - if (res->flags & IORESOURCE_MEM) { - /* If the BAR is non-0 (res != pci_mem_offset) then it's probably been - * initialized by somebody - */ - if (res->start != hose->pci_mem_offset) - return 0; - - /* The BAR is 0, let's check if memory decoding is enabled on - * the bridge. If not, we consider it unassigned - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if ((command & PCI_COMMAND_MEMORY) == 0) - return 1; - - /* Memory decoding is enabled and the BAR is 0. If any of the bridge - * resources covers that starting address (0 then it's good enough for - * us for memory - */ - for (i = 0; i < 3; i++) { - if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && - hose->mem_resources[i].start == hose->pci_mem_offset) - return 0; - } - - /* Well, it starts at 0 and we know it will collide so we may as - * well consider it as unassigned. That covers the Apple case. - */ - return 1; - } else { - /* If the BAR is non-0, then we consider it assigned */ - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - if (((res->start - offset) & 0xfffffffful) != 0) - return 0; - - /* Here, we are a bit different than memory as typically IO space - * starting at low addresses -is- valid. What we do instead if that - * we consider as unassigned anything that doesn't have IO enabled - * in the PCI command register, and that's it. - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if (command & PCI_COMMAND_IO) - return 0; - - /* It's starting at 0 and IO is disabled in the bridge, consider - * it unassigned - */ - return 1; - } -} - -/* Fixup resources of a PCI<->PCI bridge */ -static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) -{ - struct resource *res; - int i; - struct pci_dev *dev = bus->self; - for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { - if ((res = bus->resource[i]) == NULL) - continue; - if (!res->flags) - continue; - if (i >= 3 && bus->self->transparent) - continue; + pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); - pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", - pci_name(dev), i, - (unsigned long long)res->start,\ - (unsigned long long)res->end, - (unsigned int)res->flags); + /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for + * now differently between 32 and 64 bits. + */ + if (dev != NULL) { + struct resource *res; + int i; - /* Perform fixup */ - fixup_resource(res, dev); + for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { + if ((res = bus->resource[i]) == NULL) + continue; + if (!res->flags) + continue; + if (i >= 3 && bus->self->transparent) + continue; + /* On PowerMac, Apple leaves bridge windows open over + * an inaccessible region of memory space (0...fffff) + * which is somewhat bogus, but that's what they think + * means disabled... + * + * We clear those to force them to be reallocated later + * + * We detect such regions by the fact that the base is + * equal to the pci_mem_offset of the host bridge and + * their size is smaller than 1M. + */ + if (res->flags & IORESOURCE_MEM && + res->start == hose->pci_mem_offset && + res->end < 0x100000) { + printk(KERN_INFO + "PCI: Closing bogus Apple Firmware" + " region %d on bus 0x%02x\n", + i, bus->number); + res->flags = 0; + continue; + } - /* Try to detect uninitialized P2P bridge resources, - * and clear them out so they get re-assigned later - */ - if (pcibios_uninitialized_bridge_resource(bus, res)) { - res->flags = 0; - pr_debug("PCI:%s (unassigned)\n", pci_name(dev)); - } else { + pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", + pci_name(dev), i, + (unsigned long long)res->start,\ + (unsigned long long)res->end, + (unsigned int)res->flags); - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); + fixup_resource(res, dev); } } -} - -static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_dev *dev = bus->self; - - pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); - - /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for - * now differently between 32 and 64 bits. - */ - if (dev != NULL) - pcibios_fixup_bridge(bus); /* Additional setup that is different between 32 and 64 bits for now */ pcibios_do_bus_setup(bus); diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index 131b1dfa68c6..88db4ffaf11c 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -53,19 +53,12 @@ LIST_HEAD(hose_list); static int pci_bus_count; -/* This will remain NULL for now, until isa-bridge.c is made common - * to both 32-bit and 64-bit. - */ -struct pci_dev *isa_bridge_pcidev; -EXPORT_SYMBOL_GPL(isa_bridge_pcidev); - static void -fixup_hide_host_resource_fsl(struct pci_dev *dev) +fixup_hide_host_resource_fsl(struct pci_dev* dev) { int i, class = dev->class >> 8; - if ((class == PCI_CLASS_PROCESSOR_POWERPC || - class == PCI_CLASS_BRIDGE_OTHER) && + if ((class == PCI_CLASS_PROCESSOR_POWERPC) && (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) && (dev->bus->parent == NULL)) { for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { @@ -431,7 +424,6 @@ void __devinit pcibios_do_bus_setup(struct pci_bus *bus) unsigned long io_offset; struct resource *res; int i; - struct pci_dev *dev; /* Hookup PHB resources */ io_offset = (unsigned long)hose->io_base_virt - isa_io_base; @@ -465,12 +457,6 @@ void __devinit pcibios_do_bus_setup(struct pci_bus *bus) bus->resource[i+1] = res; } } - - if (ppc_md.pci_dma_bus_setup) - ppc_md.pci_dma_bus_setup(bus); - - list_for_each_entry(dev, &bus->devices, bus_list) - pcibios_setup_new_device(dev); } /* the next one is stolen from the alpha port... */ diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 8247cff1cb3e..30eedfc5a566 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -52,6 +52,35 @@ EXPORT_SYMBOL(pci_io_base); LIST_HEAD(hose_list); +static struct dma_mapping_ops *pci_dma_ops; + +void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) +{ + pci_dma_ops = dma_ops; +} + +struct dma_mapping_ops *get_pci_dma_ops(void) +{ + return pci_dma_ops; +} +EXPORT_SYMBOL(get_pci_dma_ops); + + +int pci_set_dma_mask(struct pci_dev *dev, u64 mask) +{ + return dma_set_mask(&dev->dev, mask); +} + +int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) +{ + int rc; + + rc = dma_set_mask(&dev->dev, mask); + dev->dev.coherent_dma_mask = dev->dma_mask; + + return rc; +} + static void fixup_broken_pcnet32(struct pci_dev* dev) { if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { @@ -519,6 +548,26 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) } EXPORT_SYMBOL_GPL(pcibios_map_io_space); +void __devinit pcibios_setup_new_device(struct pci_dev *dev) +{ + struct dev_archdata *sd = &dev->dev.archdata; + + sd->of_node = pci_device_to_OF_node(dev); + + DBG("PCI: device %s OF node: %s\n", pci_name(dev), + sd->of_node ? sd->of_node->full_name : ""); + + sd->dma_ops = pci_dma_ops; +#ifdef CONFIG_NUMA + sd->numa_node = pcibus_to_node(dev->bus); +#else + sd->numa_node = -1; +#endif + if (ppc_md.pci_dma_dev_setup) + ppc_md.pci_dma_dev_setup(dev); +} +EXPORT_SYMBOL(pcibios_setup_new_device); + void __devinit pcibios_do_bus_setup(struct pci_bus *bus) { struct pci_dev *dev; diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index 8edc2359c419..e1ea4fe5cfbd 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -119,9 +119,6 @@ EXPORT_SYMBOL(flush_instruction_cache); EXPORT_SYMBOL(flush_tlb_kernel_range); EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(_tlbie); -#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE) -EXPORT_SYMBOL(_tlbil_va); -#endif #endif EXPORT_SYMBOL(__flush_icache_range); EXPORT_SYMBOL(flush_dcache_range); diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 3a2dc7e6586a..87d83c56b31e 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -888,10 +888,9 @@ static u64 __init dt_mem_next_cell(int s, cell_t **cellp) */ static int __init early_init_dt_scan_drconf_memory(unsigned long node) { - cell_t *dm, *ls, *usm; + cell_t *dm, *ls; unsigned long l, n, flags; u64 base, size, lmb_size; - unsigned int is_kexec_kdump = 0, rngs; ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l); if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t)) @@ -906,12 +905,6 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node) if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t)) return 0; - /* check if this is a kexec/kdump kernel. */ - usm = (cell_t *)of_get_flat_dt_prop(node, "linux,drconf-usable-memory", - &l); - if (usm != NULL) - is_kexec_kdump = 1; - for (; n != 0; --n) { base = dt_mem_next_cell(dt_root_addr_cells, &dm); flags = dm[3]; @@ -922,34 +915,13 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node) if ((flags & 0x80) || !(flags & 0x8)) continue; size = lmb_size; - rngs = 1; - if (is_kexec_kdump) { - /* - * For each lmb in ibm,dynamic-memory, a corresponding - * entry in linux,drconf-usable-memory property contains - * a counter 'p' followed by 'p' (base, size) duple. - * Now read the counter from - * linux,drconf-usable-memory property - */ - rngs = dt_mem_next_cell(dt_root_size_cells, &usm); - if (!rngs) /* there are no (base, size) duple */ + if (iommu_is_off) { + if (base >= 0x80000000ul) continue; + if ((base + size) > 0x80000000ul) + size = 0x80000000ul - base; } - do { - if (is_kexec_kdump) { - base = dt_mem_next_cell(dt_root_addr_cells, - &usm); - size = dt_mem_next_cell(dt_root_size_cells, - &usm); - } - if (iommu_is_off) { - if (base >= 0x80000000ul) - continue; - if ((base + size) > 0x80000000ul) - size = 0x80000000ul - base; - } - lmb_add(base, size); - } while (--rngs); + lmb_add(base, size); } lmb_dump_all(); return 0; @@ -1192,9 +1164,6 @@ void __init early_init_devtree(void *params) /* Reserve LMB regions used by kernel, initrd, dt, etc... */ lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); - /* If relocatable, reserve first 32k for interrupt vectors etc. */ - if (PHYSICAL_START > MEMORY_START) - lmb_reserve(MEMORY_START, 0x8000); reserve_kdump_trampoline(); reserve_crashkernel(); early_reserve_mem(); diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 2fdbc18ae94a..b72849ac7db3 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -732,7 +732,7 @@ static struct fake_elf { u32 ignore_me; } rpadesc; } rpanote; -} fake_elf __section(.fakeelf) = { +} fake_elf = { .elfhdr = { .e_ident = { 0x7f, 'E', 'L', 'F', ELFCLASS32, ELFDATA2MSB, EV_CURRENT }, @@ -774,13 +774,13 @@ static struct fake_elf { .type = 0x12759999, .name = "IBM,RPA-Client-Config", .rpadesc = { - .lpar_affinity = 1, - .min_rmo_size = 128, /* in megabytes */ + .lpar_affinity = 0, + .min_rmo_size = 64, /* in megabytes */ .min_rmo_percent = 0, - .max_pft_size = 46, /* 2^46 bytes max PFT size */ + .max_pft_size = 48, /* 2^48 bytes max PFT size */ .splpar = 1, .min_load = ~0U, - .new_mem_def = 1 + .new_mem_def = 0 } } }; @@ -1321,7 +1321,7 @@ static void __init prom_initialize_tce_table(void) * * -- Cort */ -extern char __secondary_hold; +extern void __secondary_hold(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; @@ -1342,7 +1342,13 @@ static void __init prom_hold_cpus(void) = (void *) LOW_ADDR(__secondary_hold_spinloop); unsigned long *acknowledge = (void *) LOW_ADDR(__secondary_hold_acknowledge); +#ifdef CONFIG_PPC64 + /* __secondary_hold is actually a descriptor, not the text address */ + unsigned long secondary_hold + = __pa(*PTRRELOC((unsigned long *)__secondary_hold)); +#else unsigned long secondary_hold = LOW_ADDR(__secondary_hold); +#endif prom_debug("prom_hold_cpus: start...\n"); prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); @@ -2309,14 +2315,13 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long pp, - unsigned long r6, unsigned long r7, - unsigned long kbase) + unsigned long r6, unsigned long r7) { struct prom_t *_prom; unsigned long hdr; + unsigned long offset = reloc_offset(); #ifdef CONFIG_PPC32 - unsigned long offset = reloc_offset(); reloc_got2(offset); #endif @@ -2350,11 +2355,9 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ RELOC(of_platform) = prom_find_machine_type(); -#ifndef CONFIG_RELOCATABLE /* Bail if this is a kdump kernel. */ if (PHYSICAL_START > 0) prom_panic("Error: You can't boot a kdump kernel from OF!\n"); -#endif /* * Check for an initrd @@ -2374,7 +2377,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, * Copy the CPU hold code */ if (RELOC(of_platform) != PLATFORM_POWERMAC) - copy_and_flush(0, kbase, 0x100, 0); + copy_and_flush(0, KERNELBASE + offset, 0x100, 0); /* * Do early parsing of command line @@ -2477,7 +2480,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, reloc_got2(-offset); #endif - __start(hdr, kbase, 0); + __start(hdr, KERNELBASE + offset, 0); return 0; } diff --git a/trunk/arch/powerpc/kernel/reloc_64.S b/trunk/arch/powerpc/kernel/reloc_64.S deleted file mode 100644 index b47a0e1ab001..000000000000 --- a/trunk/arch/powerpc/kernel/reloc_64.S +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Code to process dynamic relocations in the kernel. - * - * Copyright 2008 Paul Mackerras, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include - -RELA = 7 -RELACOUNT = 0x6ffffff9 -R_PPC64_RELATIVE = 22 - -/* - * r3 = desired final address of kernel - */ -_GLOBAL(relocate) - mflr r0 - bcl 20,31,$+4 -0: mflr r12 /* r12 has runtime addr of label 0 */ - mtlr r0 - ld r11,(p_dyn - 0b)(r12) - add r11,r11,r12 /* r11 has runtime addr of .dynamic section */ - ld r9,(p_rela - 0b)(r12) - add r9,r9,r12 /* r9 has runtime addr of .rela.dyn section */ - ld r10,(p_st - 0b)(r12) - add r10,r10,r12 /* r10 has runtime addr of _stext */ - - /* - * Scan the dynamic section for the RELA and RELACOUNT entries. - */ - li r7,0 - li r8,0 -1: ld r6,0(r11) /* get tag */ - cmpdi r6,0 - beq 4f /* end of list */ - cmpdi r6,RELA - bne 2f - ld r7,8(r11) /* get RELA pointer in r7 */ - b 3f -2: addis r6,r6,(-RELACOUNT)@ha - cmpdi r6,RELACOUNT@l - bne 3f - ld r8,8(r11) /* get RELACOUNT value in r8 */ -3: addi r11,r11,16 - b 1b -4: cmpdi r7,0 /* check we have both RELA and RELACOUNT */ - cmpdi cr1,r8,0 - beq 6f - beq cr1,6f - - /* - * Work out linktime address of _stext and hence the - * relocation offset to be applied. - * cur_offset [r7] = rela.run [r9] - rela.link [r7] - * _stext.link [r10] = _stext.run [r10] - cur_offset [r7] - * final_offset [r3] = _stext.final [r3] - _stext.link [r10] - */ - subf r7,r7,r9 /* cur_offset */ - subf r10,r7,r10 - subf r3,r10,r3 /* final_offset */ - - /* - * Run through the list of relocations and process the - * R_PPC64_RELATIVE ones. - */ - mtctr r8 -5: lwz r0,12(9) /* ELF64_R_TYPE(reloc->r_info) */ - cmpwi r0,R_PPC64_RELATIVE - bne 6f - ld r6,0(r9) /* reloc->r_offset */ - ld r0,16(r9) /* reloc->r_addend */ - add r0,r0,r3 - stdx r0,r7,r6 - addi r9,r9,24 - bdnz 5b - -6: blr - -p_dyn: .llong __dynamic_start - 0b -p_rela: .llong __rela_dyn_start - 0b -p_st: .llong _stext - 0b - diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index 5ec56ff03e86..9cc5a52711e5 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -254,21 +254,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* If we are a Freescale core do a simple check so * we dont have to keep adding cases in the future */ if (PVR_VER(pvr) & 0x8000) { - switch (PVR_VER(pvr)) { - case 0x8000: /* 7441/7450/7451, Voyager */ - case 0x8001: /* 7445/7455, Apollo 6 */ - case 0x8002: /* 7447/7457, Apollo 7 */ - case 0x8003: /* 7447A, Apollo 7 PM */ - case 0x8004: /* 7448, Apollo 8 */ - case 0x800c: /* 7410, Nitro */ - maj = ((pvr >> 8) & 0xF); - min = PVR_MIN(pvr); - break; - default: /* e500/book-e */ - maj = PVR_MAJ(pvr); - min = PVR_MIN(pvr); - break; - } + maj = PVR_MAJ(pvr); + min = PVR_MIN(pvr); } else { switch (PVR_VER(pvr)) { case 0x0020: /* 403 family */ diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index c1a27626a940..066e65c59b58 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -111,7 +111,7 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) * This is called very early on the boot process, after a minimal * MMU environment has been set up but before MMU_init is called. */ -notrace void __init machine_init(unsigned long dt_ptr) +notrace void __init machine_init(unsigned long dt_ptr, unsigned long phys) { /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); @@ -209,12 +209,23 @@ EXPORT_SYMBOL(nvram_sync); #endif /* CONFIG_NVRAM */ +static DEFINE_PER_CPU(struct cpu, cpu_devices); + int __init ppc_init(void) { + int cpu; + /* clear the progress line */ if (ppc_md.progress) ppc_md.progress(" ", 0xffff); + /* register CPU devices */ + for_each_possible_cpu(cpu) { + struct cpu *c = &per_cpu(cpu_devices, cpu); + c->hotpluggable = 1; + register_cpu(c, cpu); + } + /* call platform init */ if (ppc_md.init != NULL) { ppc_md.init(); diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 843c0af210d0..8b25f51f03bf 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -255,11 +255,9 @@ void early_setup_secondary(void) #endif /* CONFIG_SMP */ #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) -extern unsigned long __secondary_hold_spinloop; -extern void generic_secondary_smp_init(void); - void smp_release_cpus(void) { + extern unsigned long __secondary_hold_spinloop; unsigned long *ptr; DBG(" -> smp_release_cpus()\n"); @@ -268,11 +266,12 @@ void smp_release_cpus(void) * all now so they can start to spin on their individual paca * spinloops. For non SMP kernels, the secondary cpus never get out * of the common spinloop. - */ + * This is useless but harmless on iSeries, secondaries are already + * waiting on their paca spinloops. */ ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop - PHYSICAL_START); - *ptr = __pa(generic_secondary_smp_init); + *ptr = 1; mb(); DBG(" <- smp_release_cpus()\n"); diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index ff9f7010097d..c27b10a1bd79 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -101,7 +101,8 @@ void smp_message_recv(int msg) generic_smp_call_function_interrupt(); break; case PPC_MSG_RESCHEDULE: - /* we notice need_resched on exit */ + /* XXX Do we have to do this? */ + set_need_resched(); break; case PPC_MSG_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); diff --git a/trunk/arch/powerpc/kernel/softemu8xx.c b/trunk/arch/powerpc/kernel/softemu8xx.c index 23c8c5e7dc4d..c906c4bf6835 100644 --- a/trunk/arch/powerpc/kernel/softemu8xx.c +++ b/trunk/arch/powerpc/kernel/softemu8xx.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/powerpc/kernel/swsusp_asm64.S b/trunk/arch/powerpc/kernel/swsusp_asm64.S index 86ac1d90d02b..e092c3cbdb9b 100644 --- a/trunk/arch/powerpc/kernel/swsusp_asm64.S +++ b/trunk/arch/powerpc/kernel/swsusp_asm64.S @@ -133,7 +133,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) cmpdi r12,0 beq- nothing_to_copy - li r15,PAGE_SIZE>>3 + li r15,512 copyloop: ld r13,pbe_address(r12) ld r14,pbe_orig_address(r12) diff --git a/trunk/arch/powerpc/kernel/sys_ppc32.c b/trunk/arch/powerpc/kernel/sys_ppc32.c index bb1cfcfdbbbb..d98634c76060 100644 --- a/trunk/arch/powerpc/kernel/sys_ppc32.c +++ b/trunk/arch/powerpc/kernel/sys_ppc32.c @@ -61,6 +61,42 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); } +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) +{ + compat_ino_t ino; + long err; + + if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || + !new_valid_dev(stat->rdev)) + return -EOVERFLOW; + + ino = stat->ino; + if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) + return -EOVERFLOW; + + err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; + err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); + err |= __put_user(ino, &statbuf->st_ino); + err |= __put_user(stat->mode, &statbuf->st_mode); + err |= __put_user(stat->nlink, &statbuf->st_nlink); + err |= __put_user(stat->uid, &statbuf->st_uid); + err |= __put_user(stat->gid, &statbuf->st_gid); + err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev); + err |= __put_user(stat->size, &statbuf->st_size); + err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime); + err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); + err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime); + err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); + err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime); + err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); + err |= __put_user(stat->blksize, &statbuf->st_blksize); + err |= __put_user(stat->blocks, &statbuf->st_blocks); + err |= __put_user(0, &statbuf->__unused4[0]); + err |= __put_user(0, &statbuf->__unused4[1]); + + return err; +} + /* Note: it is necessary to treat option as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) @@ -71,6 +107,77 @@ asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2) return sys_sysfs((int)option, arg1, arg2); } +asmlinkage long compat_sys_pause(void) +{ + current->state = TASK_INTERRUPTIBLE; + schedule(); + + return -ERESTARTNOHAND; +} + +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) +{ + long usec; + + if (!access_ok(VERIFY_READ, i, sizeof(*i))) + return -EFAULT; + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + +static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) +{ + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || + (__put_user(i->tv_sec, &o->tv_sec) | + __put_user(i->tv_usec, &o->tv_usec))); +} + + + + +/* Translations due to time_t size differences. Which affects all + sorts of things, like timeval and itimerval. */ +extern struct timezone sys_tz; + +asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + if (tv) { + struct timeval ktv; + do_gettimeofday(&ktv); + if (put_tv32(tv, &ktv)) + return -EFAULT; + } + if (tz) { + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + + return 0; +} + + + +asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_ts32(&kts, tv)) + return -EFAULT; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + #ifdef CONFIG_SYSVIPC long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth) diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index 86a2ffccef25..56d172d16e56 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -15,24 +15,18 @@ #include #include #include -#include -#include - -#ifdef CONFIG_PPC64 #include #include -#endif +#include +#include static DEFINE_PER_CPU(struct cpu, cpu_devices); static DEFINE_PER_CPU(struct kobject *, cache_toplevel); -/* - * SMT snooze delay stuff, 64-bit only for now - */ - -#ifdef CONFIG_PPC64 +/* SMT stuff */ +#ifdef CONFIG_PPC_MULTIPLATFORM /* Time in microseconds we delay before sleeping in the idle loop */ DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 }; @@ -112,7 +106,7 @@ static int __init setup_smt_snooze_delay(char *str) } __setup("smt-snooze-delay=", setup_smt_snooze_delay); -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ /* * Enabling PMCs will slow partition context switch times so we only do @@ -121,7 +115,7 @@ __setup("smt-snooze-delay=", setup_smt_snooze_delay); static DEFINE_PER_CPU(char, pmcs_enabled); -void ppc_enable_pmcs(void) +void ppc64_enable_pmcs(void) { /* Only need to enable them once */ if (__get_cpu_var(pmcs_enabled)) @@ -132,9 +126,8 @@ void ppc_enable_pmcs(void) if (ppc_md.enable_pmcs) ppc_md.enable_pmcs(); } -EXPORT_SYMBOL(ppc_enable_pmcs); +EXPORT_SYMBOL(ppc64_enable_pmcs); -#if defined(CONFIG_6xx) || defined(CONFIG_PPC64) /* XXX convert to rusty's on_one_cpu */ static unsigned long run_on_cpu(unsigned long cpu, unsigned long (*func)(unsigned long), @@ -153,7 +146,6 @@ static unsigned long run_on_cpu(unsigned long cpu, return ret; } -#endif #define SYSFS_PMCSETUP(NAME, ADDRESS) \ static unsigned long read_##NAME(unsigned long junk) \ @@ -162,7 +154,7 @@ static unsigned long read_##NAME(unsigned long junk) \ } \ static unsigned long write_##NAME(unsigned long val) \ { \ - ppc_enable_pmcs(); \ + ppc64_enable_pmcs(); \ mtspr(ADDRESS, val); \ return 0; \ } \ @@ -192,53 +184,28 @@ static ssize_t __used \ * that are implemented on the current processor */ -#if defined(CONFIG_PPC64) -#define HAS_PPC_PMC_CLASSIC 1 -#define HAS_PPC_PMC_IBM 1 -#define HAS_PPC_PMC_PA6T 1 -#elif defined(CONFIG_6xx) -#define HAS_PPC_PMC_CLASSIC 1 -#define HAS_PPC_PMC_IBM 1 -#define HAS_PPC_PMC_G4 1 -#endif - - -#ifdef HAS_PPC_PMC_CLASSIC SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); +SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); SYSFS_PMCSETUP(pmc1, SPRN_PMC1); SYSFS_PMCSETUP(pmc2, SPRN_PMC2); SYSFS_PMCSETUP(pmc3, SPRN_PMC3); SYSFS_PMCSETUP(pmc4, SPRN_PMC4); SYSFS_PMCSETUP(pmc5, SPRN_PMC5); SYSFS_PMCSETUP(pmc6, SPRN_PMC6); - -#ifdef HAS_PPC_PMC_G4 -SYSFS_PMCSETUP(mmcr2, SPRN_MMCR2); -#endif - -#ifdef CONFIG_PPC64 SYSFS_PMCSETUP(pmc7, SPRN_PMC7); SYSFS_PMCSETUP(pmc8, SPRN_PMC8); - -SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); SYSFS_PMCSETUP(purr, SPRN_PURR); SYSFS_PMCSETUP(spurr, SPRN_SPURR); SYSFS_PMCSETUP(dscr, SPRN_DSCR); -static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); -static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); -static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); -static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); -#endif /* CONFIG_PPC64 */ - -#ifdef HAS_PPC_PMC_PA6T SYSFS_PMCSETUP(pa6t_pmc0, SPRN_PA6T_PMC0); SYSFS_PMCSETUP(pa6t_pmc1, SPRN_PA6T_PMC1); SYSFS_PMCSETUP(pa6t_pmc2, SPRN_PA6T_PMC2); SYSFS_PMCSETUP(pa6t_pmc3, SPRN_PA6T_PMC3); SYSFS_PMCSETUP(pa6t_pmc4, SPRN_PA6T_PMC4); SYSFS_PMCSETUP(pa6t_pmc5, SPRN_PA6T_PMC5); + #ifdef CONFIG_DEBUG_KERNEL SYSFS_PMCSETUP(hid0, SPRN_HID0); SYSFS_PMCSETUP(hid1, SPRN_HID1); @@ -269,37 +236,28 @@ SYSFS_PMCSETUP(tsr1, SPRN_PA6T_TSR1); SYSFS_PMCSETUP(tsr2, SPRN_PA6T_TSR2); SYSFS_PMCSETUP(tsr3, SPRN_PA6T_TSR3); #endif /* CONFIG_DEBUG_KERNEL */ -#endif /* HAS_PPC_PMC_PA6T */ -#ifdef HAS_PPC_PMC_IBM -static struct sysdev_attribute ibm_common_attrs[] = { - _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), - _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), -}; -#endif /* HAS_PPC_PMC_G4 */ +static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); +static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); +static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); +static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); -#ifdef HAS_PPC_PMC_G4 -static struct sysdev_attribute g4_common_attrs[] = { +static struct sysdev_attribute ibm_common_attrs[] = { _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), - _SYSDEV_ATTR(mmcr2, 0600, show_mmcr2, store_mmcr2), }; -#endif /* HAS_PPC_PMC_G4 */ -static struct sysdev_attribute classic_pmc_attrs[] = { +static struct sysdev_attribute ibm_pmc_attrs[] = { _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1), _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2), _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3), _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4), _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5), _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6), -#ifdef CONFIG_PPC64 _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7), _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8), -#endif }; -#ifdef HAS_PPC_PMC_PA6T static struct sysdev_attribute pa6t_attrs[] = { _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), @@ -340,8 +298,6 @@ static struct sysdev_attribute pa6t_attrs[] = { _SYSDEV_ATTR(tsr3, 0600, show_tsr3, store_tsr3), #endif /* CONFIG_DEBUG_KERNEL */ }; -#endif /* HAS_PPC_PMC_PA6T */ -#endif /* HAS_PPC_PMC_CLASSIC */ struct cache_desc { struct kobject kobj; @@ -632,36 +588,23 @@ static void __cpuinit register_cpu_online(unsigned int cpu) struct sysdev_attribute *attrs, *pmc_attrs; int i, nattrs; -#ifdef CONFIG_PPC64 if (!firmware_has_feature(FW_FEATURE_ISERIES) && cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_smt_snooze_delay); -#endif /* PMC stuff */ switch (cur_cpu_spec->pmc_type) { -#ifdef HAS_PPC_PMC_IBM case PPC_PMC_IBM: attrs = ibm_common_attrs; nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = classic_pmc_attrs; + pmc_attrs = ibm_pmc_attrs; break; -#endif /* HAS_PPC_PMC_IBM */ -#ifdef HAS_PPC_PMC_G4 - case PPC_PMC_G4: - attrs = g4_common_attrs; - nattrs = sizeof(g4_common_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = classic_pmc_attrs; - break; -#endif /* HAS_PPC_PMC_G4 */ -#ifdef HAS_PPC_PMC_PA6T case PPC_PMC_PA6T: /* PA Semi starts counting at PMC0 */ attrs = pa6t_attrs; nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); pmc_attrs = NULL; break; -#endif /* HAS_PPC_PMC_PA6T */ default: attrs = NULL; nattrs = 0; @@ -675,7 +618,6 @@ static void __cpuinit register_cpu_online(unsigned int cpu) for (i = 0; i < cur_cpu_spec->num_pmcs; i++) sysdev_create_file(s, &pmc_attrs[i]); -#ifdef CONFIG_PPC64 if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_create_file(s, &attr_mmcra); @@ -687,7 +629,6 @@ static void __cpuinit register_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_DSCR)) sysdev_create_file(s, &attr_dscr); -#endif /* CONFIG_PPC64 */ create_cache_info(s); } @@ -700,9 +641,16 @@ static void remove_cache_info(struct sys_device *sysdev) int cpu = sysdev->id; cache_desc = per_cpu(cache_desc, cpu); - if (cache_desc != NULL) - kobject_put(&cache_desc->kobj); + if (cache_desc != NULL) { + sysfs_remove_file(&cache_desc->kobj, &cache_size_attr.attr); + sysfs_remove_file(&cache_desc->kobj, &cache_line_size_attr.attr); + sysfs_remove_file(&cache_desc->kobj, &cache_type_attr.attr); + sysfs_remove_file(&cache_desc->kobj, &cache_level_attr.attr); + sysfs_remove_file(&cache_desc->kobj, &cache_nr_sets_attr.attr); + sysfs_remove_file(&cache_desc->kobj, &cache_assoc_attr.attr); + kobject_put(&cache_desc->kobj); + } cache_toplevel = per_cpu(cache_toplevel, cpu); if (cache_toplevel != NULL) kobject_put(cache_toplevel); @@ -723,28 +671,17 @@ static void unregister_cpu_online(unsigned int cpu) /* PMC stuff */ switch (cur_cpu_spec->pmc_type) { -#ifdef HAS_PPC_PMC_IBM case PPC_PMC_IBM: attrs = ibm_common_attrs; nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = classic_pmc_attrs; - break; -#endif /* HAS_PPC_PMC_IBM */ -#ifdef HAS_PPC_PMC_G4 - case PPC_PMC_G4: - attrs = g4_common_attrs; - nattrs = sizeof(g4_common_attrs) / sizeof(struct sysdev_attribute); - pmc_attrs = classic_pmc_attrs; + pmc_attrs = ibm_pmc_attrs; break; -#endif /* HAS_PPC_PMC_G4 */ -#ifdef HAS_PPC_PMC_PA6T case PPC_PMC_PA6T: /* PA Semi starts counting at PMC0 */ attrs = pa6t_attrs; nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); pmc_attrs = NULL; break; -#endif /* HAS_PPC_PMC_PA6T */ default: attrs = NULL; nattrs = 0; @@ -758,7 +695,6 @@ static void unregister_cpu_online(unsigned int cpu) for (i = 0; i < cur_cpu_spec->num_pmcs; i++) sysdev_remove_file(s, &pmc_attrs[i]); -#ifdef CONFIG_PPC64 if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_remove_file(s, &attr_mmcra); @@ -770,7 +706,6 @@ static void unregister_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_DSCR)) sysdev_remove_file(s, &attr_dscr); -#endif /* CONFIG_PPC64 */ remove_cache_info(s); } diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index f5def6cf5cd6..81ccb8dd1a54 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index 434c92a85c03..2750fbab1975 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -1232,7 +1232,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) else viodev->dev.archdata.dma_ops = &dma_iommu_ops; viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); - set_dev_node(&viodev->dev, of_node_to_nid(of_node)); + viodev->dev.archdata.numa_node = of_node_to_nid(of_node); /* init generic 'struct device' fields: */ viodev->dev.parent = &vio_bus_device.dev; diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index b39c27ed7919..9f6c1ca1739e 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -187,24 +187,6 @@ SECTIONS *(.machine.desc) __machine_desc_end = . ; } - . = ALIGN(8); - .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) { *(.dynsym) } - .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) } - .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET) - { - __dynamic_start = .; - *(.dynamic) - } - .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) } - .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) } - .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET) - { - __rela_dyn_start = .; - *(.rela*) - } - - /* Fake ELF header containing RPA note; for addnote */ - .fakeelf : AT(ADDR(.fakeelf) - LOAD_OFFSET) { *(.fakeelf) } /* freed after init ends here */ . = ALIGN(PAGE_SIZE); diff --git a/trunk/arch/powerpc/lib/copypage_64.S b/trunk/arch/powerpc/lib/copypage_64.S index 75f3267fdc30..f9837f44ac0b 100644 --- a/trunk/arch/powerpc/lib/copypage_64.S +++ b/trunk/arch/powerpc/lib/copypage_64.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Mark Nelson, IBM Corp. + * Copyright (C) 2002 Paul Mackerras, IBM Corp. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -8,100 +8,112 @@ */ #include #include -#include - - .section ".toc","aw" -PPC64_CACHES: - .tc ppc64_caches[TC],ppc64_caches - .section ".text" - _GLOBAL(copy_4K_page) - li r5,4096 /* 4K page size */ -BEGIN_FTR_SECTION - ld r10,PPC64_CACHES@toc(r2) - lwz r11,DCACHEL1LOGLINESIZE(r10) /* log2 of cache line size */ - lwz r12,DCACHEL1LINESIZE(r10) /* get cache line size */ - li r9,0 - srd r8,r5,r11 - - mtctr r8 -setup: - dcbt r9,r4 - dcbz r9,r3 - add r9,r9,r12 - bdnz setup -END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ) + std r31,-8(1) + std r30,-16(1) + std r29,-24(1) + std r28,-32(1) + std r27,-40(1) + std r26,-48(1) + std r25,-56(1) + std r24,-64(1) + std r23,-72(1) + std r22,-80(1) + std r21,-88(1) + std r20,-96(1) + li r5,4096/32 - 1 addi r3,r3,-8 - srdi r8,r5,7 /* page is copied in 128 byte strides */ - addi r8,r8,-1 /* one stride copied outside loop */ - - mtctr r8 - - ld r5,0(r4) - ld r6,8(r4) - ld r7,16(r4) - ldu r8,24(r4) -1: std r5,8(r3) - ld r9,8(r4) - std r6,16(r3) - ld r10,16(r4) - std r7,24(r3) - ld r11,24(r4) - std r8,32(r3) - ld r12,32(r4) - std r9,40(r3) - ld r5,40(r4) - std r10,48(r3) - ld r6,48(r4) - std r11,56(r3) - ld r7,56(r4) - std r12,64(r3) - ld r8,64(r4) - std r5,72(r3) - ld r9,72(r4) - std r6,80(r3) - ld r10,80(r4) - std r7,88(r3) - ld r11,88(r4) - std r8,96(r3) - ld r12,96(r4) - std r9,104(r3) - ld r5,104(r4) - std r10,112(r3) - ld r6,112(r4) - std r11,120(r3) - ld r7,120(r4) - stdu r12,128(r3) - ldu r8,128(r4) + li r12,5 +0: addi r5,r5,-24 + mtctr r12 + ld r22,640(4) + ld r21,512(4) + ld r20,384(4) + ld r11,256(4) + ld r9,128(4) + ld r7,0(4) + ld r25,648(4) + ld r24,520(4) + ld r23,392(4) + ld r10,264(4) + ld r8,136(4) + ldu r6,8(4) + cmpwi r5,24 +1: std r22,648(3) + std r21,520(3) + std r20,392(3) + std r11,264(3) + std r9,136(3) + std r7,8(3) + ld r28,648(4) + ld r27,520(4) + ld r26,392(4) + ld r31,264(4) + ld r30,136(4) + ld r29,8(4) + std r25,656(3) + std r24,528(3) + std r23,400(3) + std r10,272(3) + std r8,144(3) + std r6,16(3) + ld r22,656(4) + ld r21,528(4) + ld r20,400(4) + ld r11,272(4) + ld r9,144(4) + ld r7,16(4) + std r28,664(3) + std r27,536(3) + std r26,408(3) + std r31,280(3) + std r30,152(3) + stdu r29,24(3) + ld r25,664(4) + ld r24,536(4) + ld r23,408(4) + ld r10,280(4) + ld r8,152(4) + ldu r6,24(4) bdnz 1b - - std r5,8(r3) - ld r9,8(r4) - std r6,16(r3) - ld r10,16(r4) - std r7,24(r3) - ld r11,24(r4) - std r8,32(r3) - ld r12,32(r4) - std r9,40(r3) - ld r5,40(r4) - std r10,48(r3) - ld r6,48(r4) - std r11,56(r3) - ld r7,56(r4) - std r12,64(r3) - ld r8,64(r4) - std r5,72(r3) - ld r9,72(r4) - std r6,80(r3) - ld r10,80(r4) - std r7,88(r3) - ld r11,88(r4) - std r8,96(r3) - ld r12,96(r4) - std r9,104(r3) - std r10,112(r3) - std r11,120(r3) - std r12,128(r3) + std r22,648(3) + std r21,520(3) + std r20,392(3) + std r11,264(3) + std r9,136(3) + std r7,8(3) + addi r4,r4,640 + addi r3,r3,648 + bge 0b + mtctr r5 + ld r7,0(4) + ld r8,8(4) + ldu r9,16(4) +3: ld r10,8(4) + std r7,8(3) + ld r7,16(4) + std r8,16(3) + ld r8,24(4) + std r9,24(3) + ldu r9,32(4) + stdu r10,32(3) + bdnz 3b +4: ld r10,8(4) + std r7,8(3) + std r8,16(3) + std r9,24(3) + std r10,32(3) +9: ld r20,-96(1) + ld r21,-88(1) + ld r22,-80(1) + ld r23,-72(1) + ld r24,-64(1) + ld r25,-56(1) + ld r26,-48(1) + ld r27,-40(1) + ld r28,-32(1) + ld r29,-24(1) + ld r30,-16(1) + ld r31,-8(1) blr diff --git a/trunk/arch/powerpc/lib/dma-noncoherent.c b/trunk/arch/powerpc/lib/dma-noncoherent.c index 31734c0969cd..5d83907f6591 100644 --- a/trunk/arch/powerpc/lib/dma-noncoherent.c +++ b/trunk/arch/powerpc/lib/dma-noncoherent.c @@ -203,7 +203,7 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp) /* * Set the "dma handle" */ - *handle = page_to_phys(page); + *handle = page_to_bus(page); do { BUG_ON(!pte_none(*pte)); diff --git a/trunk/arch/powerpc/math-emu/Makefile b/trunk/arch/powerpc/math-emu/Makefile index 03aa98dd9f0a..29bc9126241b 100644 --- a/trunk/arch/powerpc/math-emu/Makefile +++ b/trunk/arch/powerpc/math-emu/Makefile @@ -4,14 +4,13 @@ obj-y := math.o fmr.o lfd.o stfd.o obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \ fctiw.o fctiwz.o fdiv.o fdivs.o \ fmadd.o fmadds.o fmsub.o fmsubs.o \ - fmul.o fmuls.o fnabs.o fneg.o \ + fmul.o fmuls.o fnabs.o fneg.o types.o \ fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \ fres.o frsp.o frsqrte.o fsel.o lfs.o \ fsqrt.o fsqrts.o fsub.o fsubs.o \ mcrfs.o mffs.o mtfsb0.o mtfsb1.o \ - mtfsf.o mtfsfi.o stfiwx.o stfs.o + mtfsf.o mtfsfi.o stfiwx.o stfs.o \ + udivmodti4.o CFLAGS_fabs.o = -fno-builtin-fabs CFLAGS_math.o = -fno-builtin-fabs - -EXTRA_CFLAGS = -I. -Iinclude/math-emu -w diff --git a/trunk/arch/powerpc/math-emu/double.h b/trunk/arch/powerpc/math-emu/double.h new file mode 100644 index 000000000000..ffba8b67f059 --- /dev/null +++ b/trunk/arch/powerpc/math-emu/double.h @@ -0,0 +1,129 @@ +/* + * Definitions for IEEE Double Precision + */ + +#if _FP_W_TYPE_SIZE < 32 +#error "Here's a nickel kid. Go buy yourself a real computer." +#endif + +#if _FP_W_TYPE_SIZE < 64 +#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) +#else +#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE +#endif + +#define _FP_FRACBITS_D 53 +#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) +#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) +#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) +#define _FP_EXPBITS_D 11 +#define _FP_EXPBIAS_D 1023 +#define _FP_EXPMAX_D 2047 + +#define _FP_QNANBIT_D \ + ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)) +#define _FP_IMPLBIT_D \ + ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)) +#define _FP_OVERFLOW_D \ + ((_FP_W_TYPE)1 << (_FP_WFRACBITS_D % _FP_W_TYPE_SIZE)) + +#if _FP_W_TYPE_SIZE < 64 + +union _FP_UNION_D +{ + double flt; + struct { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned sign : 1; + unsigned exp : _FP_EXPBITS_D; + unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; + unsigned frac0 : _FP_W_TYPE_SIZE; +#else + unsigned frac0 : _FP_W_TYPE_SIZE; + unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; + unsigned exp : _FP_EXPBITS_D; + unsigned sign : 1; +#endif + } bits __attribute__((packed)); +}; + +#define FP_DECL_D(X) _FP_DECL(2,X) +#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) +#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) + +#define FP_UNPACK_D(X,val) \ + do { \ + _FP_UNPACK_RAW_2(D,X,val); \ + _FP_UNPACK_CANONICAL(D,2,X); \ + } while (0) + +#define FP_PACK_D(val,X) \ + do { \ + _FP_PACK_CANONICAL(D,2,X); \ + _FP_PACK_RAW_2(D,val,X); \ + } while (0) + +#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) +#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) +#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) +#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) +#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) +#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) + +#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) +#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) + +#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) +#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) + +#else + +union _FP_UNION_D +{ + double flt; + struct { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned sign : 1; + unsigned exp : _FP_EXPBITS_D; + unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); +#else + unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); + unsigned exp : _FP_EXPBITS_D; + unsigned sign : 1; +#endif + } bits __attribute__((packed)); +}; + +#define FP_DECL_D(X) _FP_DECL(1,X) +#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) +#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) + +#define FP_UNPACK_D(X,val) \ + do { \ + _FP_UNPACK_RAW_1(D,X,val); \ + _FP_UNPACK_CANONICAL(D,1,X); \ + } while (0) + +#define FP_PACK_D(val,X) \ + do { \ + _FP_PACK_CANONICAL(D,1,X); \ + _FP_PACK_RAW_1(D,val,X); \ + } while (0) + +#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) +#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) +#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) +#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) +#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) +#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) + +/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by + the target machine. */ + +#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) +#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) + +#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) +#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) + +#endif /* W_TYPE_SIZE < 64 */ diff --git a/trunk/arch/powerpc/math-emu/fadd.c b/trunk/arch/powerpc/math-emu/fadd.c index 04d3b4aa32ce..7befbbf2c332 100644 --- a/trunk/arch/powerpc/math-emu/fadd.c +++ b/trunk/arch/powerpc/math-emu/fadd.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fadd(void *frD, void *frA, void *frB) @@ -12,28 +11,28 @@ fadd(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c); #endif + if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF) + ret |= EFLAG_VXISI; + FP_ADD_D(R, A, B); #ifdef DEBUG printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fadds.c b/trunk/arch/powerpc/math-emu/fadds.c index 5930f40a8687..2b346b38b480 100644 --- a/trunk/arch/powerpc/math-emu/fadds.c +++ b/trunk/arch/powerpc/math-emu/fadds.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fadds(void *frD, void *frA, void *frB) @@ -13,27 +12,28 @@ fadds(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; + int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c); #endif + if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF) + ret |= EFLAG_VXISI; + FP_ADD_D(R, A, B); #ifdef DEBUG printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fcmpo.c b/trunk/arch/powerpc/math-emu/fcmpo.c index b5dc4498cd71..36d689044c63 100644 --- a/trunk/arch/powerpc/math-emu/fcmpo.c +++ b/trunk/arch/powerpc/math-emu/fcmpo.c @@ -2,16 +2,14 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fcmpo(u32 *ccr, int crfD, void *frA, void *frB) { FP_DECL_D(A); FP_DECL_D(B); - FP_DECL_EX; int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) }; long cmp; int ret = 0; @@ -20,8 +18,8 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB) printk("%s: %p (%08x) %d %p %p\n", __func__, ccr, *ccr, crfD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); diff --git a/trunk/arch/powerpc/math-emu/fcmpu.c b/trunk/arch/powerpc/math-emu/fcmpu.c index d4fb1babc6ad..53d93894f2a6 100644 --- a/trunk/arch/powerpc/math-emu/fcmpu.c +++ b/trunk/arch/powerpc/math-emu/fcmpu.c @@ -2,16 +2,14 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fcmpu(u32 *ccr, int crfD, void *frA, void *frB) { FP_DECL_D(A); FP_DECL_D(B); - FP_DECL_EX; int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) }; long cmp; @@ -19,8 +17,8 @@ fcmpu(u32 *ccr, int crfD, void *frA, void *frB) printk("%s: %p (%08x) %d %p %p\n", __func__, ccr, *ccr, crfD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); diff --git a/trunk/arch/powerpc/math-emu/fctiw.c b/trunk/arch/powerpc/math-emu/fctiw.c index f694440ddc00..fcd7a95e021d 100644 --- a/trunk/arch/powerpc/math-emu/fctiw.c +++ b/trunk/arch/powerpc/math-emu/fctiw.c @@ -2,18 +2,16 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fctiw(u32 *frD, void *frB) { FP_DECL_D(B); - FP_DECL_EX; unsigned int r; - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(B, frB); FP_TO_INT_D(r, B, 32, 1); frD[1] = r; diff --git a/trunk/arch/powerpc/math-emu/fctiwz.c b/trunk/arch/powerpc/math-emu/fctiwz.c index 71e782fd4fe3..1514d59e146e 100644 --- a/trunk/arch/powerpc/math-emu/fctiwz.c +++ b/trunk/arch/powerpc/math-emu/fctiwz.c @@ -2,15 +2,13 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fctiwz(u32 *frD, void *frB) { FP_DECL_D(B); - FP_DECL_EX; u32 fpscr; unsigned int r; @@ -18,7 +16,7 @@ fctiwz(u32 *frD, void *frB) __FPU_FPSCR &= ~(3); __FPU_FPSCR |= FP_RND_ZERO; - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(B, frB); FP_TO_INT_D(r, B, 32, 1); frD[1] = r; diff --git a/trunk/arch/powerpc/math-emu/fdiv.c b/trunk/arch/powerpc/math-emu/fdiv.c index 2db15097d98e..18a20fe396b0 100644 --- a/trunk/arch/powerpc/math-emu/fdiv.c +++ b/trunk/arch/powerpc/math-emu/fdiv.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fdiv(void *frD, void *frA, void *frB) @@ -12,15 +11,14 @@ fdiv(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -51,7 +49,5 @@ fdiv(void *frD, void *frA, void *frB) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fdivs.c b/trunk/arch/powerpc/math-emu/fdivs.c index 797f6a9a20b5..24feed689c35 100644 --- a/trunk/arch/powerpc/math-emu/fdivs.c +++ b/trunk/arch/powerpc/math-emu/fdivs.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fdivs(void *frD, void *frA, void *frB) @@ -13,15 +12,14 @@ fdivs(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -53,7 +51,5 @@ fdivs(void *frD, void *frA, void *frB) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fmadd.c b/trunk/arch/powerpc/math-emu/fmadd.c index 925313aa6f82..dedb465fdc68 100644 --- a/trunk/arch/powerpc/math-emu/fmadd.c +++ b/trunk/arch/powerpc/math-emu/fmadd.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fmadd(void *frD, void *frA, void *frB, void *frC) @@ -14,16 +13,15 @@ fmadd(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -46,7 +44,5 @@ fmadd(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fmadds.c b/trunk/arch/powerpc/math-emu/fmadds.c index aea80ef79399..6bbb56d5502c 100644 --- a/trunk/arch/powerpc/math-emu/fmadds.c +++ b/trunk/arch/powerpc/math-emu/fmadds.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fmadds(void *frD, void *frA, void *frB, void *frC) @@ -15,16 +14,15 @@ fmadds(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -47,7 +45,5 @@ fmadds(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fmsub.c b/trunk/arch/powerpc/math-emu/fmsub.c index a644d525fca6..f311e2c7e67e 100644 --- a/trunk/arch/powerpc/math-emu/fmsub.c +++ b/trunk/arch/powerpc/math-emu/fmsub.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fmsub(void *frD, void *frA, void *frB, void *frC) @@ -14,16 +13,15 @@ fmsub(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -49,7 +47,5 @@ fmsub(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fmsubs.c b/trunk/arch/powerpc/math-emu/fmsubs.c index 2fdeeb9bb569..81a716d3ee2e 100644 --- a/trunk/arch/powerpc/math-emu/fmsubs.c +++ b/trunk/arch/powerpc/math-emu/fmsubs.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fmsubs(void *frD, void *frA, void *frB, void *frC) @@ -15,16 +14,15 @@ fmsubs(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -50,7 +48,5 @@ fmsubs(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fmul.c b/trunk/arch/powerpc/math-emu/fmul.c index 391fd17d3440..2f3d32784a04 100644 --- a/trunk/arch/powerpc/math-emu/fmul.c +++ b/trunk/arch/powerpc/math-emu/fmul.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fmul(void *frD, void *frA, void *frB) @@ -12,15 +11,14 @@ fmul(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n", @@ -40,7 +38,5 @@ fmul(void *frD, void *frA, void *frB) R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fmuls.c b/trunk/arch/powerpc/math-emu/fmuls.c index 2d3ec5f7da20..962b5883f784 100644 --- a/trunk/arch/powerpc/math-emu/fmuls.c +++ b/trunk/arch/powerpc/math-emu/fmuls.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fmuls(void *frD, void *frA, void *frB) @@ -13,15 +12,14 @@ fmuls(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n", @@ -41,7 +39,5 @@ fmuls(void *frD, void *frA, void *frB) R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fnmadd.c b/trunk/arch/powerpc/math-emu/fnmadd.c index 2497b86494e5..8cf7827c4fb5 100644 --- a/trunk/arch/powerpc/math-emu/fnmadd.c +++ b/trunk/arch/powerpc/math-emu/fnmadd.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fnmadd(void *frD, void *frA, void *frB, void *frC) @@ -14,16 +13,15 @@ fnmadd(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -49,7 +47,5 @@ fnmadd(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fnmadds.c b/trunk/arch/powerpc/math-emu/fnmadds.c index ee9d71e0b376..f1c4f0f0d807 100644 --- a/trunk/arch/powerpc/math-emu/fnmadds.c +++ b/trunk/arch/powerpc/math-emu/fnmadds.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fnmadds(void *frD, void *frA, void *frB, void *frC) @@ -15,16 +14,15 @@ fnmadds(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -50,7 +48,5 @@ fnmadds(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fnmsub.c b/trunk/arch/powerpc/math-emu/fnmsub.c index 3885a77acc93..98944e6e2601 100644 --- a/trunk/arch/powerpc/math-emu/fnmsub.c +++ b/trunk/arch/powerpc/math-emu/fnmsub.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fnmsub(void *frD, void *frA, void *frB, void *frC) @@ -14,16 +13,15 @@ fnmsub(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -52,7 +50,5 @@ fnmsub(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fnmsubs.c b/trunk/arch/powerpc/math-emu/fnmsubs.c index f835dfeb0fd1..b20f4eb63fb9 100644 --- a/trunk/arch/powerpc/math-emu/fnmsubs.c +++ b/trunk/arch/powerpc/math-emu/fnmsubs.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fnmsubs(void *frD, void *frA, void *frB, void *frC) @@ -15,16 +14,15 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC) FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(T); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); - FP_UNPACK_DP(C, frC); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); + __FP_UNPACK_D(C, frC); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -53,7 +51,5 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/frsp.c b/trunk/arch/powerpc/math-emu/frsp.c index ddcc14664b1a..724ccbc0468e 100644 --- a/trunk/arch/powerpc/math-emu/frsp.c +++ b/trunk/arch/powerpc/math-emu/frsp.c @@ -2,28 +2,24 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int frsp(void *frD, void *frB) { FP_DECL_D(B); - FP_DECL_EX; #ifdef DEBUG printk("%s: D %p, B %p\n", __func__, frD, frB); #endif - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c); #endif - __FP_PACK_DS(frD, B); - - return FP_CUR_EXCEPTIONS; + return __FP_PACK_DS(frD, B); } diff --git a/trunk/arch/powerpc/math-emu/fsel.c b/trunk/arch/powerpc/math-emu/fsel.c index 1b0c14498032..ecb5f28eb1f3 100644 --- a/trunk/arch/powerpc/math-emu/fsel.c +++ b/trunk/arch/powerpc/math-emu/fsel.c @@ -2,21 +2,19 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fsel(u32 *frD, void *frA, u32 *frB, u32 *frC) { FP_DECL_D(A); - FP_DECL_EX; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frA, frB, frC); #endif - FP_UNPACK_DP(A, frA); + __FP_UNPACK_D(A, frA); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); diff --git a/trunk/arch/powerpc/math-emu/fsqrt.c b/trunk/arch/powerpc/math-emu/fsqrt.c index 3e90072693a0..38ec2b752e9d 100644 --- a/trunk/arch/powerpc/math-emu/fsqrt.c +++ b/trunk/arch/powerpc/math-emu/fsqrt.c @@ -2,23 +2,21 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fsqrt(void *frD, void *frB) { FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frB); #endif - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c); @@ -35,7 +33,5 @@ fsqrt(void *frD, void *frB) printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fsqrts.c b/trunk/arch/powerpc/math-emu/fsqrts.c index 2843be986e2e..335263e06ee5 100644 --- a/trunk/arch/powerpc/math-emu/fsqrts.c +++ b/trunk/arch/powerpc/math-emu/fsqrts.c @@ -2,24 +2,22 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fsqrts(void *frD, void *frB) { FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p %p\n", __func__, frD, frB); #endif - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c); @@ -36,7 +34,5 @@ fsqrts(void *frD, void *frB) printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fsub.c b/trunk/arch/powerpc/math-emu/fsub.c index 78b09446a0e1..208d20fc52a5 100644 --- a/trunk/arch/powerpc/math-emu/fsub.c +++ b/trunk/arch/powerpc/math-emu/fsub.c @@ -2,9 +2,8 @@ #include #include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" int fsub(void *frD, void *frA, void *frB) @@ -12,15 +11,14 @@ fsub(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -39,7 +37,5 @@ fsub(void *frD, void *frA, void *frB) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_D(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_D(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/fsubs.c b/trunk/arch/powerpc/math-emu/fsubs.c index d3bf90863cf2..0e61b808c44b 100644 --- a/trunk/arch/powerpc/math-emu/fsubs.c +++ b/trunk/arch/powerpc/math-emu/fsubs.c @@ -2,10 +2,9 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int fsubs(void *frD, void *frA, void *frB) @@ -13,15 +12,14 @@ fsubs(void *frD, void *frA, void *frB) FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); - FP_DECL_EX; int ret = 0; #ifdef DEBUG printk("%s: %p %p %p\n", __func__, frD, frA, frB); #endif - FP_UNPACK_DP(A, frA); - FP_UNPACK_DP(B, frB); + __FP_UNPACK_D(A, frA); + __FP_UNPACK_D(B, frB); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -40,7 +38,5 @@ fsubs(void *frD, void *frA, void *frB) printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - __FP_PACK_DS(frD, R); - - return FP_CUR_EXCEPTIONS; + return (ret | __FP_PACK_DS(frD, R)); } diff --git a/trunk/arch/powerpc/math-emu/lfd.c b/trunk/arch/powerpc/math-emu/lfd.c index 79ac76d596c3..6ec90b57c61a 100644 --- a/trunk/arch/powerpc/math-emu/lfd.c +++ b/trunk/arch/powerpc/math-emu/lfd.c @@ -2,8 +2,8 @@ #include #include -#include -#include +#include "sfp-machine.h" +#include "double.h" int lfd(void *frD, void *ea) diff --git a/trunk/arch/powerpc/math-emu/lfs.c b/trunk/arch/powerpc/math-emu/lfs.c index 434ed27be8db..6f18ebe3a7ff 100644 --- a/trunk/arch/powerpc/math-emu/lfs.c +++ b/trunk/arch/powerpc/math-emu/lfs.c @@ -2,17 +2,15 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int lfs(void *frD, void *ea) { FP_DECL_D(R); FP_DECL_S(A); - FP_DECL_EX; float f; #ifdef DEBUG @@ -22,7 +20,7 @@ lfs(void *frD, void *ea) if (copy_from_user(&f, ea, sizeof(float))) return -EFAULT; - FP_UNPACK_S(A, f); + __FP_UNPACK_S(A, &f); #ifdef DEBUG printk("A: %ld %lu %ld (%ld) [%08lx]\n", A_s, A_f, A_e, A_c, @@ -35,12 +33,5 @@ lfs(void *frD, void *ea) printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c); #endif - if (R_c == FP_CLS_NAN) { - R_e = _FP_EXPMAX_D; - _FP_PACK_RAW_2_P(D, frD, R); - } else { - __FP_PACK_D(frD, R); - } - - return 0; + return __FP_PACK_D(frD, R); } diff --git a/trunk/arch/powerpc/math-emu/math.c b/trunk/arch/powerpc/math-emu/math.c index 164d55935bd8..29e545e0272e 100644 --- a/trunk/arch/powerpc/math-emu/math.c +++ b/trunk/arch/powerpc/math-emu/math.c @@ -8,8 +8,8 @@ #include #include -#include -#include +#include "sfp-machine.h" +#include "double.h" #define FLOATFUNC(x) extern int x(void *, void *, void *, void *) @@ -168,8 +168,6 @@ record_exception(struct pt_regs *regs, int eflag) fpscr |= FPSCR_ZX; if (eflag & EFLAG_INEXACT) fpscr |= FPSCR_XX; - if (eflag & EFLAG_INVALID) - fpscr |= FPSCR_VX; if (eflag & EFLAG_VXSNAN) fpscr |= FPSCR_VXSNAN; if (eflag & EFLAG_VXISI) @@ -190,7 +188,7 @@ record_exception(struct pt_regs *regs, int eflag) fpscr |= FPSCR_VXCVI; } -// fpscr &= ~(FPSCR_VX); + fpscr &= ~(FPSCR_VX); if (fpscr & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI | FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI)) diff --git a/trunk/arch/powerpc/math-emu/mcrfs.c b/trunk/arch/powerpc/math-emu/mcrfs.c index e948d5708e2b..41ba247faf89 100644 --- a/trunk/arch/powerpc/math-emu/mcrfs.c +++ b/trunk/arch/powerpc/math-emu/mcrfs.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include "soft-fp.h" int mcrfs(u32 *ccr, u32 crfD, u32 crfS) diff --git a/trunk/arch/powerpc/math-emu/mffs.c b/trunk/arch/powerpc/math-emu/mffs.c index 5526cf96ede5..b0e2106e6eb6 100644 --- a/trunk/arch/powerpc/math-emu/mffs.c +++ b/trunk/arch/powerpc/math-emu/mffs.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include "soft-fp.h" int mffs(u32 *frD) diff --git a/trunk/arch/powerpc/math-emu/mtfsb0.c b/trunk/arch/powerpc/math-emu/mtfsb0.c index bc985585bca8..d3062350ea21 100644 --- a/trunk/arch/powerpc/math-emu/mtfsb0.c +++ b/trunk/arch/powerpc/math-emu/mtfsb0.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include "soft-fp.h" int mtfsb0(int crbD) diff --git a/trunk/arch/powerpc/math-emu/mtfsb1.c b/trunk/arch/powerpc/math-emu/mtfsb1.c index fe6ed5ac85b3..2e948704b56e 100644 --- a/trunk/arch/powerpc/math-emu/mtfsb1.c +++ b/trunk/arch/powerpc/math-emu/mtfsb1.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include "soft-fp.h" int mtfsb1(int crbD) diff --git a/trunk/arch/powerpc/math-emu/mtfsf.c b/trunk/arch/powerpc/math-emu/mtfsf.c index dbce92e4f046..48014d8e3af1 100644 --- a/trunk/arch/powerpc/math-emu/mtfsf.c +++ b/trunk/arch/powerpc/math-emu/mtfsf.c @@ -2,14 +2,12 @@ #include #include -#include -#include +#include "soft-fp.h" int mtfsf(unsigned int FM, u32 *frB) { u32 mask; - u32 fpscr; if (FM == 0) return 0; @@ -39,22 +37,6 @@ mtfsf(unsigned int FM, u32 *frB) __FPU_FPSCR &= ~(mask); __FPU_FPSCR |= (frB[1] & mask); - __FPU_FPSCR &= ~(FPSCR_VX); - if (__FPU_FPSCR & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI | - FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI)) - __FPU_FPSCR |= FPSCR_VX; - - fpscr = __FPU_FPSCR; - fpscr &= ~(FPSCR_FEX); - if (((fpscr & FPSCR_VX) && (fpscr & FPSCR_VE)) || - ((fpscr & FPSCR_OX) && (fpscr & FPSCR_OE)) || - ((fpscr & FPSCR_UX) && (fpscr & FPSCR_UE)) || - ((fpscr & FPSCR_ZX) && (fpscr & FPSCR_ZE)) || - ((fpscr & FPSCR_XX) && (fpscr & FPSCR_XE))) - fpscr |= FPSCR_FEX; - __FPU_FPSCR = fpscr; - #ifdef DEBUG printk("%s: %02x %p: %08lx\n", __func__, FM, frB, __FPU_FPSCR); #endif diff --git a/trunk/arch/powerpc/math-emu/mtfsfi.c b/trunk/arch/powerpc/math-emu/mtfsfi.c index fd2acc26813b..031e20093549 100644 --- a/trunk/arch/powerpc/math-emu/mtfsfi.c +++ b/trunk/arch/powerpc/math-emu/mtfsfi.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include "soft-fp.h" int mtfsfi(unsigned int crfD, unsigned int IMM) diff --git a/trunk/arch/powerpc/math-emu/op-1.h b/trunk/arch/powerpc/math-emu/op-1.h new file mode 100644 index 000000000000..c92fa95f562e --- /dev/null +++ b/trunk/arch/powerpc/math-emu/op-1.h @@ -0,0 +1,245 @@ +/* + * Basic one-word fraction declaration and manipulation. + */ + +#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f +#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) +#define _FP_FRAC_SET_1(X,I) (X##_f = I) +#define _FP_FRAC_HIGH_1(X) (X##_f) +#define _FP_FRAC_LOW_1(X) (X##_f) +#define _FP_FRAC_WORD_1(X,w) (X##_f) + +#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) +#define _FP_FRAC_SLL_1(X,N) \ + do { \ + if (__builtin_constant_p(N) && (N) == 1) \ + X##_f += X##_f; \ + else \ + X##_f <<= (N); \ + } while (0) +#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) + +/* Right shift with sticky-lsb. */ +#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) + +#define __FP_FRAC_SRS_1(X,N,sz) \ + (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ + ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) + +#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) +#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) +#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) + +/* Predicates */ +#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) +#define _FP_FRAC_ZEROP_1(X) (X##_f == 0) +#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) +#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) +#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) +#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) + +#define _FP_ZEROFRAC_1 0 +#define _FP_MINFRAC_1 1 + +/* + * Unpack the raw bits of a native fp value. Do not classify or + * normalize the data. + */ + +#define _FP_UNPACK_RAW_1(fs, X, val) \ + do { \ + union _FP_UNION_##fs _flo; _flo.flt = (val); \ + \ + X##_f = _flo.bits.frac; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } while (0) + + +/* + * Repack the raw bits of a native fp value. + */ + +#define _FP_PACK_RAW_1(fs, val, X) \ + do { \ + union _FP_UNION_##fs _flo; \ + \ + _flo.bits.frac = X##_f; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } while (0) + + +/* + * Multiplication algorithms: + */ + +/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the + multiplication immediately. */ + +#define _FP_MUL_MEAT_1_imm(fs, R, X, Y) \ + do { \ + R##_f = X##_f * Y##_f; \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_1(R, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \ + } while (0) + +/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ + +#define _FP_MUL_MEAT_1_wide(fs, R, X, Y, doit) \ + do { \ + _FP_W_TYPE _Z_f0, _Z_f1; \ + doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_2(_Z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \ + R##_f = _Z_f0; \ + } while (0) + +/* Finally, a simple widening multiply algorithm. What fun! */ + +#define _FP_MUL_MEAT_1_hard(fs, R, X, Y) \ + do { \ + _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ + \ + /* split the words in half */ \ + _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ + _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ + _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ + _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ + \ + /* multiply the pieces */ \ + _z_f0 = _xl * _yl; \ + _a_f0 = _xh * _yl; \ + _a_f1 = _xl * _yh; \ + _z_f1 = _xh * _yh; \ + \ + /* reassemble into two full words */ \ + if ((_a_f0 += _a_f1) < _a_f1) \ + _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ + _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ + _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ + _FP_FRAC_ADD_2(_z, _z, _a); \ + \ + /* normalize */ \ + _FP_FRAC_SRS_2(_z, _FP_WFRACBITS_##fs - 1, 2*_FP_WFRACBITS_##fs); \ + R##_f = _z_f0; \ + } while (0) + + +/* + * Division algorithms: + */ + +/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the + division immediately. Give this macro either _FP_DIV_HELP_imm for + C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you + choose will depend on what the compiler does with divrem4. */ + +#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ + do { \ + _FP_W_TYPE _q, _r; \ + X##_f <<= (X##_f < Y##_f \ + ? R##_e--, _FP_WFRACBITS_##fs \ + : _FP_WFRACBITS_##fs - 1); \ + doit(_q, _r, X##_f, Y##_f); \ + R##_f = _q | (_r != 0); \ + } while (0) + +/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd + that may be useful in this situation. This first is for a primitive + that requires normalization, the second for one that does not. Look + for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ + +#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ + do { \ + _FP_W_TYPE _nh, _nl, _q, _r; \ + \ + /* Normalize Y -- i.e. make the most significant bit set. */ \ + Y##_f <<= _FP_WFRACXBITS_##fs - 1; \ + \ + /* Shift X op correspondingly high, that is, up one full word. */ \ + if (X##_f <= Y##_f) \ + { \ + _nl = 0; \ + _nh = X##_f; \ + } \ + else \ + { \ + R##_e++; \ + _nl = X##_f << (_FP_W_TYPE_SIZE-1); \ + _nh = X##_f >> 1; \ + } \ + \ + udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ + R##_f = _q | (_r != 0); \ + } while (0) + +#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ + do { \ + _FP_W_TYPE _nh, _nl, _q, _r; \ + if (X##_f < Y##_f) \ + { \ + R##_e--; \ + _nl = X##_f << _FP_WFRACBITS_##fs; \ + _nh = X##_f >> _FP_WFRACXBITS_##fs; \ + } \ + else \ + { \ + _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ + _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ + } \ + udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ + R##_f = _q | (_r != 0); \ + } while (0) + + +/* + * Square root algorithms: + * We have just one right now, maybe Newton approximation + * should be added for those machines where division is fast. + */ + +#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ + do { \ + while (q) \ + { \ + T##_f = S##_f + q; \ + if (T##_f <= X##_f) \ + { \ + S##_f = T##_f + q; \ + X##_f -= T##_f; \ + R##_f += q; \ + } \ + _FP_FRAC_SLL_1(X, 1); \ + q >>= 1; \ + } \ + } while (0) + +/* + * Assembly/disassembly for converting to/from integral types. + * No shifting or overflow handled here. + */ + +#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f) +#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r) + + +/* + * Convert FP values between word sizes + */ + +#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S) \ + do { \ + D##_f = S##_f; \ + if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs) \ + _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + else \ + D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs; \ + } while (0) diff --git a/trunk/arch/powerpc/math-emu/op-2.h b/trunk/arch/powerpc/math-emu/op-2.h new file mode 100644 index 000000000000..7d6f17cc2929 --- /dev/null +++ b/trunk/arch/powerpc/math-emu/op-2.h @@ -0,0 +1,434 @@ +/* + * Basic two-word fraction declaration and manipulation. + */ + +#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1 +#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1) +#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I) +#define _FP_FRAC_HIGH_2(X) (X##_f1) +#define _FP_FRAC_LOW_2(X) (X##_f0) +#define _FP_FRAC_WORD_2(X,w) (X##_f##w) + +#define _FP_FRAC_SLL_2(X,N) \ + do { \ + if ((N) < _FP_W_TYPE_SIZE) \ + { \ + if (__builtin_constant_p(N) && (N) == 1) \ + { \ + X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ + X##_f0 += X##_f0; \ + } \ + else \ + { \ + X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ + X##_f0 <<= (N); \ + } \ + } \ + else \ + { \ + X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ + X##_f0 = 0; \ + } \ + } while (0) + +#define _FP_FRAC_SRL_2(X,N) \ + do { \ + if ((N) < _FP_W_TYPE_SIZE) \ + { \ + X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ + X##_f1 >>= (N); \ + } \ + else \ + { \ + X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ + X##_f1 = 0; \ + } \ + } while (0) + +/* Right shift with sticky-lsb. */ +#define _FP_FRAC_SRS_2(X,N,sz) \ + do { \ + if ((N) < _FP_W_TYPE_SIZE) \ + { \ + X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ + (__builtin_constant_p(N) && (N) == 1 \ + ? X##_f0 & 1 \ + : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ + X##_f1 >>= (N); \ + } \ + else \ + { \ + X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ + (((X##_f1 << (2 * _FP_W_TYPE_SIZE - (N))) | \ + X##_f0) != 0)); \ + X##_f1 = 0; \ + } \ + } while (0) + +#define _FP_FRAC_ADDI_2(X,I) \ + __FP_FRAC_ADDI_2(X##_f1, X##_f0, I) + +#define _FP_FRAC_ADD_2(R,X,Y) \ + __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) + +#define _FP_FRAC_SUB_2(R,X,Y) \ + __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) + +#define _FP_FRAC_CLZ_2(R,X) \ + do { \ + if (X##_f1) \ + __FP_CLZ(R,X##_f1); \ + else \ + { \ + __FP_CLZ(R,X##_f0); \ + R += _FP_W_TYPE_SIZE; \ + } \ + } while(0) + +/* Predicates */ +#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) +#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0) +#define _FP_FRAC_OVERP_2(fs,X) (X##_f1 & _FP_OVERFLOW_##fs) +#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0) +#define _FP_FRAC_GT_2(X, Y) \ + ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0)) +#define _FP_FRAC_GE_2(X, Y) \ + ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)) + +#define _FP_ZEROFRAC_2 0, 0 +#define _FP_MINFRAC_2 0, 1 + +/* + * Internals + */ + +#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) + +#define __FP_CLZ_2(R, xh, xl) \ + do { \ + if (xh) \ + __FP_CLZ(R,xl); \ + else \ + { \ + __FP_CLZ(R,xl); \ + R += _FP_W_TYPE_SIZE; \ + } \ + } while(0) + +#if 0 + +#ifndef __FP_FRAC_ADDI_2 +#define __FP_FRAC_ADDI_2(xh, xl, i) \ + (xh += ((xl += i) < i)) +#endif +#ifndef __FP_FRAC_ADD_2 +#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ + (rh = xh + yh + ((rl = xl + yl) < xl)) +#endif +#ifndef __FP_FRAC_SUB_2 +#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ + (rh = xh - yh - ((rl = xl - yl) > xl)) +#endif + +#else + +#undef __FP_FRAC_ADDI_2 +#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i) +#undef __FP_FRAC_ADD_2 +#define __FP_FRAC_ADD_2 add_ssaaaa +#undef __FP_FRAC_SUB_2 +#define __FP_FRAC_SUB_2 sub_ddmmss + +#endif + +/* + * Unpack the raw bits of a native fp value. Do not classify or + * normalize the data. + */ + +#define _FP_UNPACK_RAW_2(fs, X, val) \ + do { \ + union _FP_UNION_##fs _flo; _flo.flt = (val); \ + \ + X##_f0 = _flo.bits.frac0; \ + X##_f1 = _flo.bits.frac1; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } while (0) + + +/* + * Repack the raw bits of a native fp value. + */ + +#define _FP_PACK_RAW_2(fs, val, X) \ + do { \ + union _FP_UNION_##fs _flo; \ + \ + _flo.bits.frac0 = X##_f0; \ + _flo.bits.frac1 = X##_f1; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } while (0) + + +/* + * Multiplication algorithms: + */ + +/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ + +#define _FP_MUL_MEAT_2_wide(fs, R, X, Y, doit) \ + do { \ + _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ + \ + doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ + doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ + doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ + doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ + \ + __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ + _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0), \ + 0, _b_f1, _b_f0, 0, \ + _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ + _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0)); \ + __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ + _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0), \ + 0, _c_f1, _c_f0, 0, \ + _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ + _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0)); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4(_z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \ + R##_f0 = _FP_FRAC_WORD_4(_z,0); \ + R##_f1 = _FP_FRAC_WORD_4(_z,1); \ + } while (0) + +/* This next macro appears to be totally broken. Fortunately nowhere + * seems to use it :-> The problem is that we define _z[4] but + * then use it in _FP_FRAC_SRS_4, which will attempt to access + * _z_f[n] which will cause an error. The fix probably involves + * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998 + */ +#define _FP_MUL_MEAT_2_gmp(fs, R, X, Y) \ + do { \ + _FP_W_TYPE _x[2], _y[2], _z[4]; \ + _x[0] = X##_f0; _x[1] = X##_f1; \ + _y[0] = Y##_f0; _y[1] = Y##_f1; \ + \ + mpn_mul_n(_z, _x, _y, 2); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4(_z, _FP_WFRACBITS##_fs-1, 2*_FP_WFRACBITS_##fs); \ + R##_f0 = _z[0]; \ + R##_f1 = _z[1]; \ + } while (0) + + +/* + * Division algorithms: + * This seems to be giving me difficulties -- PMM + * Look, NetBSD seems to be able to comment algorithms. Can't you? + * I've thrown printks at the problem. + * This now appears to work, but I still don't really know why. + * Also, I don't think the result is properly normalised... + */ + +#define _FP_DIV_MEAT_2_udiv_64(fs, R, X, Y) \ + do { \ + extern void _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2], \ + _FP_W_TYPE n1, _FP_W_TYPE n0, \ + _FP_W_TYPE d1, _FP_W_TYPE d0); \ + _FP_W_TYPE _n_f3, _n_f2, _n_f1, _n_f0, _r_f1, _r_f0; \ + _FP_W_TYPE _q_f1, _q_f0, _m_f1, _m_f0; \ + _FP_W_TYPE _rmem[2], _qmem[2]; \ + /* I think this check is to ensure that the result is normalised. \ + * Assuming X,Y normalised (ie in [1.0,2.0)) X/Y will be in \ + * [0.5,2.0). Furthermore, it will be less than 1.0 iff X < Y. \ + * In this case we tweak things. (this is based on comments in \ + * the NetBSD FPU emulation code. ) \ + * We know X,Y are normalised because we ensure this as part of \ + * the unpacking process. -- PMM \ + */ \ + if (_FP_FRAC_GT_2(X, Y)) \ + { \ +/* R##_e++; */ \ + _n_f3 = X##_f1 >> 1; \ + _n_f2 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ + _n_f1 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ + _n_f0 = 0; \ + } \ + else \ + { \ + R##_e--; \ + _n_f3 = X##_f1; \ + _n_f2 = X##_f0; \ + _n_f1 = _n_f0 = 0; \ + } \ + \ + /* Normalize, i.e. make the most significant bit of the \ + denominator set. CHANGED: - 1 to nothing -- PMM */ \ + _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs /* -1 */); \ + \ + /* Do the 256/128 bit division given the 128-bit _fp_udivmodtf4 \ + primitive snagged from libgcc2.c. */ \ + \ + _fp_udivmodti4(_qmem, _rmem, _n_f3, _n_f2, 0, Y##_f1); \ + _q_f1 = _qmem[0]; \ + umul_ppmm(_m_f1, _m_f0, _q_f1, Y##_f0); \ + _r_f1 = _rmem[0]; \ + _r_f0 = _n_f1; \ + if (_FP_FRAC_GT_2(_m, _r)) \ + { \ + _q_f1--; \ + _FP_FRAC_ADD_2(_r, _r, Y); \ + if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ + { \ + _q_f1--; \ + _FP_FRAC_ADD_2(_r, _r, Y); \ + } \ + } \ + _FP_FRAC_SUB_2(_r, _r, _m); \ + \ + _fp_udivmodti4(_qmem, _rmem, _r_f1, _r_f0, 0, Y##_f1); \ + _q_f0 = _qmem[0]; \ + umul_ppmm(_m_f1, _m_f0, _q_f0, Y##_f0); \ + _r_f1 = _rmem[0]; \ + _r_f0 = _n_f0; \ + if (_FP_FRAC_GT_2(_m, _r)) \ + { \ + _q_f0--; \ + _FP_FRAC_ADD_2(_r, _r, Y); \ + if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ + { \ + _q_f0--; \ + _FP_FRAC_ADD_2(_r, _r, Y); \ + } \ + } \ + _FP_FRAC_SUB_2(_r, _r, _m); \ + \ + R##_f1 = _q_f1; \ + R##_f0 = _q_f0 | ((_r_f1 | _r_f0) != 0); \ + /* adjust so answer is normalized again. I'm not sure what the \ + * final sz param should be. In practice it's never used since \ + * N is 1 which is always going to be < _FP_W_TYPE_SIZE... \ + */ \ + /* _FP_FRAC_SRS_2(R,1,_FP_WFRACBITS_##fs); */ \ + } while (0) + + +#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ + do { \ + _FP_W_TYPE _x[4], _y[2], _z[4]; \ + _y[0] = Y##_f0; _y[1] = Y##_f1; \ + _x[0] = _x[3] = 0; \ + if (_FP_FRAC_GT_2(X, Y)) \ + { \ + R##_e++; \ + _x[1] = (X##_f0 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE) | \ + X##_f1 >> (_FP_W_TYPE_SIZE - \ + (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE))); \ + _x[2] = X##_f1 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE); \ + } \ + else \ + { \ + _x[1] = (X##_f0 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE) | \ + X##_f1 >> (_FP_W_TYPE_SIZE - \ + (_FP_WFRACBITS - _FP_W_TYPE_SIZE))); \ + _x[2] = X##_f1 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE); \ + } \ + \ + (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ + R##_f1 = _z[1]; \ + R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ + } while (0) + + +/* + * Square root algorithms: + * We have just one right now, maybe Newton approximation + * should be added for those machines where division is fast. + */ + +#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ + do { \ + while (q) \ + { \ + T##_f1 = S##_f1 + q; \ + if (T##_f1 <= X##_f1) \ + { \ + S##_f1 = T##_f1 + q; \ + X##_f1 -= T##_f1; \ + R##_f1 += q; \ + } \ + _FP_FRAC_SLL_2(X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f0 = S##_f0 + q; \ + T##_f1 = S##_f1; \ + if (T##_f1 < X##_f1 || \ + (T##_f1 == X##_f1 && T##_f0 < X##_f0)) \ + { \ + S##_f0 = T##_f0 + q; \ + if (((_FP_WS_TYPE)T##_f0) < 0 && \ + ((_FP_WS_TYPE)S##_f0) >= 0) \ + S##_f1++; \ + _FP_FRAC_SUB_2(X, X, T); \ + R##_f0 += q; \ + } \ + _FP_FRAC_SLL_2(X, 1); \ + q >>= 1; \ + } \ + } while (0) + + +/* + * Assembly/disassembly for converting to/from integral types. + * No shifting or overflow handled here. + */ + +#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ + do { \ + if (rsize <= _FP_W_TYPE_SIZE) \ + r = X##_f0; \ + else \ + { \ + r = X##_f1; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f0; \ + } \ + } while (0) + +#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ + do { \ + X##_f0 = r; \ + X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ + } while (0) + +/* + * Convert FP values between word sizes + */ + +#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S) \ + do { \ + _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + D##_f = S##_f0; \ + } while (0) + +#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S) \ + do { \ + D##_f0 = S##_f; \ + D##_f1 = 0; \ + _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \ + } while (0) + diff --git a/trunk/arch/powerpc/math-emu/op-4.h b/trunk/arch/powerpc/math-emu/op-4.h new file mode 100644 index 000000000000..c9ae626070da --- /dev/null +++ b/trunk/arch/powerpc/math-emu/op-4.h @@ -0,0 +1,317 @@ +/* + * Basic four-word fraction declaration and manipulation. + * + * When adding quadword support for 32 bit machines, we need + * to be a little careful as double multiply uses some of these + * macros: (in op-2.h) + * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4, + * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4 + * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use + * _FP_FRAC_DECL_4: it appears to be broken and is not used + * anywhere anyway. ) + * + * I've now fixed all the macros that were here from the sparc64 code. + * [*none* of the shift macros were correct!] -- PMM 02/1998 + * + * The only quadword stuff that remains to be coded is: + * 1) the conversion to/from ints, which requires + * that we check (in op-common.h) that the following do the right thing + * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt) + * 2) multiply, divide and sqrt, which require: + * _FP_MUL_MEAT_4_*(R,X,Y), _FP_DIV_MEAT_4_*(R,X,Y), _FP_SQRT_MEAT_4(R,S,T,X,q), + * This also needs _FP_MUL_MEAT_Q and _FP_DIV_MEAT_Q to be defined to + * some suitable _FP_MUL_MEAT_4_* macros in sfp-machine.h. + * [we're free to choose whatever FP_MUL_MEAT_4_* macros we need for + * these; they are used nowhere else. ] + */ + +#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4] +#define _FP_FRAC_COPY_4(D,S) \ + (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \ + D##_f[2] = S##_f[2], D##_f[3] = S##_f[3]) +/* The _FP_FRAC_SET_n(X,I) macro is intended for use with another + * macro such as _FP_ZEROFRAC_n which returns n comma separated values. + * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3) + * which just assigns the In values to the array X##_f[]. + * This is why the number of parameters doesn't appear to match + * at first glance... -- PMM + */ +#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) +#define _FP_FRAC_HIGH_4(X) (X##_f[3]) +#define _FP_FRAC_LOW_4(X) (X##_f[0]) +#define _FP_FRAC_WORD_4(X,w) (X##_f[w]) + +#define _FP_FRAC_SLL_4(X,N) \ + do { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _up = (N) % _FP_W_TYPE_SIZE; \ + _down = _FP_W_TYPE_SIZE - _up; \ + for (_i = 3; _i > _skip; --_i) \ + X##_f[_i] = X##_f[_i-_skip] << _up | X##_f[_i-_skip-1] >> _down; \ +/* bugfixed: was X##_f[_i] <<= _up; -- PMM 02/1998 */ \ + X##_f[_i] = X##_f[0] << _up; \ + for (--_i; _i >= 0; --_i) \ + X##_f[_i] = 0; \ + } while (0) + +/* This one was broken too */ +#define _FP_FRAC_SRL_4(X,N) \ + do { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + for (_i = 0; _i < 3-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \ + X##_f[_i] = X##_f[3] >> _down; \ + for (++_i; _i < 4; ++_i) \ + X##_f[_i] = 0; \ + } while (0) + + +/* Right shift with sticky-lsb. + * What this actually means is that we do a standard right-shift, + * but that if any of the bits that fall off the right hand side + * were one then we always set the LSbit. + */ +#define _FP_FRAC_SRS_4(X,N,size) \ + do { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _FP_W_TYPE _s; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + for (_s = _i = 0; _i < _skip; ++_i) \ + _s |= X##_f[_i]; \ + _s |= X##_f[_i] << _up; \ +/* s is now != 0 if we want to set the LSbit */ \ + for (_i = 0; _i < 3-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \ + X##_f[_i] = X##_f[3] >> _down; \ + for (++_i; _i < 4; ++_i) \ + X##_f[_i] = 0; \ + /* don't fix the LSB until the very end when we're sure f[0] is stable */ \ + X##_f[0] |= (_s != 0); \ + } while (0) + +#define _FP_FRAC_ADD_4(R,X,Y) \ + __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ + X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) + +#define _FP_FRAC_SUB_4(R,X,Y) \ + __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ + X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) + +#define _FP_FRAC_ADDI_4(X,I) \ + __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) + +#define _FP_ZEROFRAC_4 0,0,0,0 +#define _FP_MINFRAC_4 0,0,0,1 + +#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0) +#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0) +#define _FP_FRAC_OVERP_4(fs,X) (X##_f[0] & _FP_OVERFLOW_##fs) + +#define _FP_FRAC_EQ_4(X,Y) \ + (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ + && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) + +#define _FP_FRAC_GT_4(X,Y) \ + (X##_f[3] > Y##_f[3] || \ + (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ + (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ + (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ + )) \ + )) \ + ) + +#define _FP_FRAC_GE_4(X,Y) \ + (X##_f[3] > Y##_f[3] || \ + (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ + (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ + (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ + )) \ + )) \ + ) + + +#define _FP_FRAC_CLZ_4(R,X) \ + do { \ + if (X##_f[3]) \ + { \ + __FP_CLZ(R,X##_f[3]); \ + } \ + else if (X##_f[2]) \ + { \ + __FP_CLZ(R,X##_f[2]); \ + R += _FP_W_TYPE_SIZE; \ + } \ + else if (X##_f[1]) \ + { \ + __FP_CLZ(R,X##_f[2]); \ + R += _FP_W_TYPE_SIZE*2; \ + } \ + else \ + { \ + __FP_CLZ(R,X##_f[0]); \ + R += _FP_W_TYPE_SIZE*3; \ + } \ + } while(0) + + +#define _FP_UNPACK_RAW_4(fs, X, val) \ + do { \ + union _FP_UNION_##fs _flo; _flo.flt = (val); \ + X##_f[0] = _flo.bits.frac0; \ + X##_f[1] = _flo.bits.frac1; \ + X##_f[2] = _flo.bits.frac2; \ + X##_f[3] = _flo.bits.frac3; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } while (0) + +#define _FP_PACK_RAW_4(fs, val, X) \ + do { \ + union _FP_UNION_##fs _flo; \ + _flo.bits.frac0 = X##_f[0]; \ + _flo.bits.frac1 = X##_f[1]; \ + _flo.bits.frac2 = X##_f[2]; \ + _flo.bits.frac3 = X##_f[3]; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + (val) = _flo.flt; \ + } while (0) + + +/* + * Internals + */ + +#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ + (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) + +#ifndef __FP_FRAC_ADD_4 +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + int _c1, _c2, _c3; \ + r0 = x0 + y0; \ + _c1 = r0 < x0; \ + r1 = x1 + y1; \ + _c2 = r1 < x1; \ + r1 += _c1; \ + _c2 |= r1 < _c1; \ + r2 = x2 + y2; \ + _c3 = r2 < x2; \ + r2 += _c2; \ + _c3 |= r2 < _c2; \ + r3 = x3 + y3 + _c3; \ + } while (0) +#endif + +#ifndef __FP_FRAC_SUB_4 +#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + int _c1, _c2, _c3; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= r1 > _c1; \ + r2 = x2 - y2; \ + _c3 = r2 > x2; \ + r2 -= _c2; \ + _c3 |= r2 > _c2; \ + r3 = x3 - y3 - _c3; \ + } while (0) +#endif + +#ifndef __FP_FRAC_ADDI_4 +/* I always wanted to be a lisp programmer :-> */ +#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ + (x3 += ((x2 += ((x1 += ((x0 += i) < x0)) < x1) < x2))) +#endif + +/* Convert FP values between word sizes. This appears to be more + * complicated than I'd have expected it to be, so these might be + * wrong... These macros are in any case somewhat bogus because they + * use information about what various FRAC_n variables look like + * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do + * the ones in op-2.h and op-1.h. + */ +#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S) \ + do { \ + _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + D##_f = S##_f[0]; \ + } while (0) + +#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S) \ + do { \ + _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + D##_f0 = S##_f[0]; \ + D##_f1 = S##_f[1]; \ + } while (0) + +/* Assembly/disassembly for converting to/from integral types. + * No shifting or overflow handled here. + */ +/* Put the FP value X into r, which is an integer of size rsize. */ +#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ + do { \ + if (rsize <= _FP_W_TYPE_SIZE) \ + r = X##_f[0]; \ + else if (rsize <= 2*_FP_W_TYPE_SIZE) \ + { \ + r = X##_f[1]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[0]; \ + } \ + else \ + { \ + /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ + /* and int == 4words as a single case. */ \ + r = X##_f[3]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[2]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[1]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[0]; \ + } \ + } while (0) + +/* "No disassemble Number Five!" */ +/* move an integer of size rsize into X's fractional part. We rely on + * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid + * having to mask the values we store into it. + */ +#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ + do { \ + X##_f[0] = r; \ + X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ + X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ + X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ + } while (0) + +#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S) \ + do { \ + D##_f[0] = S##_f; \ + D##_f[1] = D##_f[2] = D##_f[3] = 0; \ + _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \ + } while (0) + +#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S) \ + do { \ + D##_f[0] = S##_f0; \ + D##_f[1] = S##_f1; \ + D##_f[2] = D##_f[3] = 0; \ + _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \ + } while (0) + +/* FIXME! This has to be written */ +#define _FP_SQRT_MEAT_4(R, S, T, X, q) diff --git a/trunk/arch/powerpc/math-emu/op-common.h b/trunk/arch/powerpc/math-emu/op-common.h new file mode 100644 index 000000000000..afb82b6498ce --- /dev/null +++ b/trunk/arch/powerpc/math-emu/op-common.h @@ -0,0 +1,688 @@ +#define _FP_DECL(wc, X) \ + _FP_I_TYPE X##_c, X##_s, X##_e; \ + _FP_FRAC_DECL_##wc(X) + +/* + * Finish truely unpacking a native fp value by classifying the kind + * of fp value and normalizing both the exponent and the fraction. + */ + +#define _FP_UNPACK_CANONICAL(fs, wc, X) \ +do { \ + switch (X##_e) \ + { \ + default: \ + _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \ + _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ + X##_e -= _FP_EXPBIAS_##fs; \ + X##_c = FP_CLS_NORMAL; \ + break; \ + \ + case 0: \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + X##_c = FP_CLS_ZERO; \ + else \ + { \ + /* a denormalized number */ \ + _FP_I_TYPE _shift; \ + _FP_FRAC_CLZ_##wc(_shift, X); \ + _shift -= _FP_FRACXBITS_##fs; \ + _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ + X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ + X##_c = FP_CLS_NORMAL; \ + } \ + break; \ + \ + case _FP_EXPMAX_##fs: \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + X##_c = FP_CLS_INF; \ + else \ + /* we don't differentiate between signaling and quiet nans */ \ + X##_c = FP_CLS_NAN; \ + break; \ + } \ +} while (0) + + +/* + * Before packing the bits back into the native fp result, take care + * of such mundane things as rounding and overflow. Also, for some + * kinds of fp values, the original parts may not have been fully + * extracted -- but that is ok, we can regenerate them now. + */ + +#define _FP_PACK_CANONICAL(fs, wc, X) \ +({int __ret = 0; \ + switch (X##_c) \ + { \ + case FP_CLS_NORMAL: \ + X##_e += _FP_EXPBIAS_##fs; \ + if (X##_e > 0) \ + { \ + __ret |= _FP_ROUND(wc, X); \ + if (_FP_FRAC_OVERP_##wc(fs, X)) \ + { \ + _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \ + X##_e++; \ + } \ + else \ + _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ + if (X##_e >= _FP_EXPMAX_##fs) \ + { \ + /* overflow to infinity */ \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + __ret |= EFLAG_OVERFLOW; \ + } \ + } \ + else \ + { \ + /* we've got a denormalized number */ \ + X##_e = -X##_e + 1; \ + if (X##_e <= _FP_WFRACBITS_##fs) \ + { \ + _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ + _FP_FRAC_SLL_##wc(X, 1); \ + if (_FP_FRAC_OVERP_##wc(fs, X)) \ + { \ + X##_e = 1; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + } \ + else \ + { \ + X##_e = 0; \ + _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \ + __ret |= EFLAG_UNDERFLOW; \ + } \ + } \ + else \ + { \ + /* underflow to zero */ \ + X##_e = 0; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + __ret |= EFLAG_UNDERFLOW; \ + } \ + } \ + break; \ + \ + case FP_CLS_ZERO: \ + X##_e = 0; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + break; \ + \ + case FP_CLS_INF: \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + break; \ + \ + case FP_CLS_NAN: \ + X##_e = _FP_EXPMAX_##fs; \ + if (!_FP_KEEPNANFRACP) \ + { \ + _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ + X##_s = 0; \ + } \ + else \ + _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \ + break; \ + } \ + __ret; \ +}) + + +/* + * Main addition routine. The input values should be cooked. + */ + +#define _FP_ADD(fs, wc, R, X, Y) \ +do { \ + switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ + { \ + /* shift the smaller number so that its exponent matches the larger */ \ + _FP_I_TYPE diff = X##_e - Y##_e; \ + \ + if (diff < 0) \ + { \ + diff = -diff; \ + if (diff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc(X)) \ + _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ + else \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + R##_e = Y##_e; \ + } \ + else \ + { \ + if (diff > 0) \ + { \ + if (diff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc(Y)) \ + _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ + else \ + _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \ + } \ + R##_e = X##_e; \ + } \ + \ + R##_c = FP_CLS_NORMAL; \ + \ + if (X##_s == Y##_s) \ + { \ + R##_s = X##_s; \ + _FP_FRAC_ADD_##wc(R, X, Y); \ + if (_FP_FRAC_OVERP_##wc(fs, R)) \ + { \ + _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ + R##_e++; \ + } \ + } \ + else \ + { \ + R##_s = X##_s; \ + _FP_FRAC_SUB_##wc(R, X, Y); \ + if (_FP_FRAC_ZEROP_##wc(R)) \ + { \ + /* return an exact zero */ \ + if (FP_ROUNDMODE == FP_RND_MINF) \ + R##_s |= Y##_s; \ + else \ + R##_s &= Y##_s; \ + R##_c = FP_CLS_ZERO; \ + } \ + else \ + { \ + if (_FP_FRAC_NEGP_##wc(R)) \ + { \ + _FP_FRAC_SUB_##wc(R, Y, X); \ + R##_s = Y##_s; \ + } \ + \ + /* renormalize after subtraction */ \ + _FP_FRAC_CLZ_##wc(diff, R); \ + diff -= _FP_WFRACXBITS_##fs; \ + if (diff) \ + { \ + R##_e -= diff; \ + _FP_FRAC_SLL_##wc(R, diff); \ + } \ + } \ + } \ + break; \ + } \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, R, X, Y); \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ + R##_e = X##_e; \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_s = X##_s; \ + R##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + R##_e = Y##_e; \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + _FP_FRAC_COPY_##wc(R, Y); \ + R##_s = Y##_s; \ + R##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + if (X##_s != Y##_s) \ + { \ + /* +INF + -INF => NAN */ \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + R##_s = X##_s ^ Y##_s; \ + R##_c = FP_CLS_NAN; \ + break; \ + } \ + /* FALLTHRU */ \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + R##_s = X##_s; \ + R##_c = FP_CLS_INF; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + R##_s = Y##_s; \ + R##_c = FP_CLS_INF; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + /* make sure the sign is correct */ \ + if (FP_ROUNDMODE == FP_RND_MINF) \ + R##_s = X##_s | Y##_s; \ + else \ + R##_s = X##_s & Y##_s; \ + R##_c = FP_CLS_ZERO; \ + break; \ + \ + default: \ + abort(); \ + } \ +} while (0) + + +/* + * Main negation routine. FIXME -- when we care about setting exception + * bits reliably, this will not do. We should examine all of the fp classes. + */ + +#define _FP_NEG(fs, wc, R, X) \ + do { \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_c = X##_c; \ + R##_e = X##_e; \ + R##_s = 1 ^ X##_s; \ + } while (0) + + +/* + * Main multiplication routine. The input values should be cooked. + */ + +#define _FP_MUL(fs, wc, R, X, Y) \ +do { \ + R##_s = X##_s ^ Y##_s; \ + switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ + R##_c = FP_CLS_NORMAL; \ + R##_e = X##_e + Y##_e + 1; \ + \ + _FP_MUL_MEAT_##fs(R,X,Y); \ + \ + if (_FP_FRAC_OVERP_##wc(fs, R)) \ + _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ + else \ + R##_e--; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, R, X, Y); \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + R##_s = X##_s; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + R##_s = Y##_s; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(R, Y); \ + R##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + break; \ + \ + default: \ + abort(); \ + } \ +} while (0) + + +/* + * Main division routine. The input values should be cooked. + */ + +#define _FP_DIV(fs, wc, R, X, Y) \ +do { \ + R##_s = X##_s ^ Y##_s; \ + switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ + R##_c = FP_CLS_NORMAL; \ + R##_e = X##_e - Y##_e; \ + \ + _FP_DIV_MEAT_##fs(R,X,Y); \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, R, X, Y); \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R, Y); \ + R##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + R##_c = FP_CLS_ZERO; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + R##_c = FP_CLS_INF; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + break; \ + \ + default: \ + abort(); \ + } \ +} while (0) + + +/* + * Main differential comparison routine. The inputs should be raw not + * cooked. The return is -1,0,1 for normal values, 2 otherwise. + */ + +#define _FP_CMP(fs, wc, ret, X, Y, un) \ + do { \ + /* NANs are unordered */ \ + if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ + { \ + ret = un; \ + } \ + else \ + { \ + int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ + int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ + \ + if (__x_zero && __y_zero) \ + ret = 0; \ + else if (__x_zero) \ + ret = Y##_s ? 1 : -1; \ + else if (__y_zero) \ + ret = X##_s ? -1 : 1; \ + else if (X##_s != Y##_s) \ + ret = X##_s ? -1 : 1; \ + else if (X##_e > Y##_e) \ + ret = X##_s ? -1 : 1; \ + else if (X##_e < Y##_e) \ + ret = X##_s ? 1 : -1; \ + else if (_FP_FRAC_GT_##wc(X, Y)) \ + ret = X##_s ? -1 : 1; \ + else if (_FP_FRAC_GT_##wc(Y, X)) \ + ret = X##_s ? 1 : -1; \ + else \ + ret = 0; \ + } \ + } while (0) + + +/* Simplification for strict equality. */ + +#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ + do { \ + /* NANs are unordered */ \ + if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ + { \ + ret = 1; \ + } \ + else \ + { \ + ret = !(X##_e == Y##_e \ + && _FP_FRAC_EQ_##wc(X, Y) \ + && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \ + } \ + } while (0) + +/* + * Main square root routine. The input value should be cooked. + */ + +#define _FP_SQRT(fs, wc, R, X) \ +do { \ + _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ + _FP_W_TYPE q; \ + switch (X##_c) \ + { \ + case FP_CLS_NAN: \ + R##_s = 0; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + break; \ + case FP_CLS_INF: \ + if (X##_s) \ + { \ + R##_s = 0; \ + R##_c = FP_CLS_NAN; /* sNAN */ \ + } \ + else \ + { \ + R##_s = 0; \ + R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ + } \ + break; \ + case FP_CLS_ZERO: \ + R##_s = X##_s; \ + R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ + break; \ + case FP_CLS_NORMAL: \ + R##_s = 0; \ + if (X##_s) \ + { \ + R##_c = FP_CLS_NAN; /* sNAN */ \ + break; \ + } \ + R##_c = FP_CLS_NORMAL; \ + if (X##_e & 1) \ + _FP_FRAC_SLL_##wc(X, 1); \ + R##_e = X##_e >> 1; \ + _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ + _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ + q = _FP_OVERFLOW_##fs; \ + _FP_FRAC_SLL_##wc(X, 1); \ + _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ + _FP_FRAC_SRL_##wc(R, 1); \ + } \ + } while (0) + +/* + * Convert from FP to integer + */ + +/* "When a NaN, infinity, large positive argument >= 2147483648.0, or + * large negative argument <= -2147483649.0 is converted to an integer, + * the invalid_current bit...should be set and fp_exception_IEEE_754 should + * be raised. If the floating point invalid trap is disabled, no trap occurs + * and a numerical result is generated: if the sign bit of the operand + * is 0, the result is 2147483647; if the sign bit of the operand is 1, + * the result is -2147483648." + * Similarly for conversion to extended ints, except that the boundaries + * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and + * -2^63 for s=1. + * -- SPARC Architecture Manual V9, Appendix B, which specifies how + * SPARCs resolve implementation dependencies in the IEEE-754 spec. + * I don't believe that the code below follows this. I'm not even sure + * it's right! + * It doesn't cope with needing to convert to an n bit integer when there + * is no n bit integer type. Fortunately gcc provides long long so this + * isn't a problem for sparc32. + * I have, however, fixed its NaN handling to conform as above. + * -- PMM 02/1998 + * NB: rsigned is not 'is r declared signed?' but 'should the value stored + * in r be signed or unsigned?'. r is always(?) declared unsigned. + * Comments below are mine, BTW -- PMM + */ +#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ + do { \ + switch (X##_c) \ + { \ + case FP_CLS_NORMAL: \ + if (X##_e < 0) \ + { \ + /* case FP_CLS_NAN: see above! */ \ + case FP_CLS_ZERO: \ + r = 0; \ + } \ + else if (X##_e >= rsize - (rsigned != 0)) \ + { /* overflow */ \ + case FP_CLS_NAN: \ + case FP_CLS_INF: \ + if (rsigned) \ + { \ + r = 1; \ + r <<= rsize - 1; \ + r -= 1 - X##_s; \ + } \ + else \ + { \ + r = 0; \ + if (!X##_s) \ + r = ~r; \ + } \ + } \ + else \ + { \ + if (_FP_W_TYPE_SIZE*wc < rsize) \ + { \ + _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ + r <<= X##_e - _FP_WFRACBITS_##fs; \ + } \ + else \ + { \ + if (X##_e >= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\ + else \ + _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\ + _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ + } \ + if (rsigned && X##_s) \ + r = -r; \ + } \ + break; \ + } \ + } while (0) + +#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ + do { \ + if (r) \ + { \ + X##_c = FP_CLS_NORMAL; \ + \ + if ((X##_s = (r < 0))) \ + r = -r; \ + /* Note that `r' is now considered unsigned, so we don't have \ + to worry about the single signed overflow case. */ \ + \ + if (rsize <= _FP_W_TYPE_SIZE) \ + __FP_CLZ(X##_e, r); \ + else \ + __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \ + (_FP_W_TYPE)r); \ + if (rsize < _FP_W_TYPE_SIZE) \ + X##_e -= (_FP_W_TYPE_SIZE - rsize); \ + X##_e = rsize - X##_e - 1; \ + \ + if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \ + __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \ + r &= ~((_FP_W_TYPE)1 << X##_e); \ + _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \ + _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \ + } \ + else \ + { \ + X##_c = FP_CLS_ZERO, X##_s = 0; \ + } \ + } while (0) + + +#define FP_CONV(dfs,sfs,dwc,swc,D,S) \ + do { \ + _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \ + D##_e = S##_e; \ + D##_c = S##_c; \ + D##_s = S##_s; \ + } while (0) + +/* + * Helper primitives. + */ + +/* Count leading zeros in a word. */ + +#ifndef __FP_CLZ +#if _FP_W_TYPE_SIZE < 64 +/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */ +#define __FP_CLZ(r, x) \ + do { \ + _FP_W_TYPE _t = (x); \ + r = _FP_W_TYPE_SIZE - 1; \ + if (_t > 0xffff) r -= 16; \ + if (_t > 0xffff) _t >>= 16; \ + if (_t > 0xff) r -= 8; \ + if (_t > 0xff) _t >>= 8; \ + if (_t & 0xf0) r -= 4; \ + if (_t & 0xf0) _t >>= 4; \ + if (_t & 0xc) r -= 2; \ + if (_t & 0xc) _t >>= 2; \ + if (_t & 0x2) r -= 1; \ + } while (0) +#else /* not _FP_W_TYPE_SIZE < 64 */ +#define __FP_CLZ(r, x) \ + do { \ + _FP_W_TYPE _t = (x); \ + r = _FP_W_TYPE_SIZE - 1; \ + if (_t > 0xffffffff) r -= 32; \ + if (_t > 0xffffffff) _t >>= 32; \ + if (_t > 0xffff) r -= 16; \ + if (_t > 0xffff) _t >>= 16; \ + if (_t > 0xff) r -= 8; \ + if (_t > 0xff) _t >>= 8; \ + if (_t & 0xf0) r -= 4; \ + if (_t & 0xf0) _t >>= 4; \ + if (_t & 0xc) r -= 2; \ + if (_t & 0xc) _t >>= 2; \ + if (_t & 0x2) r -= 1; \ + } while (0) +#endif /* not _FP_W_TYPE_SIZE < 64 */ +#endif /* ndef __FP_CLZ */ + +#define _FP_DIV_HELP_imm(q, r, n, d) \ + do { \ + q = n / d, r = n % d; \ + } while (0) + diff --git a/trunk/arch/powerpc/include/asm/sfp-machine.h b/trunk/arch/powerpc/math-emu/sfp-machine.h similarity index 83% rename from trunk/arch/powerpc/include/asm/sfp-machine.h rename to trunk/arch/powerpc/math-emu/sfp-machine.h index ced34f1dc8f8..4b17d83cfcdd 100644 --- a/trunk/arch/powerpc/include/asm/sfp-machine.h +++ b/trunk/arch/powerpc/math-emu/sfp-machine.h @@ -79,44 +79,27 @@ * #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y) */ -#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) -#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(S,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(D,R,X,Y,umul_ppmm) -#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) -#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y) /* These macros define what NaN looks like. They're supposed to expand to * a comma-separated set of 32bit unsigned ints that encode NaN. */ -#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) -#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 -#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 -#define _FP_NANSIGN_S 0 -#define _FP_NANSIGN_D 0 -#define _FP_NANSIGN_Q 0 +#define _FP_NANFRAC_S _FP_QNANBIT_S +#define _FP_NANFRAC_D _FP_QNANBIT_D, 0 +#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 #define _FP_KEEPNANFRACP 1 -/* Exception flags. We use the bit positions of the appropriate bits - in the FPSCR, which also correspond to the FE_* bits. This makes - everything easier ;-). */ -#define FP_EX_INVALID (1 << (31 - 2)) -#define FP_EX_INVALID_SNAN EFLAG_VXSNAN -#define FP_EX_INVALID_ISI EFLAG_VXISI -#define FP_EX_INVALID_IDI EFLAG_VXIDI -#define FP_EX_INVALID_ZDZ EFLAG_VXZDZ -#define FP_EX_INVALID_IMZ EFLAG_VXIMZ -#define FP_EX_OVERFLOW (1 << (31 - 3)) -#define FP_EX_UNDERFLOW (1 << (31 - 4)) -#define FP_EX_DIVZERO (1 << (31 - 5)) -#define FP_EX_INEXACT (1 << (31 - 6)) - /* This macro appears to be called when both X and Y are NaNs, and * has to choose one and copy it to R. i386 goes for the larger of the * two, sparc64 just picks Y. I don't understand this at all so I'll * go with sparc64 because it's shorter :-> -- PMM */ -#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ +#define _FP_CHOOSENAN(fs, wc, R, X, Y) \ do { \ R##_s = Y##_s; \ _FP_FRAC_COPY_##wc(R,Y); \ @@ -124,6 +107,62 @@ } while (0) +extern void fp_unpack_d(long *, unsigned long *, unsigned long *, + long *, long *, void *); +extern int fp_pack_d(void *, long, unsigned long, unsigned long, long, long); +extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long); + +#define __FP_UNPACK_RAW_1(fs, X, val) \ + do { \ + union _FP_UNION_##fs *_flo = \ + (union _FP_UNION_##fs *)val; \ + \ + X##_f = _flo->bits.frac; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } while (0) + +#define __FP_UNPACK_RAW_2(fs, X, val) \ + do { \ + union _FP_UNION_##fs *_flo = \ + (union _FP_UNION_##fs *)val; \ + \ + X##_f0 = _flo->bits.frac0; \ + X##_f1 = _flo->bits.frac1; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } while (0) + +#define __FP_UNPACK_S(X,val) \ + do { \ + __FP_UNPACK_RAW_1(S,X,val); \ + _FP_UNPACK_CANONICAL(S,1,X); \ + } while (0) + +#define __FP_UNPACK_D(X,val) \ + fp_unpack_d(&X##_s, &X##_f1, &X##_f0, &X##_e, &X##_c, val) + +#define __FP_PACK_RAW_1(fs, val, X) \ + do { \ + union _FP_UNION_##fs *_flo = \ + (union _FP_UNION_##fs *)val; \ + \ + _flo->bits.frac = X##_f; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } while (0) + +#define __FP_PACK_RAW_2(fs, val, X) \ + do { \ + union _FP_UNION_##fs *_flo = \ + (union _FP_UNION_##fs *)val; \ + \ + _flo->bits.frac0 = X##_f0; \ + _flo->bits.frac1 = X##_f1; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } while (0) + #include #include @@ -143,30 +182,15 @@ #define __FP_PACK_S(val,X) \ ({ int __exc = _FP_PACK_CANONICAL(S,1,X); \ if(!__exc || !__FPU_TRAP_P(__exc)) \ - _FP_PACK_RAW_1_P(S,val,X); \ + __FP_PACK_RAW_1(S,val,X); \ __exc; \ }) #define __FP_PACK_D(val,X) \ - do { \ - _FP_PACK_CANONICAL(D, 2, X); \ - if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) \ - _FP_PACK_RAW_2_P(D, val, X); \ - } while (0) - -#define __FP_PACK_DS(val,X) \ - do { \ - FP_DECL_S(__X); \ - FP_CONV(S, D, 1, 2, __X, X); \ - _FP_PACK_CANONICAL(S, 1, __X); \ - if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) { \ - _FP_UNPACK_CANONICAL(S, 1, __X); \ - FP_CONV(D, S, 2, 1, X, __X); \ - _FP_PACK_CANONICAL(D, 2, X); \ - if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) \ - _FP_PACK_RAW_2_P(D, val, X); \ - } \ - } while (0) + fp_pack_d(val, X##_s, X##_f1, X##_f0, X##_e, X##_c) + +#define __FP_PACK_DS(val,X) \ + fp_pack_ds(val, X##_s, X##_f1, X##_f0, X##_e, X##_c) /* Obtain the current rounding mode. */ #define FP_ROUNDMODE \ diff --git a/trunk/arch/powerpc/math-emu/single.h b/trunk/arch/powerpc/math-emu/single.h new file mode 100644 index 000000000000..f19d99451815 --- /dev/null +++ b/trunk/arch/powerpc/math-emu/single.h @@ -0,0 +1,66 @@ +/* + * Definitions for IEEE Single Precision + */ + +#if _FP_W_TYPE_SIZE < 32 +#error "Here's a nickel kid. Go buy yourself a real computer." +#endif + +#define _FP_FRACBITS_S 24 +#define _FP_FRACXBITS_S (_FP_W_TYPE_SIZE - _FP_FRACBITS_S) +#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S) +#define _FP_WFRACXBITS_S (_FP_W_TYPE_SIZE - _FP_WFRACBITS_S) +#define _FP_EXPBITS_S 8 +#define _FP_EXPBIAS_S 127 +#define _FP_EXPMAX_S 255 +#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2)) +#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1)) +#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S)) + +/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be + chosen by the target machine. */ + +union _FP_UNION_S +{ + float flt; + struct { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned sign : 1; + unsigned exp : _FP_EXPBITS_S; + unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); +#else + unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); + unsigned exp : _FP_EXPBITS_S; + unsigned sign : 1; +#endif + } bits __attribute__((packed)); +}; + +#define FP_DECL_S(X) _FP_DECL(1,X) +#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) +#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) + +#define FP_UNPACK_S(X,val) \ + do { \ + _FP_UNPACK_RAW_1(S,X,val); \ + _FP_UNPACK_CANONICAL(S,1,X); \ + } while (0) + +#define FP_PACK_S(val,X) \ + do { \ + _FP_PACK_CANONICAL(S,1,X); \ + _FP_PACK_RAW_1(S,val,X); \ + } while (0) + +#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) +#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y) +#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y) +#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y) +#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y) +#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X) + +#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un) +#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y) + +#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg) +#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt) diff --git a/trunk/arch/powerpc/math-emu/soft-fp.h b/trunk/arch/powerpc/math-emu/soft-fp.h new file mode 100644 index 000000000000..cca39598f873 --- /dev/null +++ b/trunk/arch/powerpc/math-emu/soft-fp.h @@ -0,0 +1,104 @@ +#ifndef SOFT_FP_H +#define SOFT_FP_H + +#include "sfp-machine.h" + +#define _FP_WORKBITS 3 +#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) +#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) +#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) +#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) + +#ifndef FP_RND_NEAREST +# define FP_RND_NEAREST 0 +# define FP_RND_ZERO 1 +# define FP_RND_PINF 2 +# define FP_RND_MINF 3 +#ifndef FP_ROUNDMODE +# define FP_ROUNDMODE FP_RND_NEAREST +#endif +#endif + +#define _FP_ROUND_NEAREST(wc, X) \ +({ int __ret = 0; \ + int __frac = _FP_FRAC_LOW_##wc(X) & 15; \ + if (__frac & 7) { \ + __ret = EFLAG_INEXACT; \ + if ((__frac & 7) != _FP_WORK_ROUND) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ + else if (__frac & _FP_WORK_LSB) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ + } \ + __ret; \ +}) + +#define _FP_ROUND_ZERO(wc, X) \ +({ int __ret = 0; \ + if (_FP_FRAC_LOW_##wc(X) & 7) \ + __ret = EFLAG_INEXACT; \ + __ret; \ +}) + +#define _FP_ROUND_PINF(wc, X) \ +({ int __ret = EFLAG_INEXACT; \ + if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ + else __ret = 0; \ + __ret; \ +}) + +#define _FP_ROUND_MINF(wc, X) \ +({ int __ret = EFLAG_INEXACT; \ + if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ + else __ret = 0; \ + __ret; \ +}) + +#define _FP_ROUND(wc, X) \ +({ int __ret = 0; \ + switch (FP_ROUNDMODE) \ + { \ + case FP_RND_NEAREST: \ + __ret |= _FP_ROUND_NEAREST(wc,X); \ + break; \ + case FP_RND_ZERO: \ + __ret |= _FP_ROUND_ZERO(wc,X); \ + break; \ + case FP_RND_PINF: \ + __ret |= _FP_ROUND_PINF(wc,X); \ + break; \ + case FP_RND_MINF: \ + __ret |= _FP_ROUND_MINF(wc,X); \ + break; \ + }; \ + __ret; \ +}) + +#define FP_CLS_NORMAL 0 +#define FP_CLS_ZERO 1 +#define FP_CLS_INF 2 +#define FP_CLS_NAN 3 + +#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) + +#include "op-1.h" +#include "op-2.h" +#include "op-4.h" +#include "op-common.h" + +/* Sigh. Silly things longlong.h needs. */ +#define UWtype _FP_W_TYPE +#define W_TYPE_SIZE _FP_W_TYPE_SIZE + +typedef int SItype __attribute__((mode(SI))); +typedef int DItype __attribute__((mode(DI))); +typedef unsigned int USItype __attribute__((mode(SI))); +typedef unsigned int UDItype __attribute__((mode(DI))); +#if _FP_W_TYPE_SIZE == 32 +typedef unsigned int UHWtype __attribute__((mode(HI))); +#elif _FP_W_TYPE_SIZE == 64 +typedef USItype UHWtype; +#endif + +#endif diff --git a/trunk/arch/powerpc/math-emu/stfs.c b/trunk/arch/powerpc/math-emu/stfs.c index 6122147356d1..8689aa48ef69 100644 --- a/trunk/arch/powerpc/math-emu/stfs.c +++ b/trunk/arch/powerpc/math-emu/stfs.c @@ -2,24 +2,23 @@ #include #include -#include -#include -#include -#include +#include "soft-fp.h" +#include "double.h" +#include "single.h" int stfs(void *frS, void *ea) { FP_DECL_D(A); FP_DECL_S(R); - FP_DECL_EX; float f; + int err; #ifdef DEBUG printk("%s: S %p, ea %p\n", __func__, frS, ea); #endif - FP_UNPACK_DP(A, frS); + __FP_UNPACK_D(A, frS); #ifdef DEBUG printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c); @@ -31,12 +30,12 @@ stfs(void *frS, void *ea) printk("R: %ld %lu %ld (%ld)\n", R_s, R_f, R_e, R_c); #endif - _FP_PACK_CANONICAL(S, 1, R); - if (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS)) { - _FP_PACK_RAW_1_P(S, &f, R); + err = _FP_PACK_CANONICAL(S, 1, R); + if (!err || !__FPU_TRAP_P(err)) { + __FP_PACK_RAW_1(S, &f, R); if (copy_to_user(ea, &f, sizeof(float))) return -EFAULT; } - return FP_CUR_EXCEPTIONS; + return err; } diff --git a/trunk/arch/powerpc/math-emu/types.c b/trunk/arch/powerpc/math-emu/types.c new file mode 100644 index 000000000000..e1ed15d829db --- /dev/null +++ b/trunk/arch/powerpc/math-emu/types.c @@ -0,0 +1,51 @@ +#include "soft-fp.h" +#include "double.h" +#include "single.h" + +void +fp_unpack_d(long *_s, unsigned long *_f1, unsigned long *_f0, + long *_e, long *_c, void *val) +{ + FP_DECL_D(X); + + __FP_UNPACK_RAW_2(D, X, val); + + _FP_UNPACK_CANONICAL(D, 2, X); + + *_s = X_s; + *_f1 = X_f1; + *_f0 = X_f0; + *_e = X_e; + *_c = X_c; +} + +int +fp_pack_d(void *val, long X_s, unsigned long X_f1, + unsigned long X_f0, long X_e, long X_c) +{ + int exc; + + exc = _FP_PACK_CANONICAL(D, 2, X); + if (!exc || !__FPU_TRAP_P(exc)) + __FP_PACK_RAW_2(D, val, X); + return exc; +} + +int +fp_pack_ds(void *val, long X_s, unsigned long X_f1, + unsigned long X_f0, long X_e, long X_c) +{ + FP_DECL_S(__X); + int exc; + + FP_CONV(S, D, 1, 2, __X, X); + exc = _FP_PACK_CANONICAL(S, 1, __X); + if (!exc || !__FPU_TRAP_P(exc)) { + _FP_UNPACK_CANONICAL(S, 1, __X); + FP_CONV(D, S, 2, 1, X, __X); + exc |= _FP_PACK_CANONICAL(D, 2, X); + if (!exc || !__FPU_TRAP_P(exc)) + __FP_PACK_RAW_2(D, val, X); + } + return exc; +} diff --git a/trunk/arch/powerpc/math-emu/udivmodti4.c b/trunk/arch/powerpc/math-emu/udivmodti4.c index 6172044ab003..7e112dc1e2f2 100644 --- a/trunk/arch/powerpc/math-emu/udivmodti4.c +++ b/trunk/arch/powerpc/math-emu/udivmodti4.c @@ -1,6 +1,6 @@ /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */ -#include +#include "soft-fp.h" #undef count_leading_zeros #define count_leading_zeros __FP_CLZ diff --git a/trunk/arch/powerpc/mm/fsl_booke_mmu.c b/trunk/arch/powerpc/mm/fsl_booke_mmu.c index 23cee39534fd..ce10e2b1b902 100644 --- a/trunk/arch/powerpc/mm/fsl_booke_mmu.c +++ b/trunk/arch/powerpc/mm/fsl_booke_mmu.c @@ -202,7 +202,7 @@ adjust_total_lowmem(void) cam_max_size = max_lowmem_size; /* adjust lowmem size to max_lowmem_size */ - ram = min(max_lowmem_size, total_lowmem); + ram = min(max_lowmem_size, (phys_addr_t)total_lowmem); /* Calculate CAM values */ __cam0 = 1UL << 2 * (__ilog2(ram) / 2); @@ -225,8 +225,7 @@ adjust_total_lowmem(void) printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb," " CAM2=%ldMb residual: %ldMb\n", __cam0 >> 20, __cam1 >> 20, __cam2 >> 20, - (long int)((total_lowmem - __cam0 - __cam1 - __cam2) - >> 20)); + (total_lowmem - __cam0 - __cam1 - __cam2) >> 20); __max_low_memory = __cam0 + __cam1 + __cam2; __initial_memory_limit_addr = memstart_addr + __max_low_memory; } diff --git a/trunk/arch/powerpc/mm/gup.c b/trunk/arch/powerpc/mm/gup.c index 28a114db3ba0..9fdf4d6335e4 100644 --- a/trunk/arch/powerpc/mm/gup.c +++ b/trunk/arch/powerpc/mm/gup.c @@ -41,7 +41,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, page = pte_page(pte); if (!page_cache_get_speculative(page)) return 0; - if (unlikely(pte_val(pte) != pte_val(*ptep))) { + if (unlikely(pte != *ptep)) { put_page(page); return 0; } @@ -92,7 +92,7 @@ static noinline int gup_huge_pte(pte_t *ptep, struct hstate *hstate, *nr -= refs; return 0; } - if (unlikely(pte_val(pte) != pte_val(*ptep))) { + if (unlikely(pte != *ptep)) { /* Could be optimized better */ while (*nr) { put_page(page); @@ -237,8 +237,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, pgd_t pgd = *pgdp; VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift); - pr_debug(" %016lx: normal pgd %p\n", addr, - (void *)pgd_val(pgd)); + pr_debug(" %016lx: normal pgd %p\n", addr, (void *)pgd); next = pgd_addr_end(addr, end); if (pgd_none(pgd)) goto slow; diff --git a/trunk/arch/powerpc/mm/hash_low_32.S b/trunk/arch/powerpc/mm/hash_low_32.S index 7bffb70b9fe2..b9ba7d930801 100644 --- a/trunk/arch/powerpc/mm/hash_low_32.S +++ b/trunk/arch/powerpc/mm/hash_low_32.S @@ -75,7 +75,7 @@ _GLOBAL(hash_page_sync) * Returns to the caller if the access is illegal or there is no * mapping for the address. Otherwise it places an appropriate PTE * in the hash table and returns from the exception. - * Uses r0, r3 - r8, r10, ctr, lr. + * Uses r0, r3 - r8, ctr, lr. */ .text _GLOBAL(hash_page) @@ -106,15 +106,9 @@ _GLOBAL(hash_page) addi r5,r5,swapper_pg_dir@l /* kernel page table */ rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */ 112: add r5,r5,r7 /* convert to phys addr */ -#ifndef CONFIG_PTE_64BIT rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ lwz r8,0(r5) /* get pmd entry */ rlwinm. r8,r8,0,0,19 /* extract address of pte page */ -#else - rlwinm r8,r4,13,19,29 /* Compute pgdir/pmd offset */ - lwzx r8,r8,r5 /* Get L1 entry */ - rlwinm. r8,r8,0,0,20 /* extract pt base address */ -#endif #ifdef CONFIG_SMP beq- hash_page_out /* return if no mapping */ #else @@ -124,11 +118,7 @@ _GLOBAL(hash_page) to the address following the rfi. */ beqlr- #endif -#ifndef CONFIG_PTE_64BIT rlwimi r8,r4,22,20,29 /* insert next 10 bits of address */ -#else - rlwimi r8,r4,23,20,28 /* compute pte address */ -#endif rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE @@ -137,15 +127,9 @@ _GLOBAL(hash_page) * because almost always, there won't be a permission violation * and there won't already be an HPTE, and thus we will have * to update the PTE to set _PAGE_HASHPTE. -- paulus. - * - * If PTE_64BIT is set, the low word is the flags word; use that - * word for locking since it contains all the interesting bits. */ -#if (PTE_FLAGS_OFFSET != 0) - addi r8,r8,PTE_FLAGS_OFFSET -#endif retry: - lwarx r6,0,r8 /* get linux-style pte, flag word */ + lwarx r6,0,r8 /* get linux-style pte */ andc. r5,r3,r6 /* check access & ~permission */ #ifdef CONFIG_SMP bne- hash_page_out /* return if access not permitted */ @@ -153,15 +137,6 @@ retry: bnelr- #endif or r5,r0,r6 /* set accessed/dirty bits */ -#ifdef CONFIG_PTE_64BIT -#ifdef CONFIG_SMP - subf r10,r6,r8 /* create false data dependency */ - subi r10,r10,PTE_FLAGS_OFFSET - lwzx r10,r6,r10 /* Get upper PTE word */ -#else - lwz r10,-PTE_FLAGS_OFFSET(r8) -#endif /* CONFIG_SMP */ -#endif /* CONFIG_PTE_64BIT */ stwcx. r5,0,r8 /* attempt to update PTE */ bne- retry /* retry if someone got there first */ @@ -228,9 +203,9 @@ _GLOBAL(add_hash_page) * we can't take a hash table miss (assuming the code is * covered by a BAT). -- paulus */ - mfmsr r9 + mfmsr r10 SYNC - rlwinm r0,r9,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ rlwinm r0,r0,0,28,26 /* clear MSR_DR */ mtmsr r0 SYNC_601 @@ -239,14 +214,14 @@ _GLOBAL(add_hash_page) tophys(r7,0) #ifdef CONFIG_SMP - addis r6,r7,mmu_hash_lock@ha - addi r6,r6,mmu_hash_lock@l -10: lwarx r0,0,r6 /* take the mmu_hash_lock */ + addis r9,r7,mmu_hash_lock@ha + addi r9,r9,mmu_hash_lock@l +10: lwarx r0,0,r9 /* take the mmu_hash_lock */ cmpi 0,r0,0 bne- 11f - stwcx. r8,0,r6 + stwcx. r8,0,r9 beq+ 12f -11: lwz r0,0(r6) +11: lwz r0,0(r9) cmpi 0,r0,0 beq 10b b 11b @@ -259,24 +234,10 @@ _GLOBAL(add_hash_page) * HPTE, so we just unlock and return. */ mr r8,r5 -#ifndef CONFIG_PTE_64BIT rlwimi r8,r4,22,20,29 -#else - rlwimi r8,r4,23,20,28 - addi r8,r8,PTE_FLAGS_OFFSET -#endif 1: lwarx r6,0,r8 andi. r0,r6,_PAGE_HASHPTE bne 9f /* if HASHPTE already set, done */ -#ifdef CONFIG_PTE_64BIT -#ifdef CONFIG_SMP - subf r10,r6,r8 /* create false data dependency */ - subi r10,r10,PTE_FLAGS_OFFSET - lwzx r10,r6,r10 /* Get upper PTE word */ -#else - lwz r10,-PTE_FLAGS_OFFSET(r8) -#endif /* CONFIG_SMP */ -#endif /* CONFIG_PTE_64BIT */ ori r5,r6,_PAGE_HASHPTE stwcx. r5,0,r8 bne- 1b @@ -285,15 +246,13 @@ _GLOBAL(add_hash_page) 9: #ifdef CONFIG_SMP - addis r6,r7,mmu_hash_lock@ha - addi r6,r6,mmu_hash_lock@l eieio li r0,0 - stw r0,0(r6) /* clear mmu_hash_lock */ + stw r0,0(r9) /* clear mmu_hash_lock */ #endif /* reenable interrupts and DR */ - mtmsr r9 + mtmsr r10 SYNC_601 isync @@ -308,8 +267,7 @@ _GLOBAL(add_hash_page) * r5 contains the linux PTE, r6 contains the old value of the * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the * offset to be added to addresses (0 if the MMU is on, - * -KERNELBASE if it is off). r10 contains the upper half of - * the PTE if CONFIG_PTE_64BIT. + * -KERNELBASE if it is off). * On SMP, the caller should have the mmu_hash_lock held. * We assume that the caller has (or will) set the _PAGE_HASHPTE * bit in the linux PTE in memory. The value passed in r6 should @@ -327,7 +285,7 @@ Hash_bits = 12 /* e.g. 256kB hash table */ Hash_msk = (((1 << Hash_bits) - 1) * 64) /* defines for the PTE format for 32-bit PPCs */ -#define HPTE_SIZE 8 +#define PTE_SIZE 8 #define PTEG_SIZE 64 #define LG_PTEG_SIZE 6 #define LDPTEu lwzu @@ -355,11 +313,6 @@ _GLOBAL(create_hpte) BEGIN_FTR_SECTION ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */ END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) -#ifdef CONFIG_PTE_64BIT - /* Put the XPN bits into the PTE */ - rlwimi r8,r10,8,20,22 - rlwimi r8,r10,2,29,29 -#endif /* Construct the high word of the PPC-style PTE (r5) */ rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ @@ -389,8 +342,8 @@ _GLOBAL(hash_page_patch_A) /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ mtctr r0 - addi r4,r3,-HPTE_SIZE -1: LDPTEu r6,HPTE_SIZE(r4) /* get next PTE */ + addi r4,r3,-PTE_SIZE +1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */ CMPPTE 0,r6,r5 bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ beq+ found_slot @@ -400,9 +353,9 @@ _GLOBAL(hash_page_patch_A) _GLOBAL(hash_page_patch_B) xoris r4,r3,Hash_msk>>16 /* compute secondary hash */ xori r4,r4,(-PTEG_SIZE & 0xffff) - addi r4,r4,-HPTE_SIZE + addi r4,r4,-PTE_SIZE mtctr r0 -2: LDPTEu r6,HPTE_SIZE(r4) +2: LDPTEu r6,PTE_SIZE(r4) CMPPTE 0,r6,r5 bdnzf 2,2b beq+ found_slot @@ -410,8 +363,8 @@ _GLOBAL(hash_page_patch_B) /* Search the primary PTEG for an empty slot */ 10: mtctr r0 - addi r4,r3,-HPTE_SIZE /* search primary PTEG */ -1: LDPTEu r6,HPTE_SIZE(r4) /* get next PTE */ + addi r4,r3,-PTE_SIZE /* search primary PTEG */ +1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */ TST_V(r6) /* test valid bit */ bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ beq+ found_empty @@ -427,9 +380,9 @@ _GLOBAL(hash_page_patch_B) _GLOBAL(hash_page_patch_C) xoris r4,r3,Hash_msk>>16 /* compute secondary hash */ xori r4,r4,(-PTEG_SIZE & 0xffff) - addi r4,r4,-HPTE_SIZE + addi r4,r4,-PTE_SIZE mtctr r0 -2: LDPTEu r6,HPTE_SIZE(r4) +2: LDPTEu r6,PTE_SIZE(r4) TST_V(r6) bdnzf 2,2b beq+ found_empty @@ -456,11 +409,11 @@ _GLOBAL(hash_page_patch_C) 1: addis r4,r7,next_slot@ha /* get next evict slot */ lwz r6,next_slot@l(r4) - addi r6,r6,HPTE_SIZE /* search for candidate */ - andi. r6,r6,7*HPTE_SIZE + addi r6,r6,PTE_SIZE /* search for candidate */ + andi. r6,r6,7*PTE_SIZE stw r6,next_slot@l(r4) add r4,r3,r6 - LDPTE r0,HPTE_SIZE/2(r4) /* get PTE second word */ + LDPTE r0,PTE_SIZE/2(r4) /* get PTE second word */ clrrwi r0,r0,12 lis r6,etext@h ori r6,r6,etext@l /* get etext */ @@ -473,7 +426,7 @@ _GLOBAL(hash_page_patch_C) found_empty: STPTE r5,0(r4) found_slot: - STPTE r8,HPTE_SIZE/2(r4) + STPTE r8,PTE_SIZE/2(r4) #else /* CONFIG_SMP */ /* @@ -499,7 +452,7 @@ found_slot: STPTE r5,0(r4) sync TLBSYNC - STPTE r8,HPTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */ + STPTE r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */ sync SET_V(r5) STPTE r5,0(r4) /* finally set V bit in PTE */ @@ -546,18 +499,14 @@ _GLOBAL(flush_hash_pages) isync /* First find a PTE in the range that has _PAGE_HASHPTE set */ -#ifndef CONFIG_PTE_64BIT rlwimi r5,r4,22,20,29 -#else - rlwimi r5,r4,23,20,28 -#endif -1: lwz r0,PTE_FLAGS_OFFSET(r5) +1: lwz r0,0(r5) cmpwi cr1,r6,1 andi. r0,r0,_PAGE_HASHPTE bne 2f ble cr1,19f addi r4,r4,0x1000 - addi r5,r5,PTE_SIZE + addi r5,r5,4 addi r6,r6,-1 b 1b @@ -596,10 +545,7 @@ _GLOBAL(flush_hash_pages) * already clear, we're done (for this pte). If not, * clear it (atomically) and proceed. -- paulus. */ -#if (PTE_FLAGS_OFFSET != 0) - addi r5,r5,PTE_FLAGS_OFFSET -#endif -33: lwarx r8,0,r5 /* fetch the pte flags word */ +33: lwarx r8,0,r5 /* fetch the pte */ andi. r0,r8,_PAGE_HASHPTE beq 8f /* done if HASHPTE is already clear */ rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ @@ -616,8 +562,8 @@ _GLOBAL(flush_hash_patch_A) /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ li r0,8 /* PTEs/group */ mtctr r0 - addi r12,r8,-HPTE_SIZE -1: LDPTEu r0,HPTE_SIZE(r12) /* get next PTE */ + addi r12,r8,-PTE_SIZE +1: LDPTEu r0,PTE_SIZE(r12) /* get next PTE */ CMPPTE 0,r0,r11 bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ beq+ 3f @@ -628,9 +574,9 @@ _GLOBAL(flush_hash_patch_A) _GLOBAL(flush_hash_patch_B) xoris r12,r8,Hash_msk>>16 /* compute secondary hash */ xori r12,r12,(-PTEG_SIZE & 0xffff) - addi r12,r12,-HPTE_SIZE + addi r12,r12,-PTE_SIZE mtctr r0 -2: LDPTEu r0,HPTE_SIZE(r12) +2: LDPTEu r0,PTE_SIZE(r12) CMPPTE 0,r0,r11 bdnzf 2,2b xori r11,r11,PTE_H /* clear H again */ @@ -644,7 +590,7 @@ _GLOBAL(flush_hash_patch_B) 8: ble cr1,9f /* if all ptes checked */ 81: addi r6,r6,-1 - addi r5,r5,PTE_SIZE + addi r5,r5,4 /* advance to next pte */ addi r4,r4,0x1000 lwz r0,0(r5) /* check next pte */ cmpwi cr1,r6,1 diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index 5c64af174752..8920eea34528 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -194,7 +194,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, unsigned long tprot = prot; /* Make kernel text executable */ - if (overlaps_kernel_text(vaddr, vaddr + step)) + if (in_kernel_text(vaddr)) tprot &= ~HPTE_R_N; hash = hpt_hash(va, shift, ssize); @@ -348,7 +348,6 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, return 0; } -#ifdef CONFIG_HUGETLB_PAGE /* Scan for 16G memory blocks that have been set aside for huge pages * and reserve those blocks for 16G huge pages. */ @@ -386,7 +385,6 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, add_gpage(phys_addr, block_size, expected_pages); return 0; } -#endif /* CONFIG_HUGETLB_PAGE */ static void __init htab_init_page_sizes(void) { @@ -541,7 +539,7 @@ static unsigned long __init htab_get_table_size(void) void create_section_mapping(unsigned long start, unsigned long end) { BUG_ON(htab_bolt_mapping(start, end, __pa(start), - pgprot_val(PAGE_KERNEL), mmu_linear_psize, + PAGE_KERNEL, mmu_linear_psize, mmu_kernel_ssize)); } @@ -649,7 +647,7 @@ void __init htab_initialize(void) mtspr(SPRN_SDR1, _SDR1); } - prot = pgprot_val(PAGE_KERNEL); + prot = PAGE_KERNEL; #ifdef CONFIG_DEBUG_PAGEALLOC linear_map_hash_count = lmb_end_of_DRAM() >> PAGE_SHIFT; diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index a117024ab8cd..f1c2d55b4377 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -128,37 +128,29 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, return 0; } - -static pud_t *hpud_offset(pgd_t *pgd, unsigned long addr, struct hstate *hstate) -{ - if (huge_page_shift(hstate) < PUD_SHIFT) - return pud_offset(pgd, addr); - else - return (pud_t *) pgd; -} -static pud_t *hpud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long addr, - struct hstate *hstate) -{ - if (huge_page_shift(hstate) < PUD_SHIFT) - return pud_alloc(mm, pgd, addr); - else - return (pud_t *) pgd; -} -static pmd_t *hpmd_offset(pud_t *pud, unsigned long addr, struct hstate *hstate) +/* Base page size affects how we walk hugetlb page tables */ +#ifdef CONFIG_PPC_64K_PAGES +#define hpmd_offset(pud, addr, h) pmd_offset(pud, addr) +#define hpmd_alloc(mm, pud, addr, h) pmd_alloc(mm, pud, addr) +#else +static inline +pmd_t *hpmd_offset(pud_t *pud, unsigned long addr, struct hstate *hstate) { - if (huge_page_shift(hstate) < PMD_SHIFT) + if (huge_page_shift(hstate) == PAGE_SHIFT_64K) return pmd_offset(pud, addr); else return (pmd_t *) pud; } -static pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr, - struct hstate *hstate) +static inline +pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr, + struct hstate *hstate) { - if (huge_page_shift(hstate) < PMD_SHIFT) + if (huge_page_shift(hstate) == PAGE_SHIFT_64K) return pmd_alloc(mm, pud, addr); else return (pmd_t *) pud; } +#endif /* Build list of addresses of gigantic pages. This function is used in early * boot before the buddy or bootmem allocator is setup. @@ -212,7 +204,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) pg = pgd_offset(mm, addr); if (!pgd_none(*pg)) { - pu = hpud_offset(pg, addr, hstate); + pu = pud_offset(pg, addr); if (!pud_none(*pu)) { pm = hpmd_offset(pu, addr, hstate); if (!pmd_none(*pm)) @@ -241,7 +233,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, addr &= hstate->mask; pg = pgd_offset(mm, addr); - pu = hpud_alloc(mm, pg, addr, hstate); + pu = pud_alloc(mm, pg, addr); if (pu) { pm = hpmd_alloc(mm, pu, addr, hstate); @@ -324,7 +316,13 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, pud = pud_offset(pgd, addr); do { next = pud_addr_end(addr, end); - if (shift < PMD_SHIFT) { +#ifdef CONFIG_PPC_64K_PAGES + if (pud_none_or_clear_bad(pud)) + continue; + hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling, + psize); +#else + if (shift == PAGE_SHIFT_64K) { if (pud_none_or_clear_bad(pud)) continue; hugetlb_free_pmd_range(tlb, pud, addr, next, floor, @@ -334,6 +332,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, continue; free_hugepte_range(tlb, (hugepd_t *)pud, psize); } +#endif } while (pud++, addr = next, addr != end); start &= PGDIR_MASK; @@ -423,15 +422,9 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, psize = get_slice_psize(tlb->mm, addr); BUG_ON(!mmu_huge_psizes[psize]); next = pgd_addr_end(addr, end); - if (mmu_psize_to_shift(psize) < PUD_SHIFT) { - if (pgd_none_or_clear_bad(pgd)) - continue; - hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); - } else { - if (pgd_none(*pgd)) - continue; - free_hugepte_range(tlb, (hugepd_t *)pgd, psize); - } + if (pgd_none_or_clear_bad(pgd)) + continue; + hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); } while (pgd++, addr = next, addr != end); } diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index 3e6a6543f53a..036fe2f10c77 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -228,8 +228,8 @@ int __meminit vmemmap_populate(struct page *start_page, start, p, __pa(p)); mapped = htab_bolt_mapping(start, start + page_size, __pa(p), - pgprot_val(PAGE_KERNEL), - mmu_vmemmap_psize, mmu_kernel_ssize); + PAGE_KERNEL, mmu_vmemmap_psize, + mmu_kernel_ssize); BUG_ON(mapped < 0); } diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 98d7bf99533a..1c93c255873b 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -75,10 +75,11 @@ static inline pte_t *virt_to_kpte(unsigned long vaddr) int page_is_ram(unsigned long pfn) { + unsigned long paddr = (pfn << PAGE_SHIFT); + #ifndef CONFIG_PPC64 /* XXX for now */ - return pfn < max_pfn; + return paddr < __pa(high_memory); #else - unsigned long paddr = (pfn << PAGE_SHIFT); int i; for (i=0; i < lmb.memory.cnt; i++) { unsigned long base; diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 6cf5c71c431f..d9a181351332 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -89,46 +89,6 @@ static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, return 0; } -/* - * get_active_region_work_fn - A helper function for get_node_active_region - * Returns datax set to the start_pfn and end_pfn if they contain - * the initial value of datax->start_pfn between them - * @start_pfn: start page(inclusive) of region to check - * @end_pfn: end page(exclusive) of region to check - * @datax: comes in with ->start_pfn set to value to search for and - * goes out with active range if it contains it - * Returns 1 if search value is in range else 0 - */ -static int __init get_active_region_work_fn(unsigned long start_pfn, - unsigned long end_pfn, void *datax) -{ - struct node_active_region *data; - data = (struct node_active_region *)datax; - - if (start_pfn <= data->start_pfn && end_pfn > data->start_pfn) { - data->start_pfn = start_pfn; - data->end_pfn = end_pfn; - return 1; - } - return 0; - -} - -/* - * get_node_active_region - Return active region containing start_pfn - * @start_pfn: The page to return the region for. - * @node_ar: Returned set to the active region containing start_pfn - */ -static void __init get_node_active_region(unsigned long start_pfn, - struct node_active_region *node_ar) -{ - int nid = early_pfn_to_nid(start_pfn); - - node_ar->nid = nid; - node_ar->start_pfn = start_pfn; - work_with_active_regions(nid, get_active_region_work_fn, node_ar); -} - static void __cpuinit map_cpu_to_node(int cpu, int node) { numa_cpu_lookup_table[cpu] = node; @@ -190,21 +150,6 @@ static const int *of_get_associativity(struct device_node *dev) return of_get_property(dev, "ibm,associativity", NULL); } -/* - * Returns the property linux,drconf-usable-memory if - * it exists (the property exists only in kexec/kdump kernels, - * added by kexec-tools) - */ -static const u32 *of_get_usable_memory(struct device_node *memory) -{ - const u32 *prop; - u32 len; - prop = of_get_property(memory, "linux,drconf-usable-memory", &len); - if (!prop || len < sizeof(unsigned int)) - return 0; - return prop; -} - /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa * info is found. */ @@ -541,30 +486,15 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, return lmb_end_of_DRAM() - start; } -/* - * Reads the counter for a given entry in - * linux,drconf-usable-memory property - */ -static inline int __init read_usm_ranges(const u32 **usm) -{ - /* - * For each lmb in ibm,dynamic-memory a corresponding - * entry in linux,drconf-usable-memory property contains - * a counter followed by that many (base, size) duple. - * read the counter from linux,drconf-usable-memory - */ - return read_n_cells(n_mem_size_cells, usm); -} - /* * Extract NUMA information from the ibm,dynamic-reconfiguration-memory * node. This assumes n_mem_{addr,size}_cells have been set. */ static void __init parse_drconf_memory(struct device_node *memory) { - const u32 *dm, *usm; - unsigned int n, rc, ranges, is_kexec_kdump = 0; - unsigned long lmb_size, base, size, sz; + const u32 *dm; + unsigned int n, rc; + unsigned long lmb_size, size; int nid; struct assoc_arrays aa; @@ -580,11 +510,6 @@ static void __init parse_drconf_memory(struct device_node *memory) if (rc) return; - /* check if this is a kexec/kdump kernel */ - usm = of_get_usable_memory(memory); - if (usm != NULL) - is_kexec_kdump = 1; - for (; n != 0; --n) { struct of_drconf_cell drmem; @@ -596,31 +521,21 @@ static void __init parse_drconf_memory(struct device_node *memory) || !(drmem.flags & DRCONF_MEM_ASSIGNED)) continue; - base = drmem.base_addr; - size = lmb_size; - ranges = 1; + nid = of_drconf_to_nid_single(&drmem, &aa); - if (is_kexec_kdump) { - ranges = read_usm_ranges(&usm); - if (!ranges) /* there are no (base, size) duple */ - continue; - } - do { - if (is_kexec_kdump) { - base = read_n_cells(n_mem_addr_cells, &usm); - size = read_n_cells(n_mem_size_cells, &usm); - } - nid = of_drconf_to_nid_single(&drmem, &aa); - fake_numa_create_new_node( - ((base + size) >> PAGE_SHIFT), + fake_numa_create_new_node( + ((drmem.base_addr + lmb_size) >> PAGE_SHIFT), &nid); - node_set_online(nid); - sz = numa_enforce_memory_limit(base, size); - if (sz) - add_active_range(nid, base >> PAGE_SHIFT, - (base >> PAGE_SHIFT) - + (sz >> PAGE_SHIFT)); - } while (--ranges); + + node_set_online(nid); + + size = numa_enforce_memory_limit(drmem.base_addr, lmb_size); + if (!size) + continue; + + add_active_range(nid, drmem.base_addr >> PAGE_SHIFT, + (drmem.base_addr >> PAGE_SHIFT) + + (size >> PAGE_SHIFT)); } } @@ -922,50 +837,38 @@ void __init do_init_bootmem(void) start_pfn, end_pfn); free_bootmem_with_active_regions(nid, end_pfn); - } - /* Mark reserved regions */ - for (i = 0; i < lmb.reserved.cnt; i++) { - unsigned long physbase = lmb.reserved.region[i].base; - unsigned long size = lmb.reserved.region[i].size; - unsigned long start_pfn = physbase >> PAGE_SHIFT; - unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT); - struct node_active_region node_ar; - - get_node_active_region(start_pfn, &node_ar); - while (start_pfn < end_pfn) { - /* - * if reserved region extends past active region - * then trim size to active region - */ - if (end_pfn > node_ar.end_pfn) - size = (node_ar.end_pfn << PAGE_SHIFT) - - (start_pfn << PAGE_SHIFT); - dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size, - node_ar.nid); - reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, - size, BOOTMEM_DEFAULT); - /* - * if reserved region is contained in the active region - * then done. - */ - if (end_pfn <= node_ar.end_pfn) - break; - - /* - * reserved region extends past the active region - * get next active region that contains this - * reserved region - */ - start_pfn = node_ar.end_pfn; - physbase = start_pfn << PAGE_SHIFT; - get_node_active_region(start_pfn, &node_ar); - } + /* Mark reserved regions on this node */ + for (i = 0; i < lmb.reserved.cnt; i++) { + unsigned long physbase = lmb.reserved.region[i].base; + unsigned long size = lmb.reserved.region[i].size; + unsigned long start_paddr = start_pfn << PAGE_SHIFT; + unsigned long end_paddr = end_pfn << PAGE_SHIFT; - } + if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid && + early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid) + continue; + + if (physbase < end_paddr && + (physbase+size) > start_paddr) { + /* overlaps */ + if (physbase < start_paddr) { + size -= start_paddr - physbase; + physbase = start_paddr; + } + + if (size > end_paddr - physbase) + size = end_paddr - physbase; + + dbg("reserve_bootmem %lx %lx\n", physbase, + size); + reserve_bootmem_node(NODE_DATA(nid), physbase, + size, BOOTMEM_DEFAULT); + } + } - for_each_online_node(nid) sparse_memory_present_with_active_regions(nid); + } } void __init paging_init(void) diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index c31d6d26f0b5..2001abdb1912 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -73,7 +73,7 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa); #endif /* HAVE_TLBCAM */ #ifdef CONFIG_PTE_64BIT -/* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ +/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ #define PGDIR_ORDER 1 #else #define PGDIR_ORDER 0 @@ -288,7 +288,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) } /* - * Map in a big chunk of physical memory starting at KERNELBASE. + * Map in all of physical memory starting at KERNELBASE. */ void __init mapin_ram(void) { diff --git a/trunk/arch/powerpc/mm/tlb_32.c b/trunk/arch/powerpc/mm/tlb_32.c index f9a47fee3927..eb4b512d65fa 100644 --- a/trunk/arch/powerpc/mm/tlb_32.c +++ b/trunk/arch/powerpc/mm/tlb_32.c @@ -45,7 +45,6 @@ void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) flush_hash_pages(mm->context.id, addr, ptephys, 1); } } -EXPORT_SYMBOL(flush_hash_entry); /* * Called by ptep_set_access_flags, must flush on CPUs for which the diff --git a/trunk/arch/powerpc/oprofile/cell/vma_map.c b/trunk/arch/powerpc/oprofile/cell/vma_map.c index 258fa4411e9e..fff66662d021 100644 --- a/trunk/arch/powerpc/oprofile/cell/vma_map.c +++ b/trunk/arch/powerpc/oprofile/cell/vma_map.c @@ -229,7 +229,7 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu, */ overlay_tbl_offset = vma_map_lookup(map, ovly_table_sym, aSpu, &grd_val); - if (overlay_tbl_offset > 0x10000000) { + if (overlay_tbl_offset < 0) { printk(KERN_ERR "SPU_PROF: " "%s, line %d: Error finding SPU overlay table\n", __func__, __LINE__); diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 3e3d91f536e0..446a8bbb847b 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -64,7 +64,7 @@ static int power4_reg_setup(struct op_counter_config *ctr, return 0; } -extern void ppc_enable_pmcs(void); +extern void ppc64_enable_pmcs(void); /* * Older CPUs require the MMCRA sample bit to be always set, but newer @@ -91,7 +91,7 @@ static int power4_cpu_setup(struct op_counter_config *ctr) unsigned int mmcr0 = mmcr0_val; unsigned long mmcra = mmcra_val; - ppc_enable_pmcs(); + ppc64_enable_pmcs(); /* set the freeze bit */ mmcr0 |= MMCR0_FC; diff --git a/trunk/arch/powerpc/platforms/44x/Kconfig b/trunk/arch/powerpc/platforms/44x/Kconfig index 79c1154f88d4..249ba01c6674 100644 --- a/trunk/arch/powerpc/platforms/44x/Kconfig +++ b/trunk/arch/powerpc/platforms/44x/Kconfig @@ -2,7 +2,6 @@ config BAMBOO bool "Bamboo" depends on 44x default n - select PPC44x_SIMPLE select 440EP select PCI help @@ -31,7 +30,6 @@ config SEQUOIA bool "Sequoia" depends on 44x default n - select PPC44x_SIMPLE select 440EPX help This option enables support for the AMCC PPC440EPX evaluation board. @@ -40,7 +38,6 @@ config TAISHAN bool "Taishan" depends on 44x default n - select PPC44x_SIMPLE select 440GX select PCI help @@ -51,7 +48,6 @@ config KATMAI bool "Katmai" depends on 44x default n - select PPC44x_SIMPLE select 440SPe select PCI select PPC4xx_PCI_EXPRESS @@ -62,7 +58,6 @@ config RAINIER bool "Rainier" depends on 44x default n - select PPC44x_SIMPLE select 440GRX select PCI help @@ -81,48 +76,20 @@ config WARP See http://www.pikatechnologies.com/ and follow the "PIKA for Computer Telephony Developers" link for more information. -config ARCHES - bool "Arches" - depends on 44x - default n - select PPC44x_SIMPLE - select 460EX # Odd since it uses 460GT but the effects are the same - select PCI - select PPC4xx_PCI_EXPRESS - help - This option enables support for the AMCC Dual PPC460GT evaluation board. - config CANYONLANDS bool "Canyonlands" depends on 44x default n - select PPC44x_SIMPLE select 460EX select PCI select PPC4xx_PCI_EXPRESS - select IBM_NEW_EMAC_RGMII - select IBM_NEW_EMAC_ZMII help This option enables support for the AMCC PPC460EX evaluation board. -config GLACIER - bool "Glacier" - depends on 44x - default n - select PPC44x_SIMPLE - select 460EX # Odd since it uses 460GT but the effects are the same - select PCI - select PPC4xx_PCI_EXPRESS - select IBM_NEW_EMAC_RGMII - select IBM_NEW_EMAC_ZMII - help - This option enables support for the AMCC PPC460GT evaluation board. - config YOSEMITE bool "Yosemite" depends on 44x default n - select PPC44x_SIMPLE select 440EP select PCI help @@ -160,13 +127,6 @@ config XILINX_VIRTEX440_GENERIC_BOARD Most Virtex 5 designs should use this unless it needs to do some special configuration at board probe time. -config PPC44x_SIMPLE - bool "Simple PowerPC 44x board support" - depends on 44x - default n - help - This option enables the simple PowerPC 44x platform support. - # 44x specific CPU modules, selected based on the board above. config 440EP bool @@ -210,6 +170,8 @@ config 460EX bool select PPC_FPU select IBM_NEW_EMAC_EMAC4 + select IBM_NEW_EMAC_RGMII + select IBM_NEW_EMAC_ZMII select IBM_NEW_EMAC_TAH # 44x errata/workaround config symbols, selected by the CPU models above diff --git a/trunk/arch/powerpc/platforms/44x/Makefile b/trunk/arch/powerpc/platforms/44x/Makefile index 698133180aee..8d0b1a192d62 100644 --- a/trunk/arch/powerpc/platforms/44x/Makefile +++ b/trunk/arch/powerpc/platforms/44x/Makefile @@ -1,7 +1,13 @@ obj-$(CONFIG_44x) := misc_44x.o idle.o -obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o obj-$(CONFIG_EBONY) += ebony.o +obj-$(CONFIG_TAISHAN) += taishan.o +obj-$(CONFIG_BAMBOO) += bamboo.o +obj-$(CONFIG_YOSEMITE) += bamboo.o obj-$(CONFIG_SAM440EP) += sam440ep.o +obj-$(CONFIG_SEQUOIA) += sequoia.o +obj-$(CONFIG_KATMAI) += katmai.o +obj-$(CONFIG_RAINIER) += rainier.o obj-$(CONFIG_WARP) += warp.o obj-$(CONFIG_WARP) += warp-nand.o +obj-$(CONFIG_CANYONLANDS) += canyonlands.o obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o diff --git a/trunk/arch/powerpc/platforms/44x/bamboo.c b/trunk/arch/powerpc/platforms/44x/bamboo.c new file mode 100644 index 000000000000..cef169e95156 --- /dev/null +++ b/trunk/arch/powerpc/platforms/44x/bamboo.c @@ -0,0 +1,62 @@ +/* + * Bamboo board specific routines + * + * Wade Farnsworth + * Copyright 2004 MontaVista Software Inc. + * + * Rewritten and ported to the merged powerpc tree: + * Josh Boyer + * Copyright 2007 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id bamboo_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init bamboo_device_probe(void) +{ + of_platform_bus_probe(NULL, bamboo_of_bus, NULL); + + return 0; +} +machine_device_initcall(bamboo, bamboo_device_probe); + +static int __init bamboo_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "amcc,bamboo")) + return 0; + + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + + return 1; +} + +define_machine(bamboo) { + .name = "Bamboo", + .probe = bamboo_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/trunk/arch/powerpc/platforms/44x/canyonlands.c b/trunk/arch/powerpc/platforms/44x/canyonlands.c new file mode 100644 index 000000000000..3949289f51df --- /dev/null +++ b/trunk/arch/powerpc/platforms/44x/canyonlands.c @@ -0,0 +1,63 @@ +/* + * Canyonlands board specific routines + * + * Copyright 2008 DENX Software Engineering, Stefan Roese + * + * Based on the Katmai code by + * Benjamin Herrenschmidt + * Copyright 2007 IBM Corp. + * Josh Boyer + * Copyright 2007 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id canyonlands_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init canyonlands_device_probe(void) +{ + of_platform_bus_probe(NULL, canyonlands_of_bus, NULL); + + return 0; +} +machine_device_initcall(canyonlands, canyonlands_device_probe); + +static int __init canyonlands_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "amcc,canyonlands")) + return 0; + + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + + return 1; +} + +define_machine(canyonlands) { + .name = "Canyonlands", + .probe = canyonlands_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/trunk/arch/powerpc/platforms/44x/katmai.c b/trunk/arch/powerpc/platforms/44x/katmai.c new file mode 100644 index 000000000000..44f4b3a00ced --- /dev/null +++ b/trunk/arch/powerpc/platforms/44x/katmai.c @@ -0,0 +1,62 @@ +/* + * Katmai board specific routines + * + * Benjamin Herrenschmidt + * Copyright 2007 IBM Corp. + * + * Based on the Bamboo code by + * Josh Boyer + * Copyright 2007 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id katmai_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init katmai_device_probe(void) +{ + of_platform_bus_probe(NULL, katmai_of_bus, NULL); + + return 0; +} +machine_device_initcall(katmai, katmai_device_probe); + +static int __init katmai_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "amcc,katmai")) + return 0; + + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + + return 1; +} + +define_machine(katmai) { + .name = "Katmai", + .probe = katmai_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c b/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c deleted file mode 100644 index 29671262801f..000000000000 --- a/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Generic PowerPC 44x platform support - * - * Copyright 2008 IBM Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; version 2 of the License. - * - * This implements simple platform support for PowerPC 44x chips. This is - * mostly used for eval boards or other simple and "generic" 44x boards. If - * your board has custom functions or hardware, then you will likely want to - * implement your own board.c file to accommodate it. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static __initdata struct of_device_id ppc44x_of_bus[] = { - { .compatible = "ibm,plb4", }, - { .compatible = "ibm,opb", }, - { .compatible = "ibm,ebc", }, - { .compatible = "simple-bus", }, - {}, -}; - -static int __init ppc44x_device_probe(void) -{ - of_platform_bus_probe(NULL, ppc44x_of_bus, NULL); - - return 0; -} -machine_device_initcall(ppc44x_simple, ppc44x_device_probe); - -/* This is the list of boards that can be supported by this simple - * platform code. This does _not_ mean the boards are compatible, - * as they most certainly are not from a device tree perspective. - * However, their differences are handled by the device tree and the - * drivers and therefore they don't need custom board support files. - * - * Again, if your board needs to do things differently then create a - * board.c file for it rather than adding it to this list. - */ -static char *board[] __initdata = { - "amcc,arches", - "amcc,bamboo", - "amcc,canyonlands", - "amcc,glacier", - "ibm,ebony", - "amcc,katmai", - "amcc,rainier", - "amcc,sequoia", - "amcc,taishan", - "amcc,yosemite" -}; - -static int __init ppc44x_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - int i = 0; - - for (i = 0; i < ARRAY_SIZE(board); i++) { - if (of_flat_dt_is_compatible(root, board[i])) { - ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; - return 1; - } - } - - return 0; -} - -define_machine(ppc44x_simple) { - .name = "PowerPC 44x Platform", - .probe = ppc44x_probe, - .progress = udbg_progress, - .init_IRQ = uic_init_tree, - .get_irq = uic_get_irq, - .restart = ppc4xx_reset_system, - .calibrate_decr = generic_calibrate_decr, -}; diff --git a/trunk/arch/powerpc/platforms/44x/rainier.c b/trunk/arch/powerpc/platforms/44x/rainier.c new file mode 100644 index 000000000000..4f1ff84c4b63 --- /dev/null +++ b/trunk/arch/powerpc/platforms/44x/rainier.c @@ -0,0 +1,62 @@ +/* + * Rainier board specific routines + * + * Valentine Barshak + * Copyright 2007 MontaVista Software Inc. + * + * Based on the Bamboo code by + * Josh Boyer + * Copyright 2007 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id rainier_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init rainier_device_probe(void) +{ + of_platform_bus_probe(NULL, rainier_of_bus, NULL); + + return 0; +} +machine_device_initcall(rainier, rainier_device_probe); + +static int __init rainier_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "amcc,rainier")) + return 0; + + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + + return 1; +} + +define_machine(rainier) { + .name = "Rainier", + .probe = rainier_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/trunk/arch/powerpc/platforms/44x/sequoia.c b/trunk/arch/powerpc/platforms/44x/sequoia.c new file mode 100644 index 000000000000..49eb73daacdf --- /dev/null +++ b/trunk/arch/powerpc/platforms/44x/sequoia.c @@ -0,0 +1,63 @@ +/* + * Sequoia board specific routines + * + * Valentine Barshak + * Copyright 2007 MontaVista Software Inc. + * + * Based on the Bamboo code by + * Josh Boyer + * Copyright 2007 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +static __initdata struct of_device_id sequoia_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init sequoia_device_probe(void) +{ + of_platform_bus_probe(NULL, sequoia_of_bus, NULL); + + return 0; +} +machine_device_initcall(sequoia, sequoia_device_probe); + +static int __init sequoia_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "amcc,sequoia")) + return 0; + + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + + return 1; +} + +define_machine(sequoia) { + .name = "Sequoia", + .probe = sequoia_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/trunk/arch/powerpc/platforms/44x/taishan.c b/trunk/arch/powerpc/platforms/44x/taishan.c new file mode 100644 index 000000000000..49c78b2098b4 --- /dev/null +++ b/trunk/arch/powerpc/platforms/44x/taishan.c @@ -0,0 +1,72 @@ +/* + * Taishan board specific routines based off ebony.c code + * original copyrights below + * + * Matt Porter + * Copyright 2002-2005 MontaVista Software Inc. + * + * Eugene Surovegin or + * Copyright (c) 2003-2005 Zultys Technologies + * + * Rewritten and ported to the merged powerpc tree: + * Copyright 2007 David Gibson , IBM Corporation. + * + * Modified from ebony.c for taishan: + * Copyright 2007 Hugh Blemings , IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id taishan_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init taishan_device_probe(void) +{ + of_platform_bus_probe(NULL, taishan_of_bus, NULL); + + return 0; +} +machine_device_initcall(taishan, taishan_device_probe); + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init taishan_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "amcc,taishan")) + return 0; + + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + + return 1; +} + +define_machine(taishan) { + .name = "Taishan", + .probe = taishan_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/trunk/arch/powerpc/platforms/512x/Kconfig b/trunk/arch/powerpc/platforms/512x/Kconfig index 326852c78b8f..c62f893ede19 100644 --- a/trunk/arch/powerpc/platforms/512x/Kconfig +++ b/trunk/arch/powerpc/platforms/512x/Kconfig @@ -3,8 +3,6 @@ config PPC_MPC512x select FSL_SOC select IPIC select PPC_CLOCK - select PPC_PCI_CHOICE - select FSL_PCI if PCI config PPC_MPC5121 bool diff --git a/trunk/arch/powerpc/platforms/512x/mpc5121_ads.c b/trunk/arch/powerpc/platforms/512x/mpc5121_ads.c index 441abc488851..5ebf6939a697 100644 --- a/trunk/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/trunk/arch/powerpc/platforms/512x/mpc5121_ads.c @@ -22,26 +22,16 @@ #include #include -#include - #include "mpc512x.h" #include "mpc5121_ads.h" static void __init mpc5121_ads_setup_arch(void) { -#ifdef CONFIG_PCI - struct device_node *np; -#endif printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n"); /* * cpld regs are needed early */ mpc5121_ads_cpld_map(); - -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") - mpc83xx_add_bridge(np); -#endif } static void __init mpc5121_ads_init_IRQ(void) diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c index 044b4e6e8743..4d5fd1dbd400 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -90,7 +90,7 @@ mpc5200_setup_xlb_arbiter(void) of_node_put(np); if (!xlb) { printk(KERN_ERR __FILE__ ": " - "Error mapping XLB in mpc52xx_setup_cpu(). " + "Error mapping XLB in mpc52xx_setup_cpu(). " "Expect some abnormal behavior\n"); return; } @@ -216,8 +216,7 @@ mpc52xx_restart(char *cmd) out_be32(&mpc52xx_wdt->count, 0x000000ff); out_be32(&mpc52xx_wdt->mode, 0x00009004); } else - printk(KERN_ERR __FILE__ ": " - "mpc52xx_restart: Can't access wdt. " + printk("mpc52xx_restart: Can't access wdt. " "Restart impossible, system halted.\n"); while (1); diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c index b49a18527661..5a382bb15f62 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -265,11 +265,8 @@ mpc52xx_pci_setup(struct pci_controller *hose, /* Memory windows */ res = &hose->mem_resources[0]; if (res->flags) { - pr_debug("mem_resource[0] = " - "{.start=%llx, .end=%llx, .flags=%llx}\n", - (unsigned long long)res->start, - (unsigned long long)res->end, - (unsigned long long)res->flags); + pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n", + res->start, res->end, res->flags); out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start, res->end - res->start + 1)); @@ -300,11 +297,9 @@ mpc52xx_pci_setup(struct pci_controller *hose, printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__); return; } - pr_debug(".io_resource={.start=%llx,.end=%llx,.flags=%llx} " + pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} " ".io_base_phys=0x%p\n", - (unsigned long long)res->start, - (unsigned long long)res->end, - (unsigned long long)res->flags, (void*)hose->io_base_phys); + res->start, res->end, res->flags, (void*)hose->io_base_phys); out_be32(&pci_regs->iw2btar, MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys, res->start, diff --git a/trunk/arch/powerpc/platforms/82xx/Kconfig b/trunk/arch/powerpc/platforms/82xx/Kconfig index 30f008b2f92e..75eb1ede5497 100644 --- a/trunk/arch/powerpc/platforms/82xx/Kconfig +++ b/trunk/arch/powerpc/platforms/82xx/Kconfig @@ -38,14 +38,6 @@ config EP8248E This board is also resold by Freescale as the QUICCStart MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE. -config MGCOGE - bool "Keymile MGCOGE" - select 8272 - select 8260 - select FSL_SOC - help - This enables support for the Keymile MGCOGE board. - endif config PQ2ADS diff --git a/trunk/arch/powerpc/platforms/82xx/Makefile b/trunk/arch/powerpc/platforms/82xx/Makefile index d982793f4dbd..6cd5cd59bf2a 100644 --- a/trunk/arch/powerpc/platforms/82xx/Makefile +++ b/trunk/arch/powerpc/platforms/82xx/Makefile @@ -6,4 +6,3 @@ obj-$(CONFIG_CPM2) += pq2.o obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o obj-$(CONFIG_PQ2FADS) += pq2fads.o obj-$(CONFIG_EP8248E) += ep8248e.o -obj-$(CONFIG_MGCOGE) += mgcoge.o diff --git a/trunk/arch/powerpc/platforms/82xx/mgcoge.c b/trunk/arch/powerpc/platforms/82xx/mgcoge.c deleted file mode 100644 index c2af169c1d1d..000000000000 --- a/trunk/arch/powerpc/platforms/82xx/mgcoge.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Keymile mgcoge support - * Copyright 2008 DENX Software Engineering GmbH - * Author: Heiko Schocher - * - * based on code from: - * Copyright 2007 Freescale Semiconductor, Inc. - * Author: Scott Wood - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pq2.h" - -static void __init mgcoge_pic_init(void) -{ - struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic"); - if (!np) { - printk(KERN_ERR "PIC init: can not find cpm-pic node\n"); - return; - } - - cpm2_pic_init(np); - of_node_put(np); -} - -struct cpm_pin { - int port, pin, flags; -}; - -static __initdata struct cpm_pin mgcoge_pins[] = { - - /* SMC2 */ - {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, - {1, 9, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, - - /* SCC4 */ - {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, - {3, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, - {3, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, - {3, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, - {4, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, - {4, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -}; - -static void __init init_ioports(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(mgcoge_pins); i++) { - const struct cpm_pin *pin = &mgcoge_pins[i]; - cpm2_set_pin(pin->port - 1, pin->pin, pin->flags); - } - - cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8); - cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK7, CPM_CLK_RX); - cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK8, CPM_CLK_TX); -} - -static void __init mgcoge_setup_arch(void) -{ - if (ppc_md.progress) - ppc_md.progress("mgcoge_setup_arch()", 0); - - cpm2_reset(); - - /* When this is set, snooping CPM DMA from RAM causes - * machine checks. See erratum SIU18. - */ - clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP); - - init_ioports(); - - if (ppc_md.progress) - ppc_md.progress("mgcoge_setup_arch(), finish", 0); -} - -static __initdata struct of_device_id of_bus_ids[] = { - { .compatible = "simple-bus", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_device_initcall(mgcoge, declare_of_platform_devices); - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init mgcoge_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "keymile,mgcoge"); -} - -define_machine(mgcoge) -{ - .name = "Keymile MGCOGE", - .probe = mgcoge_probe, - .setup_arch = mgcoge_setup_arch, - .init_IRQ = mgcoge_pic_init, - .get_irq = cpm2_get_irq, - .calibrate_decr = generic_calibrate_decr, - .restart = pq2_restart, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/83xx/Kconfig b/trunk/arch/powerpc/platforms/83xx/Kconfig index 83c664afc897..6159c5d4e5f1 100644 --- a/trunk/arch/powerpc/platforms/83xx/Kconfig +++ b/trunk/arch/powerpc/platforms/83xx/Kconfig @@ -19,6 +19,7 @@ config MPC831x_RDB config MPC832x_MDS bool "Freescale MPC832x MDS" select DEFAULT_UIMAGE + select QUICC_ENGINE select PPC_MPC832x help This option enables support for the MPC832x MDS evaluation board. @@ -26,6 +27,7 @@ config MPC832x_MDS config MPC832x_RDB bool "Freescale MPC832x RDB" select DEFAULT_UIMAGE + select QUICC_ENGINE select PPC_MPC832x help This option enables support for the MPC8323 RDB board. @@ -55,12 +57,15 @@ config MPC834x_ITX config MPC836x_MDS bool "Freescale MPC836x MDS" select DEFAULT_UIMAGE + select QUICC_ENGINE help This option enables support for the MPC836x MDS Processor Board. config MPC836x_RDK bool "Freescale/Logic MPC836x RDK" select DEFAULT_UIMAGE + select QUICC_ENGINE + select QE_GPIO select FSL_GTM select FSL_LBC help diff --git a/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c index 8bb13c807142..be62de23bead 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -85,14 +85,8 @@ static void __init mpc837x_mds_setup_arch(void) ppc_md.progress("mpc837x_mds_setup_arch()", 0); #ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") { - if (!of_device_is_available(np)) { - pr_warning("%s: disabled by the firmware.\n", - np->full_name); - continue; - } + for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") mpc83xx_add_bridge(np); - } #endif mpc837xmds_usb_cfg(); } diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index b79dc710ed34..291675b0097a 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -33,6 +33,7 @@ config MPC85xx_CDS config MPC85xx_MDS bool "Freescale MPC85xx MDS" select DEFAULT_UIMAGE + select QUICC_ENGINE select PHYLIB help This option enables support for the MPC85xx MDS board diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 0293e3d3580f..d17807a6b89a 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -213,6 +213,7 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); + seq_printf(m, "Machine\t\t: mpc85xx\n"); seq_printf(m, "PVR\t\t: 0x%x\n", pvid); seq_printf(m, "SVR\t\t: 0x%x\n", svid); diff --git a/trunk/arch/powerpc/platforms/85xx/sbc8560.c b/trunk/arch/powerpc/platforms/85xx/sbc8560.c index 0c9a856f66b6..6509ade71668 100644 --- a/trunk/arch/powerpc/platforms/85xx/sbc8560.c +++ b/trunk/arch/powerpc/platforms/85xx/sbc8560.c @@ -156,7 +156,7 @@ static void __init init_ioports(void) int i; for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) { - const struct cpm_pin *pin = &sbc8560_pins[i]; + struct cpm_pin *pin = &sbc8560_pins[i]; cpm2_set_pin(pin->port, pin->pin, pin->flags); } @@ -200,6 +200,7 @@ static void sbc8560_show_cpuinfo(struct seq_file *m) svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Wind River\n"); + seq_printf(m, "Machine\t\t: SBC8560\n"); seq_printf(m, "PVR\t\t: 0x%x\n", pvid); seq_printf(m, "SVR\t\t: 0x%x\n", svid); diff --git a/trunk/arch/powerpc/platforms/86xx/Kconfig b/trunk/arch/powerpc/platforms/86xx/Kconfig index 77dd797a2580..9355a5269431 100644 --- a/trunk/arch/powerpc/platforms/86xx/Kconfig +++ b/trunk/arch/powerpc/platforms/86xx/Kconfig @@ -31,13 +31,6 @@ config MPC8610_HPCD help This option enables support for the MPC8610 HPCD board. -config GEF_SBC610 - bool "GE Fanuc SBC610" - select DEFAULT_UIMAGE - select HAS_RAPIDIO - help - This option enables support for GE Fanuc's SBC610. - endif config MPC8641 @@ -46,7 +39,7 @@ config MPC8641 select FSL_PCI if PCI select PPC_UDBG_16550 select MPIC - default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 + default y if MPC8641_HPCN || SBC8641D config MPC8610 bool diff --git a/trunk/arch/powerpc/platforms/86xx/Makefile b/trunk/arch/powerpc/platforms/86xx/Makefile index 4a56ff619afd..8fee37dec795 100644 --- a/trunk/arch/powerpc/platforms/86xx/Makefile +++ b/trunk/arch/powerpc/platforms/86xx/Makefile @@ -7,4 +7,3 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_SBC8641D) += sbc8641d.o obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o -obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o diff --git a/trunk/arch/powerpc/platforms/86xx/gef_pic.c b/trunk/arch/powerpc/platforms/86xx/gef_pic.c deleted file mode 100644 index 50d0a2b63809..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/gef_pic.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Interrupt handling for GE Fanuc's FPGA based PIC - * - * Author: Martyn Welch - * - * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "gef_pic.h" - -#define DEBUG -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while (0) -#else -#define DBG(fmt...) do { } while (0) -#endif - -#define GEF_PIC_NUM_IRQS 32 - -/* Interrupt Controller Interface Registers */ -#define GEF_PIC_INTR_STATUS 0x0000 - -#define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu)) -#define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0) -#define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1) - -#define GEF_PIC_MCP_MASK(cpu) (0x0018 + (0x4 * cpu)) -#define GEF_PIC_CPU0_MCP_MASK GEF_PIC_MCP_MASK(0) -#define GEF_PIC_CPU1_MCP_MASK GEF_PIC_MCP_MASK(1) - -#define gef_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) - - -static DEFINE_SPINLOCK(gef_pic_lock); - -static void __iomem *gef_pic_irq_reg_base; -static struct irq_host *gef_pic_irq_host; -static int gef_pic_cascade_irq; - -/* - * Interrupt Controller Handling - * - * The interrupt controller handles interrupts for most on board interrupts, - * apart from PCI interrupts. For example on SBC610: - * - * 17:31 RO Reserved - * 16 RO PCI Express Doorbell 3 Status - * 15 RO PCI Express Doorbell 2 Status - * 14 RO PCI Express Doorbell 1 Status - * 13 RO PCI Express Doorbell 0 Status - * 12 RO Real Time Clock Interrupt Status - * 11 RO Temperature Interrupt Status - * 10 RO Temperature Critical Interrupt Status - * 9 RO Ethernet PHY1 Interrupt Status - * 8 RO Ethernet PHY3 Interrupt Status - * 7 RO PEX8548 Interrupt Status - * 6 RO Reserved - * 5 RO Watchdog 0 Interrupt Status - * 4 RO Watchdog 1 Interrupt Status - * 3 RO AXIS Message FIFO A Interrupt Status - * 2 RO AXIS Message FIFO B Interrupt Status - * 1 RO AXIS Message FIFO C Interrupt Status - * 0 RO AXIS Message FIFO D Interrupt Status - * - * Interrupts can be forwarded to one of two output lines. Nothing - * clever is done, so if the masks are incorrectly set, a single input - * interrupt could generate interrupts on both output lines! - * - * The dual lines are there to allow the chained interrupts to be easily - * passed into two different cores. We currently do not use this functionality - * in this driver. - * - * Controller can also be configured to generate Machine checks (MCP), again on - * two lines, to be attached to two different cores. It is suggested that these - * should be masked out. - */ - -void gef_pic_cascade(unsigned int irq, struct irq_desc *desc) -{ - unsigned int cascade_irq; - - /* - * See if we actually have an interrupt, call generic handling code if - * we do. - */ - cascade_irq = gef_pic_get_irq(); - - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); - - desc->chip->eoi(irq); - -} - -static void gef_pic_mask(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq; - u32 mask; - - hwirq = gef_irq_to_hw(virq); - - spin_lock_irqsave(&gef_pic_lock, flags); - mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); - mask &= ~(1 << hwirq); - out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - spin_unlock_irqrestore(&gef_pic_lock, flags); -} - -static void gef_pic_mask_ack(unsigned int virq) -{ - /* Don't think we actually have to do anything to ack an interrupt, - * we just need to clear down the devices interrupt and it will go away - */ - gef_pic_mask(virq); -} - -static void gef_pic_unmask(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq; - u32 mask; - - hwirq = gef_irq_to_hw(virq); - - spin_lock_irqsave(&gef_pic_lock, flags); - mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); - mask |= (1 << hwirq); - out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - spin_unlock_irqrestore(&gef_pic_lock, flags); -} - -static struct irq_chip gef_pic_chip = { - .typename = "gefp", - .mask = gef_pic_mask, - .mask_ack = gef_pic_mask_ack, - .unmask = gef_pic_unmask, -}; - - -/* When an interrupt is being configured, this call allows some flexibilty - * in deciding which irq_chip structure is used - */ -static int gef_pic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hwirq) -{ - /* All interrupts are LEVEL sensitive */ - get_irq_desc(virq)->status |= IRQ_LEVEL; - set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq); - - return 0; -} - -static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, - u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) -{ - - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_LEVEL_HIGH; - - return 0; -} - -static struct irq_host_ops gef_pic_host_ops = { - .map = gef_pic_host_map, - .xlate = gef_pic_host_xlate, -}; - - -/* - * Initialisation of PIC, this should be called in BSP - */ -void __init gef_pic_init(struct device_node *np) -{ - unsigned long flags; - - /* Map the devices registers into memory */ - gef_pic_irq_reg_base = of_iomap(np, 0); - - spin_lock_irqsave(&gef_pic_lock, flags); - - /* Initialise everything as masked. */ - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0); - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0); - - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0); - out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0); - - spin_unlock_irqrestore(&gef_pic_lock, flags); - - /* Map controller */ - gef_pic_cascade_irq = irq_of_parse_and_map(np, 0); - if (gef_pic_cascade_irq == NO_IRQ) { - printk(KERN_ERR "SBC610: failed to map cascade interrupt"); - return; - } - - /* Setup an irq_host structure */ - gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - GEF_PIC_NUM_IRQS, - &gef_pic_host_ops, NO_IRQ); - if (gef_pic_irq_host == NULL) - return; - - /* Chain with parent controller */ - set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade); -} - -/* - * This is called when we receive an interrupt with apparently comes from this - * chip - check, returning the highest interrupt generated or return NO_IRQ - */ -unsigned int gef_pic_get_irq(void) -{ - u32 cause, mask, active; - unsigned int virq = NO_IRQ; - int hwirq; - - cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS); - - mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); - - active = cause & mask; - - if (active) { - for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--) { - if (active & (0x1 << hwirq)) - break; - } - virq = irq_linear_revmap(gef_pic_irq_host, - (irq_hw_number_t)hwirq); - } - - return virq; -} - diff --git a/trunk/arch/powerpc/platforms/86xx/gef_pic.h b/trunk/arch/powerpc/platforms/86xx/gef_pic.h deleted file mode 100644 index 6149916da3f4..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/gef_pic.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __GEF_PIC_H__ -#define __GEF_PIC_H__ - -#include - -void gef_pic_cascade(unsigned int, struct irq_desc *); -unsigned int gef_pic_get_irq(void); -void gef_pic_init(struct device_node *); - -#endif /* __GEF_PIC_H__ */ - diff --git a/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c b/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c deleted file mode 100644 index 821c45fac18b..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * GE Fanuc SBC610 board support - * - * Author: Martyn Welch - * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, 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 - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines) - * Copyright 2006 Freescale Semiconductor Inc. - * - * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "mpc86xx.h" -#include "gef_pic.h" - -#undef DEBUG - -#ifdef DEBUG -#define DBG (fmt...) do { printk(KERN_ERR "SBC610: " fmt); } while (0) -#else -#define DBG (fmt...) do { } while (0) -#endif - -void __iomem *sbc610_regs; - -static void __init gef_sbc610_init_irq(void) -{ - struct device_node *cascade_node = NULL; - - mpc86xx_init_irq(); - - /* - * There is a simple interrupt handler in the main FPGA, this needs - * to be cascaded into the MPIC - */ - cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic"); - if (!cascade_node) { - printk(KERN_WARNING "SBC610: No FPGA PIC\n"); - return; - } - - gef_pic_init(cascade_node); - of_node_put(cascade_node); -} - -static void __init gef_sbc610_setup_arch(void) -{ - struct device_node *regs; -#ifdef CONFIG_PCI - struct device_node *np; - - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - fsl_add_bridge(np, 1); - } -#endif - - printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n"); - -#ifdef CONFIG_SMP - mpc86xx_smp_init(); -#endif - - /* Remap basic board registers */ - regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); - if (regs) { - sbc610_regs = of_iomap(regs, 0); - if (sbc610_regs == NULL) - printk(KERN_WARNING "Unable to map board registers\n"); - of_node_put(regs); - } -} - -/* Return the PCB revision */ -static unsigned int gef_sbc610_get_pcb_rev(void) -{ - unsigned int reg; - - reg = ioread32(sbc610_regs); - return (reg >> 8) & 0xff; -} - -/* Return the board (software) revision */ -static unsigned int gef_sbc610_get_board_rev(void) -{ - unsigned int reg; - - reg = ioread32(sbc610_regs); - return (reg >> 16) & 0xff; -} - -/* Return the FPGA revision */ -static unsigned int gef_sbc610_get_fpga_rev(void) -{ - unsigned int reg; - - reg = ioread32(sbc610_regs); - return (reg >> 24) & 0xf; -} - -static void gef_sbc610_show_cpuinfo(struct seq_file *m) -{ - uint memsize = total_memory; - uint svid = mfspr(SPRN_SVR); - - seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); - - seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(), - ('A' + gef_sbc610_get_board_rev() - 1)); - seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev()); - - seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -} - -static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev) -{ - unsigned int val; - - printk(KERN_INFO "Running NEC uPD720101 Fixup\n"); - - /* Ensure ports 1, 2, 3, 4 & 5 are enabled */ - pci_read_config_dword(pdev, 0xe0, &val); - pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5); - - /* System clock is 48-MHz Oscillator and EHCI Enabled. */ - pci_write_config_dword(pdev, 0xe4, 1 << 5); -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, - gef_sbc610_nec_fixup); - -/* - * Called very early, device-tree isn't unflattened - * - * This function is called to determine whether the BSP is compatible with the - * supplied device-tree, which is assumed to be the correct one for the actual - * board. It is expected thati, in the future, a kernel may support multiple - * boards. - */ -static int __init gef_sbc610_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "gef,sbc610")) - return 1; - - return 0; -} - -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static __initdata struct of_device_id of_bus_ids[] = { - { .compatible = "simple-bus", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - printk(KERN_DEBUG "Probe platform devices\n"); - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_device_initcall(gef_sbc610, declare_of_platform_devices); - -define_machine(gef_sbc610) { - .name = "GE Fanuc SBC610", - .probe = gef_sbc610_probe, - .setup_arch = gef_sbc610_setup_arch, - .init_IRQ = gef_sbc610_init_irq, - .show_cpuinfo = gef_sbc610_show_cpuinfo, - .get_irq = mpic_get_irq, - .restart = fsl_rstcr_restart, - .time_init = mpc86xx_time_init, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif -}; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index e8d54ac5292c..5eedb710896e 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -238,6 +238,7 @@ static void __init mpc86xx_hpcd_setup_arch(void) } #endif #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) + preallocate_diu_videomemory(); diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format; diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table; diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 2672829a71dc..f712d9c0991b 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -101,11 +101,19 @@ mpc86xx_hpcn_setup_arch(void) static void mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) { + struct device_node *root; uint memsize = total_memory; + const char *model = ""; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); + root = of_find_node_by_path("/"); + if (root) + model = of_get_property(root, "model", NULL); + seq_printf(m, "Machine\t\t: %s\n", model); + of_node_put(root); + seq_printf(m, "SVR\t\t: 0x%x\n", svid); seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/trunk/arch/powerpc/platforms/86xx/sbc8641d.c b/trunk/arch/powerpc/platforms/86xx/sbc8641d.c index da677a74e2d1..00e6fad3b3ca 100644 --- a/trunk/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/trunk/arch/powerpc/platforms/86xx/sbc8641d.c @@ -63,11 +63,19 @@ sbc8641_setup_arch(void) static void sbc8641_show_cpuinfo(struct seq_file *m) { + struct device_node *root; uint memsize = total_memory; + const char *model = ""; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Wind River Systems\n"); + root = of_find_node_by_path("/"); + if (root) + model = of_get_property(root, "model", NULL); + seq_printf(m, "Machine\t\t: %s\n", model); + of_node_put(root); + seq_printf(m, "SVR\t\t: 0x%x\n", svid); seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/trunk/arch/powerpc/platforms/8xx/Kconfig b/trunk/arch/powerpc/platforms/8xx/Kconfig index 48a920a98e7b..71d7562e190b 100644 --- a/trunk/arch/powerpc/platforms/8xx/Kconfig +++ b/trunk/arch/powerpc/platforms/8xx/Kconfig @@ -49,12 +49,6 @@ config PPC_ADDER875 This enables support for the Analogue & Micro Adder 875 board. -config PPC_MGSUVD - bool "MGSUVD" - select CPM1 - help - This enables support for the Keymile MGSUVD board. - endchoice menu "Freescale Ethernet driver platform-specific options" diff --git a/trunk/arch/powerpc/platforms/8xx/Makefile b/trunk/arch/powerpc/platforms/8xx/Makefile index bdbfd7496018..7b71d9c8fb45 100644 --- a/trunk/arch/powerpc/platforms/8xx/Makefile +++ b/trunk/arch/powerpc/platforms/8xx/Makefile @@ -6,4 +6,3 @@ obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o obj-$(CONFIG_PPC_EP88XC) += ep88xc.o obj-$(CONFIG_PPC_ADDER875) += adder875.o -obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o diff --git a/trunk/arch/powerpc/platforms/8xx/mgsuvd.c b/trunk/arch/powerpc/platforms/8xx/mgsuvd.c deleted file mode 100644 index ca3cb071772c..000000000000 --- a/trunk/arch/powerpc/platforms/8xx/mgsuvd.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Platform setup for the Keymile mgsuvd board - * - * Heiko Schocher - * - * Copyright 2008 DENX Software Engineering GmbH - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "mpc8xx.h" - -struct cpm_pin { - int port, pin, flags; -}; - -static __initdata struct cpm_pin mgsuvd_pins[] = { - /* SMC1 */ - {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ - {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ - - /* SCC3 */ - {CPM_PORTA, 10, CPM_PIN_INPUT}, - {CPM_PORTA, 11, CPM_PIN_INPUT}, - {CPM_PORTA, 3, CPM_PIN_INPUT}, - {CPM_PORTA, 2, CPM_PIN_INPUT}, - {CPM_PORTC, 13, CPM_PIN_INPUT}, -}; - -static void __init init_ioports(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(mgsuvd_pins); i++) { - struct cpm_pin *pin = &mgsuvd_pins[i]; - cpm1_set_pin(pin->port, pin->pin, pin->flags); - } - - setbits16(&mpc8xx_immr->im_ioport.iop_pcso, 0x300); - cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RX); - cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_TX); - cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); -} - -static void __init mgsuvd_setup_arch(void) -{ - cpm_reset(); - init_ioports(); -} - -static __initdata struct of_device_id of_bus_ids[] = { - { .compatible = "simple-bus" }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, of_bus_ids, NULL); - return 0; -} -machine_device_initcall(mgsuvd, declare_of_platform_devices); - -static int __init mgsuvd_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "keymile,mgsuvd"); -} - -define_machine(mgsuvd) { - .name = "MGSUVD", - .probe = mgsuvd_probe, - .setup_arch = mgsuvd_setup_arch, - .init_IRQ = mpc8xx_pics_init, - .get_irq = mpc8xx_get_irq, - .restart = mpc8xx_restart, - .calibrate_decr = mpc8xx_calibrate_decr, - .set_rtc_time = mpc8xx_set_rtc_time, - .get_rtc_time = mpc8xx_get_rtc_time, -}; diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index 47e956c871fe..4c900efa164e 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -239,8 +239,7 @@ config TAU_AVERAGE If in doubt, say N here. config QUICC_ENGINE - bool "Freescale QUICC Engine (QE) Support" - depends on FSL_SOC + bool select PPC_LIB_RHEAP select CRC32 help @@ -249,15 +248,6 @@ config QUICC_ENGINE Selecting this option means that you wish to build a kernel for a machine with a QE coprocessor. -config QE_GPIO - bool "QE GPIO support" - depends on QUICC_ENGINE - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Say Y here if you're going to use hardware that connects to the - QE GPIOs. - config CPM2 bool "Enable support for the CPM2 (Communications Processor Module)" depends on MPC85xx || 8260 @@ -303,13 +293,4 @@ config OF_RTC source "arch/powerpc/sysdev/bestcomm/Kconfig" -config MPC8xxx_GPIO - bool "MPC8xxx GPIO support" - depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || PPC_85xx || PPC_86xx - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Say Y here if you're going to use hardware that connects to the - MPC831x/834x/837x/8572/8610 GPIOs. - endmenu diff --git a/trunk/arch/powerpc/platforms/Kconfig.cputype b/trunk/arch/powerpc/platforms/Kconfig.cputype index 439c5ba34ecf..7f6512733862 100644 --- a/trunk/arch/powerpc/platforms/Kconfig.cputype +++ b/trunk/arch/powerpc/platforms/Kconfig.cputype @@ -50,7 +50,6 @@ config 44x select PPC_UDBG_16550 select 4xx_SOC select PPC_PCI_CHOICE - select PHYS_64BIT config E200 bool "Freescale e200" @@ -129,20 +128,18 @@ config FSL_EMB_PERFMON config PTE_64BIT bool - depends on 44x || E500 || PPC_86xx - default y if PHYS_64BIT + depends on 44x || E500 + default y if 44x + default y if E500 && PHYS_64BIT config PHYS_64BIT - bool 'Large physical address support' if E500 || PPC_86xx - depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx + bool 'Large physical address support' if E500 + depends on 44x || E500 select RESOURCES_64BIT + default y if 44x ---help--- This option enables kernel support for larger than 32-bit physical - addresses. This feature may not be available on all cores. - - If you have more than 3.5GB of RAM or so, you also need to enable - SWIOTLB under Kernel Options for this to work. The actual number - is platform-dependent. + addresses. This features is not be available on all e500 cores. If in doubt, say N here. diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index ef92e7146215..e06420af5fe9 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -556,11 +556,11 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) * node's iommu. We -might- do something smarter later though it may * never be necessary */ - iommu = cell_iommu_for_node(dev_to_node(dev)); + iommu = cell_iommu_for_node(archdata->numa_node); if (iommu == NULL || list_empty(&iommu->windows)) { printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", archdata->of_node ? archdata->of_node->full_name : "?", - dev_to_node(dev)); + archdata->numa_node); return NULL; } window = list_entry(iommu->windows.next, struct iommu_window, list); @@ -577,7 +577,7 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, return iommu_alloc_coherent(dev, cell_get_iommu_table(dev), size, dma_handle, device_to_mask(dev), flag, - dev_to_node(dev)); + dev->archdata.numa_node); else return dma_direct_ops.alloc_coherent(dev, size, dma_handle, flag); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index cb85d237e492..690ca7b0dcf6 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -298,8 +298,8 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, d_instantiate(dentry, inode); dget(dentry); - inc_nlink(dir); - inc_nlink(dentry->d_inode); + dir->i_nlink++; + dentry->d_inode->i_nlink++; goto out; out_free_ctx: @@ -496,8 +496,6 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, ret = spufs_context_open(dget(dentry), mntget(mnt)); if (ret < 0) { WARN_ON(spufs_rmdir(inode, dentry)); - if (affinity) - mutex_unlock(&gang->aff_mutex); mutex_unlock(&inode->i_mutex); spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); goto out; @@ -540,8 +538,8 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) inode->i_fop = &simple_dir_operations; d_instantiate(dentry, inode); - inc_nlink(dir); - inc_nlink(dentry->d_inode); + dir->i_nlink++; + dentry->d_inode->i_nlink++; return ret; out_iput: @@ -661,7 +659,7 @@ enum { Opt_uid, Opt_gid, Opt_mode, Opt_debug, Opt_err, }; -static const match_table_t spufs_tokens = { +static match_table_t spufs_tokens = { { Opt_uid, "uid=%d" }, { Opt_gid, "gid=%d" }, { Opt_mode, "mode=%o" }, @@ -757,7 +755,6 @@ spufs_create_root(struct super_block *sb, void *data) inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; SPUFS_I(inode)->i_ctx = NULL; - inc_nlink(inode); ret = -EINVAL; if (!spufs_parse_options(sb, data, inode)) diff --git a/trunk/arch/powerpc/platforms/chrp/pci.c b/trunk/arch/powerpc/platforms/chrp/pci.c index d3cde6b9d2df..768c262b9368 100644 --- a/trunk/arch/powerpc/platforms/chrp/pci.c +++ b/trunk/arch/powerpc/platforms/chrp/pci.c @@ -260,13 +260,13 @@ chrp_find_bridges(void) dev->full_name); continue; } - hose->first_busno = hose->self_busno = bus_range[0]; + hose->first_busno = bus_range[0]; hose->last_busno = bus_range[1]; model = of_get_property(dev, "model", NULL); if (model == NULL) model = ""; - if (strncmp(model, "IBM, Python", 11) == 0) { + if (of_device_is_compatible(dev, "IBM,python")) { setup_python(hose, dev); } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 272d79a8d289..1ba7ce5aafae 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/chrp/time.c b/trunk/arch/powerpc/platforms/chrp/time.c index 054dfe5b8e77..96d1e4b3c493 100644 --- a/trunk/arch/powerpc/platforms/chrp/time.c +++ b/trunk/arch/powerpc/platforms/chrp/time.c @@ -94,12 +94,12 @@ int chrp_set_rtc_time(struct rtc_time *tmarg) chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - tm.tm_sec = bin2bcd(tm.tm_sec); - tm.tm_min = bin2bcd(tm.tm_min); - tm.tm_hour = bin2bcd(tm.tm_hour); - tm.tm_mon = bin2bcd(tm.tm_mon); - tm.tm_mday = bin2bcd(tm.tm_mday); - tm.tm_year = bin2bcd(tm.tm_year); + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); } chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS); chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES); @@ -136,12 +136,12 @@ void chrp_get_rtc_time(struct rtc_time *tm) } while (sec != chrp_cmos_clock_read(RTC_SECONDS)); if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); } if (year < 70) year += 100; diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 7a2ba39d7811..84e2d78b9a62 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -164,6 +164,7 @@ static void __init mpc7448_hpc2_init_IRQ(void) void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) { seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); + seq_printf(m, "machine\t\t: MPC7448hpc2\n"); } void mpc7448_hpc2_restart(char *cmd) diff --git a/trunk/arch/powerpc/platforms/iseries/exception.S b/trunk/arch/powerpc/platforms/iseries/exception.S index 2f581521eb9b..8ff330d026ca 100644 --- a/trunk/arch/powerpc/platforms/iseries/exception.S +++ b/trunk/arch/powerpc/platforms/iseries/exception.S @@ -38,13 +38,12 @@ .globl system_reset_iSeries system_reset_iSeries: - bl .relative_toc mfspr r13,SPRN_SPRG3 /* Get alpaca address */ - LOAD_REG_ADDR(r23, alpaca) + LOAD_REG_IMMEDIATE(r23, alpaca) li r0,ALPACA_SIZE sub r23,r13,r23 divdu r23,r23,r0 /* r23 has cpu number */ - LOAD_REG_ADDR(r13, paca) + LOAD_REG_IMMEDIATE(r13, paca) mulli r0,r23,PACA_SIZE add r13,r13,r0 mtspr SPRN_SPRG3,r13 /* Save it away for the future */ @@ -61,14 +60,14 @@ system_reset_iSeries: mtspr SPRN_CTRLT,r4 /* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */ -/* In the UP case we'll yield() later, and we will not access the paca anyway */ +/* In the UP case we'll yeild() later, and we will not access the paca anyway */ #ifdef CONFIG_SMP 1: HMT_LOW - LOAD_REG_ADDR(r23, __secondary_hold_spinloop) + LOAD_REG_IMMEDIATE(r23, __secondary_hold_spinloop) ld r23,0(r23) sync - LOAD_REG_ADDR(r3,current_set) + LOAD_REG_IMMEDIATE(r3,current_set) sldi r28,r24,3 /* get current_set[cpu#] */ ldx r3,r3,r28 addi r1,r3,THREAD_SIZE @@ -91,7 +90,7 @@ system_reset_iSeries: lbz r23,PACAPROCSTART(r13) /* Test if this processor * should start */ sync - LOAD_REG_ADDR(r3,current_set) + LOAD_REG_IMMEDIATE(r3,current_set) sldi r28,r24,3 /* get current_set[cpu#] */ ldx r3,r3,r28 addi r1,r3,THREAD_SIZE @@ -256,8 +255,8 @@ hardware_interrupt_iSeries_masked: _INIT_STATIC(__start_initialization_iSeries) /* Clear out the BSS */ - LOAD_REG_ADDR(r11,__bss_stop) - LOAD_REG_ADDR(r8,__bss_start) + LOAD_REG_IMMEDIATE(r11,__bss_stop) + LOAD_REG_IMMEDIATE(r8,__bss_start) sub r11,r11,r8 /* bss size */ addi r11,r11,7 /* round up to an even double word */ rldicl. r11,r11,61,3 /* shift right by 3 */ @@ -268,11 +267,15 @@ _INIT_STATIC(__start_initialization_iSeries) 3: stdu r0,8(r8) bdnz 3b 4: - LOAD_REG_ADDR(r1,init_thread_union) + LOAD_REG_IMMEDIATE(r1,init_thread_union) addi r1,r1,THREAD_SIZE li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) + LOAD_REG_IMMEDIATE(r2,__toc_start) + addi r2,r2,0x4000 + addi r2,r2,0x4000 + bl .iSeries_early_setup bl .early_setup diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index 3689c2413d24..731d7b157749 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -722,13 +722,13 @@ static int mf_set_rtc(struct rtc_time *tm) day = tm->tm_mday; mon = tm->tm_mon + 1; - sec = bin2bcd(sec); - min = bin2bcd(min); - hour = bin2bcd(hour); - mon = bin2bcd(mon); - day = bin2bcd(day); - y1 = bin2bcd(y1); - y2 = bin2bcd(y2); + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hour); + BIN_TO_BCD(mon); + BIN_TO_BCD(day); + BIN_TO_BCD(y1); + BIN_TO_BCD(y2); memset(ce_time, 0, sizeof(ce_time)); ce_time[3] = 0x41; @@ -777,12 +777,12 @@ static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm) u8 day = ce_msg[10]; u8 mon = ce_msg[11]; - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); if (year <= 69) year += 100; diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index d4c61c3c9669..364714757cf1 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/maple/time.c b/trunk/arch/powerpc/platforms/maple/time.c index eac569dee27c..53bca132fb48 100644 --- a/trunk/arch/powerpc/platforms/maple/time.c +++ b/trunk/arch/powerpc/platforms/maple/time.c @@ -68,12 +68,12 @@ void maple_get_rtc_time(struct rtc_time *tm) if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - tm->tm_sec = bcd2bin(tm->tm_sec); - tm->tm_min = bcd2bin(tm->tm_min); - tm->tm_hour = bcd2bin(tm->tm_hour); - tm->tm_mday = bcd2bin(tm->tm_mday); - tm->tm_mon = bcd2bin(tm->tm_mon); - tm->tm_year = bcd2bin(tm->tm_year); + BCD_TO_BIN(tm->tm_sec); + BCD_TO_BIN(tm->tm_min); + BCD_TO_BIN(tm->tm_hour); + BCD_TO_BIN(tm->tm_mday); + BCD_TO_BIN(tm->tm_mon); + BCD_TO_BIN(tm->tm_year); } if ((tm->tm_year + 1900) < 1970) tm->tm_year += 100; @@ -104,12 +104,12 @@ int maple_set_rtc_time(struct rtc_time *tm) year = tm->tm_year; if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bin2bcd(sec); - min = bin2bcd(min); - hour = bin2bcd(hour); - mon = bin2bcd(mon); - mday = bin2bcd(mday); - year = bin2bcd(year); + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hour); + BIN_TO_BCD(mon); + BIN_TO_BCD(mday); + BIN_TO_BCD(year); } maple_clock_write(sec, RTC_SECONDS); maple_clock_write(min, RTC_MINUTES); diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c index e6c0040ee797..5169ecc37123 100644 --- a/trunk/arch/powerpc/platforms/powermac/feature.c +++ b/trunk/arch/powerpc/platforms/powermac/feature.c @@ -2677,7 +2677,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ macio_chips[i].of_node = node; macio_chips[i].type = type; macio_chips[i].base = base; - macio_chips[i].flags = MACIO_FLAG_SCCA_ON | MACIO_FLAG_SCCB_ON; + macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; macio_chips[i].name = macio_names[type]; revp = of_get_property(node, "revision-id", NULL); if (revp) diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 82c14d203d8b..88ccf3a08a9c 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index 40f72c2a4699..4ae3d00e0bdd 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -787,7 +787,7 @@ static void __devinit smp_core99_kick_cpu(int nr) { unsigned int save_vector; unsigned long target, flags; - unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100); + unsigned int *vector = (unsigned int *)(KERNELBASE+0x100); if (nr < 0 || nr > 3) return; @@ -801,7 +801,7 @@ static void __devinit smp_core99_kick_cpu(int nr) save_vector = *vector; /* Setup fake reset vector that does - * b __secondary_start_pmac_0 + nr*8 + * b __secondary_start_pmac_0 + nr*8 - KERNELBASE */ target = (unsigned long) __secondary_start_pmac_0 + nr * 8; patch_branch(vector, target, BRANCH_SET_LINK); diff --git a/trunk/arch/powerpc/platforms/powermac/time.c b/trunk/arch/powerpc/platforms/powermac/time.c index 59eb840d8ce2..bbbefd64ab59 100644 --- a/trunk/arch/powerpc/platforms/powermac/time.c +++ b/trunk/arch/powerpc/platforms/powermac/time.c @@ -93,14 +93,11 @@ static void to_rtc_time(unsigned long now, struct rtc_time *tm) } #endif -#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) || \ - defined(CONFIG_PMAC_SMU) static unsigned long from_rtc_time(struct rtc_time *tm) { return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } -#endif #ifdef CONFIG_ADB_CUDA static unsigned long cuda_get_time(void) diff --git a/trunk/arch/powerpc/platforms/ps3/system-bus.c b/trunk/arch/powerpc/platforms/ps3/system-bus.c index a789bf58ca8b..280ee88cb0b0 100644 --- a/trunk/arch/powerpc/platforms/ps3/system-bus.c +++ b/trunk/arch/powerpc/platforms/ps3/system-bus.c @@ -762,7 +762,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) }; dev->core.archdata.of_node = NULL; - set_dev_node(&dev->core, 0); + dev->core.archdata.numa_node = 0; pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); diff --git a/trunk/arch/powerpc/platforms/pseries/cmm.c b/trunk/arch/powerpc/platforms/pseries/cmm.c index 5cd4d2761620..38fe32a7cc70 100644 --- a/trunk/arch/powerpc/platforms/pseries/cmm.c +++ b/trunk/arch/powerpc/platforms/pseries/cmm.c @@ -121,7 +121,7 @@ static long cmm_alloc_pages(long nr) npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC); if (!npa) { - pr_info("%s: Can not allocate new page list\n", __func__); + pr_info("%s: Can not allocate new page list\n", __FUNCTION__); free_page(addr); break; } @@ -138,7 +138,7 @@ static long cmm_alloc_pages(long nr) } if ((rc = plpar_page_set_loaned(__pa(addr)))) { - pr_err("%s: Can not set page to loaned. rc=%ld\n", __func__, rc); + pr_err("%s: Can not set page to loaned. rc=%ld\n", __FUNCTION__, rc); spin_unlock(&cmm_lock); free_page(addr); break; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index 0ad56ff7b4a0..8c1ca477c52c 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -41,7 +41,7 @@ static inline const char * pcid_name (struct pci_dev *pdev) return ""; } -#if 0 +#ifdef DEBUG static void print_device_node_tree(struct pci_dn *pdn, int dent) { int i; diff --git a/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c b/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c index 140d02a5232a..a1a368dd2d99 100644 --- a/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/trunk/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -21,7 +21,7 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) struct zone *zone; int ret; - start_pfn = base >> PAGE_SHIFT; + start_pfn = base >> PFN_SECTION_SHIFT; zone = page_zone(pfn_to_page(start_pfn)); /* diff --git a/trunk/arch/powerpc/platforms/pseries/reconfig.c b/trunk/arch/powerpc/platforms/pseries/reconfig.c index c591a25b0b0d..7637bd38c795 100644 --- a/trunk/arch/powerpc/platforms/pseries/reconfig.c +++ b/trunk/arch/powerpc/platforms/pseries/reconfig.c @@ -466,11 +466,11 @@ static int do_update_property(char *buf, size_t bufsize) else action = PSERIES_DRCONF_MEM_REMOVE; - rc = blocking_notifier_call_chain(&pSeries_reconfig_chain, - action, value); + blocking_notifier_call_chain(&pSeries_reconfig_chain, + action, value); } - return rc; + return 0; } /** diff --git a/trunk/arch/powerpc/platforms/pseries/rtasd.c b/trunk/arch/powerpc/platforms/pseries/rtasd.c index f4e55be2eea9..c9ffd8c225f1 100644 --- a/trunk/arch/powerpc/platforms/pseries/rtasd.c +++ b/trunk/arch/powerpc/platforms/pseries/rtasd.c @@ -295,29 +295,19 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf, if (!tmp) return -ENOMEM; + spin_lock_irqsave(&rtasd_log_lock, s); /* if it's 0, then we know we got the last one (the one in NVRAM) */ - while (rtas_log_size == 0) { - if (file->f_flags & O_NONBLOCK) { - spin_unlock_irqrestore(&rtasd_log_lock, s); - error = -EAGAIN; - goto out; - } - - if (!logging_enabled) { - spin_unlock_irqrestore(&rtasd_log_lock, s); - error = -ENODATA; - goto out; - } + if (rtas_log_size == 0 && logging_enabled) nvram_clear_error_log(); + spin_unlock_irqrestore(&rtasd_log_lock, s); - spin_unlock_irqrestore(&rtasd_log_lock, s); - error = wait_event_interruptible(rtas_log_wait, rtas_log_size); - if (error) - goto out; - spin_lock_irqsave(&rtasd_log_lock, s); - } + error = wait_event_interruptible(rtas_log_wait, rtas_log_size); + if (error) + goto out; + + spin_lock_irqsave(&rtasd_log_lock, s); offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); memcpy(tmp, &rtas_log_buf[offset], count); diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index ec341707e41b..7b01d67b4e48 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/pseries/smp.c b/trunk/arch/powerpc/platforms/pseries/smp.c index e00f96baa381..9d8f8c84ab89 100644 --- a/trunk/arch/powerpc/platforms/pseries/smp.c +++ b/trunk/arch/powerpc/platforms/pseries/smp.c @@ -37,6 +37,7 @@ #include #include #include +#include "xics.h" #include #include #include @@ -48,7 +49,6 @@ #include "plpar_wrappers.h" #include "pseries.h" -#include "xics.h" /* @@ -105,6 +105,36 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) } #ifdef CONFIG_XICS +static inline void smp_xics_do_message(int cpu, int msg) +{ + set_bit(msg, &xics_ipi_message[cpu].value); + mb(); + xics_cause_IPI(cpu); +} + +static void smp_xics_message_pass(int target, int msg) +{ + unsigned int i; + + if (target < NR_CPUS) { + smp_xics_do_message(target, msg); + } else { + for_each_online_cpu(i) { + if (target == MSG_ALL_BUT_SELF + && i == smp_processor_id()) + continue; + smp_xics_do_message(i, msg); + } + } +} + +static int __init smp_xics_probe(void) +{ + xics_request_IPIs(); + + return cpus_weight(cpu_possible_map); +} + static void __devinit smp_xics_setup_cpu(int cpu) { if (cpu != boot_cpuid) diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index e1904774a70f..0fc830f576f5 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -9,30 +9,32 @@ * 2 of the License, or (at your option) any later version. */ + #include #include #include #include #include #include +#include #include +#include #include #include -#include #include +#include #include #include #include #include #include #include +#include #include "xics.h" #include "plpar_wrappers.h" -static struct irq_host *xics_host; - #define XICS_IPI 2 #define XICS_IRQ_SPURIOUS 0 @@ -45,20 +47,6 @@ static struct irq_host *xics_host; */ #define IPI_PRIORITY 4 -static unsigned int default_server = 0xFF; -static unsigned int default_distrib_server = 0; -static unsigned int interrupt_server_size = 8; - -/* RTAS service tokens */ -static int ibm_get_xive; -static int ibm_set_xive; -static int ibm_int_on; -static int ibm_int_off; - - -/* Direct hardware low level accessors */ - -/* The part of the interrupt presentation layer that we care about */ struct xics_ipl { union { u32 word; @@ -77,6 +65,27 @@ struct xics_ipl { static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; +static unsigned int default_server = 0xFF; +static unsigned int default_distrib_server = 0; +static unsigned int interrupt_server_size = 8; + +static struct irq_host *xics_host; + +/* + * XICS only has a single IPI, so encode the messages per CPU + */ +struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; + +/* RTAS service tokens */ +static int ibm_get_xive; +static int ibm_set_xive; +static int ibm_int_on; +static int ibm_int_off; + + +/* Direct HW low level accessors */ + + static inline unsigned int direct_xirr_info_get(void) { int cpu = smp_processor_id(); @@ -84,7 +93,7 @@ static inline unsigned int direct_xirr_info_get(void) return in_be32(&xics_per_cpu[cpu]->xirr.word); } -static inline void direct_xirr_info_set(unsigned int value) +static inline void direct_xirr_info_set(int value) { int cpu = smp_processor_id(); @@ -106,6 +115,7 @@ static inline void direct_qirr_info(int n_cpu, u8 value) /* LPAR low level accessors */ + static inline unsigned int lpar_xirr_info_get(void) { unsigned long lpar_rc; @@ -117,14 +127,15 @@ static inline unsigned int lpar_xirr_info_get(void) return (unsigned int)return_value; } -static inline void lpar_xirr_info_set(unsigned int value) +static inline void lpar_xirr_info_set(int value) { unsigned long lpar_rc; + unsigned long val64 = value & 0xffffffff; - lpar_rc = plpar_eoi(value); + lpar_rc = plpar_eoi(val64); if (lpar_rc != H_SUCCESS) - panic("bad return code EOI - rc = %ld, value=%x\n", lpar_rc, - value); + panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc, + val64); } static inline void lpar_cppr_info(u8 value) @@ -146,7 +157,48 @@ static inline void lpar_qirr_info(int n_cpu , u8 value) } -/* Interface to generic irq subsystem */ +/* High level handlers and init code */ + +static void xics_update_irq_servers(void) +{ + int i, j; + struct device_node *np; + u32 ilen; + const u32 *ireg, *isize; + u32 hcpuid; + + /* Find the server numbers for the boot cpu. */ + np = of_get_cpu_node(boot_cpuid, NULL); + BUG_ON(!np); + + ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); + if (!ireg) { + of_node_put(np); + return; + } + + i = ilen / sizeof(int); + hcpuid = get_hard_smp_processor_id(boot_cpuid); + + /* Global interrupt distribution server is specified in the last + * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last + * entry fom this property for current boot cpu id and use it as + * default distribution server + */ + for (j = 0; j < i; j += 2) { + if (ireg[j] == hcpuid) { + default_server = hcpuid; + default_distrib_server = ireg[j+1]; + + isize = of_get_property(np, + "ibm,interrupt-server#-size", NULL); + if (isize) + interrupt_server_size = *isize; + } + } + + of_node_put(np); +} #ifdef CONFIG_SMP static int get_irq_server(unsigned int virq, unsigned int strict_check) @@ -156,6 +208,9 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check) cpumask_t cpumask = irq_desc[virq].affinity; cpumask_t tmp = CPU_MASK_NONE; + if (! cpu_isset(default_server, cpu_online_map)) + xics_update_irq_servers(); + if (!distribute_irqs) return default_server; @@ -183,6 +238,7 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check) } #endif + static void xics_unmask_irq(unsigned int virq) { unsigned int irq; @@ -201,28 +257,21 @@ static void xics_unmask_irq(unsigned int virq) call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, 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); + printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive " + "returned %d\n", irq, call_status); + printk("set_xive %x, server %x\n", ibm_set_xive, server); return; } /* Now unmask the interrupt (often a no-op) */ call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); if (call_status != 0) { - printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n", - __func__, irq, call_status); + printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on " + "returned %d\n", irq, call_status); return; } } -static unsigned int xics_startup(unsigned int virq) -{ - /* unmask it */ - xics_unmask_irq(virq); - return 0; -} - static void xics_mask_real_irq(unsigned int irq) { int call_status; @@ -232,8 +281,8 @@ static void xics_mask_real_irq(unsigned int irq) call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); if (call_status != 0) { - printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n", - __func__, irq, call_status); + printk(KERN_ERR "xics_disable_real_irq: irq=%u: " + "ibm_int_off returned %d\n", irq, call_status); return; } @@ -241,8 +290,8 @@ static void xics_mask_real_irq(unsigned int irq) call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, default_server, 0xff); if (call_status != 0) { - printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n", - __func__, irq, call_status); + printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)" + " returned %d\n", irq, call_status); return; } } @@ -259,77 +308,132 @@ static void xics_mask_irq(unsigned int virq) xics_mask_real_irq(irq); } -static void xics_mask_unknown_vec(unsigned int vec) +static unsigned int xics_startup(unsigned int virq) { - printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec); - xics_mask_real_irq(vec); + unsigned int irq; + + /* force a reverse mapping of the interrupt so it gets in the cache */ + irq = (unsigned int)irq_map[virq].hwirq; + irq_radix_revmap(xics_host, irq); + + /* unmask it */ + xics_unmask_irq(virq); + return 0; +} + +static void xics_eoi_direct(unsigned int virq) +{ + unsigned int irq = (unsigned int)irq_map[virq].hwirq; + + iosync(); + direct_xirr_info_set((0xff << 24) | irq); } -static inline unsigned int xics_xirr_vector(unsigned int xirr) + +static void xics_eoi_lpar(unsigned int virq) { - /* - * The top byte is the old cppr, to be restored on EOI. - * The remaining 24 bits are the vector. - */ - return xirr & 0x00ffffff; + unsigned int irq = (unsigned int)irq_map[virq].hwirq; + + iosync(); + lpar_xirr_info_set((0xff << 24) | irq); } -static unsigned int xics_get_irq_direct(void) +static inline unsigned int xics_remap_irq(unsigned int vec) { - unsigned int xirr = direct_xirr_info_get(); - unsigned int vec = xics_xirr_vector(xirr); unsigned int irq; + vec &= 0x00ffffff; + if (vec == XICS_IRQ_SPURIOUS) return NO_IRQ; - - irq = irq_radix_revmap_lookup(xics_host, vec); + irq = irq_radix_revmap(xics_host, vec); if (likely(irq != NO_IRQ)) return irq; - /* We don't have a linux mapping, so have rtas mask it. */ - xics_mask_unknown_vec(vec); - - /* We might learn about it later, so EOI it */ - direct_xirr_info_set(xirr); + printk(KERN_ERR "Interrupt %u (real) is invalid," + " disabling it.\n", vec); + xics_mask_real_irq(vec); return NO_IRQ; } +static unsigned int xics_get_irq_direct(void) +{ + return xics_remap_irq(direct_xirr_info_get()); +} + static unsigned int xics_get_irq_lpar(void) { - unsigned int xirr = lpar_xirr_info_get(); - unsigned int vec = xics_xirr_vector(xirr); - unsigned int irq; + return xics_remap_irq(lpar_xirr_info_get()); +} - if (vec == XICS_IRQ_SPURIOUS) - return NO_IRQ; +#ifdef CONFIG_SMP - irq = irq_radix_revmap_lookup(xics_host, vec); - if (likely(irq != NO_IRQ)) - return irq; +static irqreturn_t xics_ipi_dispatch(int cpu) +{ + WARN_ON(cpu_is_offline(cpu)); + + while (xics_ipi_message[cpu].value) { + if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, + &xics_ipi_message[cpu].value)) { + mb(); + smp_message_recv(PPC_MSG_CALL_FUNCTION); + } + if (test_and_clear_bit(PPC_MSG_RESCHEDULE, + &xics_ipi_message[cpu].value)) { + mb(); + smp_message_recv(PPC_MSG_RESCHEDULE); + } + if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, + &xics_ipi_message[cpu].value)) { + mb(); + smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); + } +#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) + if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, + &xics_ipi_message[cpu].value)) { + mb(); + smp_message_recv(PPC_MSG_DEBUGGER_BREAK); + } +#endif + } + return IRQ_HANDLED; +} - /* We don't have a linux mapping, so have RTAS mask it. */ - xics_mask_unknown_vec(vec); +static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) +{ + int cpu = smp_processor_id(); - /* We might learn about it later, so EOI it */ - lpar_xirr_info_set(xirr); - return NO_IRQ; + direct_qirr_info(cpu, 0xff); + + return xics_ipi_dispatch(cpu); } -static void xics_eoi_direct(unsigned int virq) +static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id) { - unsigned int irq = (unsigned int)irq_map[virq].hwirq; + int cpu = smp_processor_id(); - iosync(); - direct_xirr_info_set((0xff << 24) | irq); + lpar_qirr_info(cpu, 0xff); + + return xics_ipi_dispatch(cpu); } -static void xics_eoi_lpar(unsigned int virq) +void xics_cause_IPI(int cpu) { - unsigned int irq = (unsigned int)irq_map[virq].hwirq; + if (firmware_has_feature(FW_FEATURE_LPAR)) + lpar_qirr_info(cpu, IPI_PRIORITY); + else + direct_qirr_info(cpu, IPI_PRIORITY); +} +#endif /* CONFIG_SMP */ + +static void xics_set_cpu_priority(unsigned char cppr) +{ + if (firmware_has_feature(FW_FEATURE_LPAR)) + lpar_cppr_info(cppr); + else + direct_cppr_info(cppr); iosync(); - lpar_xirr_info_set((0xff << 24) | irq); } static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) @@ -346,8 +450,8 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { - printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n", - __func__, irq, status); + printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive " + "returns %d\n", irq, status); return; } @@ -359,9 +463,8 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) if (irq_server == -1) { char cpulist[128]; cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); - printk(KERN_WARNING - "%s: No online cpus in the mask %s for irq %d\n", - __func__, cpulist, virq); + printk(KERN_WARNING "xics_set_affinity: No online cpus in " + "the mask %s for irq %d\n", cpulist, virq); return; } @@ -369,12 +472,28 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) irq, irq_server, xics_status[1]); if (status) { - printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n", - __func__, irq, status); + printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " + "returns %d\n", irq, status); return; } } +void xics_setup_cpu(void) +{ + xics_set_cpu_priority(0xff); + + /* + * Put the calling processor into the GIQ. This is really only + * necessary from a secondary thread as the OF start-cpu interface + * performs this function for us on primary threads. + * + * XXX: undo of teardown on kexec needs this too, as may hotplug + */ + rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); +} + + static struct irq_chip xics_pic_direct = { .typename = " XICS ", .startup = xics_startup, @@ -384,6 +503,7 @@ static struct irq_chip xics_pic_direct = { .set_affinity = xics_set_affinity }; + static struct irq_chip xics_pic_lpar = { .typename = " XICS ", .startup = xics_startup, @@ -393,9 +513,6 @@ static struct irq_chip xics_pic_lpar = { .set_affinity = xics_set_affinity }; - -/* Interface to arch irq controller subsystem layer */ - /* Points to the irq_chip we're actually using */ static struct irq_chip *xics_irq_chip; @@ -413,9 +530,6 @@ static int xics_host_map(struct irq_host *h, unsigned int virq, { pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw); - /* Insert the interrupt mapping into the radix tree for fast lookup */ - irq_radix_revmap_insert(xics_host, virq, hw); - get_irq_desc(virq)->status |= IRQ_LEVEL; set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq); return 0; @@ -455,169 +569,10 @@ static void __init xics_init_host(void) irq_set_default_host(xics_host); } - -/* Inter-processor interrupt support */ - -#ifdef CONFIG_SMP -/* - * XICS only has a single IPI, so encode the messages per CPU - */ -struct xics_ipi_struct { - unsigned long value; - } ____cacheline_aligned; - -static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; - -static inline void smp_xics_do_message(int cpu, int msg) -{ - set_bit(msg, &xics_ipi_message[cpu].value); - mb(); - if (firmware_has_feature(FW_FEATURE_LPAR)) - lpar_qirr_info(cpu, IPI_PRIORITY); - else - direct_qirr_info(cpu, IPI_PRIORITY); -} - -void smp_xics_message_pass(int target, int msg) -{ - unsigned int i; - - if (target < NR_CPUS) { - smp_xics_do_message(target, msg); - } else { - for_each_online_cpu(i) { - if (target == MSG_ALL_BUT_SELF - && i == smp_processor_id()) - continue; - smp_xics_do_message(i, msg); - } - } -} - -static irqreturn_t xics_ipi_dispatch(int cpu) -{ - WARN_ON(cpu_is_offline(cpu)); - - mb(); /* order mmio clearing qirr */ - while (xics_ipi_message[cpu].value) { - if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, - &xics_ipi_message[cpu].value)) { - smp_message_recv(PPC_MSG_CALL_FUNCTION); - } - if (test_and_clear_bit(PPC_MSG_RESCHEDULE, - &xics_ipi_message[cpu].value)) { - smp_message_recv(PPC_MSG_RESCHEDULE); - } - if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, - &xics_ipi_message[cpu].value)) { - smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); - } -#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) - if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, - &xics_ipi_message[cpu].value)) { - smp_message_recv(PPC_MSG_DEBUGGER_BREAK); - } -#endif - } - return IRQ_HANDLED; -} - -static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) -{ - int cpu = smp_processor_id(); - - direct_qirr_info(cpu, 0xff); - - return xics_ipi_dispatch(cpu); -} - -static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id) -{ - int cpu = smp_processor_id(); - - lpar_qirr_info(cpu, 0xff); - - return xics_ipi_dispatch(cpu); -} - -static void xics_request_ipi(void) -{ - unsigned int ipi; - int rc; - - ipi = irq_create_mapping(xics_host, XICS_IPI); - BUG_ON(ipi == NO_IRQ); - - /* - * IPIs are marked IRQF_DISABLED as they must run with irqs - * disabled - */ - set_irq_handler(ipi, handle_percpu_irq); - if (firmware_has_feature(FW_FEATURE_LPAR)) - rc = request_irq(ipi, xics_ipi_action_lpar, - IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL); - else - rc = request_irq(ipi, xics_ipi_action_direct, - IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL); - BUG_ON(rc); -} - -int __init smp_xics_probe(void) -{ - xics_request_ipi(); - - return cpus_weight(cpu_possible_map); -} - -#endif /* CONFIG_SMP */ - - -/* Initialization */ - -static void xics_update_irq_servers(void) -{ - int i, j; - struct device_node *np; - u32 ilen; - const u32 *ireg, *isize; - u32 hcpuid; - - /* Find the server numbers for the boot cpu. */ - np = of_get_cpu_node(boot_cpuid, NULL); - BUG_ON(!np); - - ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); - if (!ireg) { - of_node_put(np); - return; - } - - i = ilen / sizeof(int); - hcpuid = get_hard_smp_processor_id(boot_cpuid); - - /* Global interrupt distribution server is specified in the last - * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last - * entry fom this property for current boot cpu id and use it as - * default distribution server - */ - for (j = 0; j < i; j += 2) { - if (ireg[j] == hcpuid) { - default_server = hcpuid; - default_distrib_server = ireg[j+1]; - } - } - - /* get the bit size of server numbers */ - isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); - if (isize) - interrupt_server_size = *isize; - - of_node_put(np); -} - static void __init xics_map_one_cpu(int hw_id, unsigned long addr, unsigned long size) { +#ifdef CONFIG_SMP int i; /* This may look gross but it's good enough for now, we don't quite @@ -631,6 +586,11 @@ static void __init xics_map_one_cpu(int hw_id, unsigned long addr, return; } } +#else + if (hw_id != 0) + return; + xics_per_cpu[0] = ioremap(addr, size); +#endif /* CONFIG_SMP */ } static void __init xics_init_one_node(struct device_node *np, @@ -692,17 +652,15 @@ void __init xics_init_IRQ(void) for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") { found = 1; - if (firmware_has_feature(FW_FEATURE_LPAR)) { - of_node_put(np); + if (firmware_has_feature(FW_FEATURE_LPAR)) break; - } xics_init_one_node(np, &indx); } if (found == 0) return; - xics_update_irq_servers(); xics_init_host(); + xics_update_irq_servers(); if (firmware_has_feature(FW_FEATURE_LPAR)) ppc_md.get_irq = xics_get_irq_lpar; @@ -714,31 +672,30 @@ void __init xics_init_IRQ(void) ppc64_boot_msg(0x21, "XICS Done"); } -/* Cpu startup, shutdown, and hotplug */ -static void xics_set_cpu_priority(unsigned char cppr) -{ - if (firmware_has_feature(FW_FEATURE_LPAR)) - lpar_cppr_info(cppr); - else - direct_cppr_info(cppr); - iosync(); -} - -/* Have the calling processor join or leave the specified global queue */ -static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) +#ifdef CONFIG_SMP +void xics_request_IPIs(void) { - int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, - (1UL << interrupt_server_size) - 1 - gserver, join); - WARN_ON(status < 0); -} + unsigned int ipi; + int rc; -void xics_setup_cpu(void) -{ - xics_set_cpu_priority(0xff); + ipi = irq_create_mapping(xics_host, XICS_IPI); + BUG_ON(ipi == NO_IRQ); - xics_set_cpu_giq(default_distrib_server, 1); + /* + * IPIs are marked IRQF_DISABLED as they must run with irqs + * disabled + */ + set_irq_handler(ipi, handle_percpu_irq); + if (firmware_has_feature(FW_FEATURE_LPAR)) + rc = request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED, + "IPI", NULL); + else + rc = request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED, + "IPI", NULL); + BUG_ON(rc); } +#endif /* CONFIG_SMP */ void xics_teardown_cpu(void) { @@ -746,7 +703,9 @@ void xics_teardown_cpu(void) xics_set_cpu_priority(0); - /* Clear any pending IPI request */ + /* + * Clear IPI + */ if (firmware_has_feature(FW_FEATURE_LPAR)) lpar_qirr_info(cpu, 0xff); else @@ -755,28 +714,34 @@ void xics_teardown_cpu(void) void xics_kexec_teardown_cpu(int secondary) { + unsigned int ipi; + struct irq_desc *desc; + xics_teardown_cpu(); /* - * we take the ipi irq but and never return so we - * need to EOI the IPI, but want to leave our priority 0 + * we need to EOI the IPI * - * should we check all the other interrupts too? + * probably need to check all the other interrupts too * should we be flagging idle loop instead? * or creating some task to be scheduled? */ - if (firmware_has_feature(FW_FEATURE_LPAR)) - lpar_xirr_info_set((0x00 << 24) | XICS_IPI); - else - direct_xirr_info_set((0x00 << 24) | XICS_IPI); + ipi = irq_find_mapping(xics_host, XICS_IPI); + if (ipi == XICS_IRQ_SPURIOUS) + return; + desc = get_irq_desc(ipi); + if (desc->chip && desc->chip->eoi) + desc->chip->eoi(ipi); /* * Some machines need to have at least one cpu in the GIQ, * so leave the master cpu in the group. */ if (secondary) - xics_set_cpu_giq(default_distrib_server, 0); + rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - + default_distrib_server, 0); } #ifdef CONFIG_HOTPLUG_CPU @@ -784,18 +749,17 @@ void xics_kexec_teardown_cpu(int secondary) /* Interrupts are disabled. */ void xics_migrate_irqs_away(void) { + int status; int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); unsigned int irq, virq; - /* If we used to be the default server, move to the new "boot_cpuid" */ - if (hw_cpu == default_server) - xics_update_irq_servers(); - /* Reject any interrupt that was queued to us... */ xics_set_cpu_priority(0); - /* Remove ourselves from the global interrupt queue */ - xics_set_cpu_giq(default_distrib_server, 0); + /* remove ourselves from the global interrupt queue */ + status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); + WARN_ON(status < 0); /* Allow IPIs again... */ xics_set_cpu_priority(DEFAULT_PRIORITY); @@ -803,7 +767,6 @@ void xics_migrate_irqs_away(void) for_each_irq(virq) { struct irq_desc *desc; int xics_status[2]; - int status; unsigned long flags; /* We cant set affinity on ISA interrupts */ @@ -827,8 +790,9 @@ void xics_migrate_irqs_away(void) status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { - printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n", - __func__, irq, status); + printk(KERN_ERR "migrate_irqs_away: irq=%u " + "ibm,get-xive returns %d\n", + virq, status); goto unlock; } diff --git a/trunk/arch/powerpc/platforms/pseries/xics.h b/trunk/arch/powerpc/platforms/pseries/xics.h index d1d5a83039ae..1c5321ae8f2f 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.h +++ b/trunk/arch/powerpc/platforms/pseries/xics.h @@ -12,12 +12,20 @@ #ifndef _POWERPC_KERNEL_XICS_H #define _POWERPC_KERNEL_XICS_H +#include + extern void xics_init_IRQ(void); extern void xics_setup_cpu(void); extern void xics_teardown_cpu(void); extern void xics_kexec_teardown_cpu(int secondary); +extern void xics_cause_IPI(int cpu); +extern void xics_request_IPIs(void); extern void xics_migrate_irqs_away(void); -extern int smp_xics_probe(void); -extern void smp_xics_message_pass(int target, int msg); + +struct xics_ipi_struct { + volatile unsigned long value; +} ____cacheline_aligned; + +extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; #endif /* _POWERPC_KERNEL_XICS_H */ diff --git a/trunk/arch/powerpc/sysdev/Kconfig b/trunk/arch/powerpc/sysdev/Kconfig index 396582835cb5..72fb35b9ebca 100644 --- a/trunk/arch/powerpc/sysdev/Kconfig +++ b/trunk/arch/powerpc/sysdev/Kconfig @@ -6,9 +6,3 @@ config PPC4xx_PCI_EXPRESS bool depends on PCI && 4xx default n - -config PPC_MSI_BITMAP - bool - depends on PCI_MSI - default y if MPIC - default y if FSL_PCI diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index a44709a94f97..a90054b56d5c 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -5,7 +5,6 @@ endif mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) fsl-msi-obj-$(CONFIG_PCI_MSI) += fsl_msi.o -obj-$(CONFIG_PPC_MSI_BITMAP) += msi_bitmap.o obj-$(CONFIG_PPC_MPC106) += grackle.o obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o @@ -16,7 +15,6 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_FSL_GTM) += fsl_gtm.o -obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ @@ -38,12 +36,15 @@ ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_4xx) += ppc4xx_pci.o endif +# Temporary hack until we have migrated to asm-powerpc +ifeq ($(ARCH),powerpc) obj-$(CONFIG_CPM) += cpm_common.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o obj-$(CONFIG_PPC_DCR) += dcr.o obj-$(CONFIG_8xx) += mpc8xx_pic.o cpm1.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o +endif ifeq ($(CONFIG_SUSPEND),y) obj-$(CONFIG_6xx) += 6xx-suspend.o diff --git a/trunk/arch/powerpc/sysdev/cpm1.c b/trunk/arch/powerpc/sysdev/cpm1.c index 490473ce8103..4a04823e8423 100644 --- a/trunk/arch/powerpc/sysdev/cpm1.c +++ b/trunk/arch/powerpc/sysdev/cpm1.c @@ -546,11 +546,15 @@ static int cpm1_gpio16_get(struct gpio_chip *gc, unsigned int gpio) return !!(in_be16(&iop->dat) & pin_mask); } -static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask, - int value) +static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value) { + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc); struct cpm_ioport16 __iomem *iop = mm_gc->regs; + unsigned long flags; + u16 pin_mask = 1 << (15 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); if (value) cpm1_gc->cpdata |= pin_mask; @@ -558,18 +562,6 @@ static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask, cpm1_gc->cpdata &= ~pin_mask; out_be16(&iop->dat, cpm1_gc->cpdata); -} - -static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc); - unsigned long flags; - u16 pin_mask = 1 << (15 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - __cpm1_gpio16_set(mm_gc, pin_mask, value); spin_unlock_irqrestore(&cpm1_gc->lock, flags); } @@ -577,17 +569,14 @@ static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value) static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc); struct cpm_ioport16 __iomem *iop = mm_gc->regs; - unsigned long flags; - u16 pin_mask = 1 << (15 - gpio); + u16 pin_mask; - spin_lock_irqsave(&cpm1_gc->lock, flags); + pin_mask = 1 << (15 - gpio); setbits16(&iop->dir, pin_mask); - __cpm1_gpio16_set(mm_gc, pin_mask, val); - spin_unlock_irqrestore(&cpm1_gc->lock, flags); + cpm1_gpio16_set(gc, gpio, val); return 0; } @@ -595,17 +584,13 @@ static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) static int cpm1_gpio16_dir_in(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc); struct cpm_ioport16 __iomem *iop = mm_gc->regs; - unsigned long flags; - u16 pin_mask = 1 << (15 - gpio); + u16 pin_mask; - spin_lock_irqsave(&cpm1_gc->lock, flags); + pin_mask = 1 << (15 - gpio); clrbits16(&iop->dir, pin_mask); - spin_unlock_irqrestore(&cpm1_gc->lock, flags); - return 0; } @@ -670,11 +655,15 @@ static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio) return !!(in_be32(&iop->dat) & pin_mask); } -static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask, - int value) +static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value) { + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc); struct cpm_ioport32b __iomem *iop = mm_gc->regs; + unsigned long flags; + u32 pin_mask = 1 << (31 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); if (value) cpm1_gc->cpdata |= pin_mask; @@ -682,18 +671,6 @@ static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask, cpm1_gc->cpdata &= ~pin_mask; out_be32(&iop->dat, cpm1_gc->cpdata); -} - -static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc); - unsigned long flags; - u32 pin_mask = 1 << (31 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - __cpm1_gpio32_set(mm_gc, pin_mask, value); spin_unlock_irqrestore(&cpm1_gc->lock, flags); } @@ -701,17 +678,14 @@ static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value) static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc); struct cpm_ioport32b __iomem *iop = mm_gc->regs; - unsigned long flags; - u32 pin_mask = 1 << (31 - gpio); + u32 pin_mask; - spin_lock_irqsave(&cpm1_gc->lock, flags); + pin_mask = 1 << (31 - gpio); setbits32(&iop->dir, pin_mask); - __cpm1_gpio32_set(mm_gc, pin_mask, val); - spin_unlock_irqrestore(&cpm1_gc->lock, flags); + cpm1_gpio32_set(gc, gpio, val); return 0; } @@ -719,17 +693,13 @@ static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio32_chip *cpm1_gc = to_cpm1_gpio32_chip(mm_gc); struct cpm_ioport32b __iomem *iop = mm_gc->regs; - unsigned long flags; - u32 pin_mask = 1 << (31 - gpio); + u32 pin_mask; - spin_lock_irqsave(&cpm1_gc->lock, flags); + pin_mask = 1 << (31 - gpio); clrbits32(&iop->dir, pin_mask); - spin_unlock_irqrestore(&cpm1_gc->lock, flags); - return 0; } diff --git a/trunk/arch/powerpc/sysdev/fsl_lbc.c b/trunk/arch/powerpc/sysdev/fsl_lbc.c index 0494ee55920f..422c8faef593 100644 --- a/trunk/arch/powerpc/sysdev/fsl_lbc.c +++ b/trunk/arch/powerpc/sysdev/fsl_lbc.c @@ -11,19 +11,14 @@ * (at your option) any later version. */ -#include -#include #include -#include -#include -#include -#include #include -#include #include -static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock); -static struct fsl_lbc_regs __iomem *fsl_lbc_regs; +spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock); + +struct fsl_lbc_regs __iomem *fsl_lbc_regs; +EXPORT_SYMBOL(fsl_lbc_regs); static char __initdata *compat_lbc[] = { "fsl,pq2-localbus", @@ -132,43 +127,3 @@ int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm) return 0; } EXPORT_SYMBOL(fsl_upm_find); - -/** - * fsl_upm_run_pattern - actually run an UPM pattern - * @upm: pointer to the fsl_upm structure obtained via fsl_upm_find - * @io_base: remapped pointer to where memory access should happen - * @mar: MAR register content during pattern execution - * - * This function triggers dummy write to the memory specified by the io_base, - * thus UPM pattern actually executed. Note that mar usage depends on the - * pre-programmed AMX bits in the UPM RAM. - */ -int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar) -{ - int ret = 0; - unsigned long flags; - - spin_lock_irqsave(&fsl_lbc_lock, flags); - - out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width)); - - switch (upm->width) { - case 8: - out_8(io_base, 0x0); - break; - case 16: - out_be16(io_base, 0x0); - break; - case 32: - out_be32(io_base, 0x0); - break; - default: - ret = -EINVAL; - break; - } - - spin_unlock_irqrestore(&fsl_lbc_lock, flags); - - return ret; -} -EXPORT_SYMBOL(fsl_upm_run_pattern); diff --git a/trunk/arch/powerpc/sysdev/fsl_msi.c b/trunk/arch/powerpc/sysdev/fsl_msi.c index f25ce818d40a..2c5187cc8a24 100644 --- a/trunk/arch/powerpc/sysdev/fsl_msi.c +++ b/trunk/arch/powerpc/sysdev/fsl_msi.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include #include @@ -66,22 +67,95 @@ static struct irq_host_ops fsl_msi_host_ops = { .map = fsl_msi_host_map, }; +static irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num) +{ + unsigned long flags; + int order = get_count_order(num); + int offset; + + spin_lock_irqsave(&msi->bitmap_lock, flags); + + offset = bitmap_find_free_region(msi->fsl_msi_bitmap, + NR_MSI_IRQS, order); + + spin_unlock_irqrestore(&msi->bitmap_lock, flags); + + pr_debug("%s: allocated 0x%x (2^%d) at offset 0x%x\n", + __func__, num, order, offset); + + return offset; +} + +static void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num) +{ + unsigned long flags; + int order = get_count_order(num); + + pr_debug("%s: freeing 0x%x (2^%d) at offset 0x%x\n", + __func__, num, order, offset); + + spin_lock_irqsave(&msi->bitmap_lock, flags); + bitmap_release_region(msi->fsl_msi_bitmap, offset, order); + spin_unlock_irqrestore(&msi->bitmap_lock, flags); +} + +static int fsl_msi_free_dt_hwirqs(struct fsl_msi *msi) +{ + int i; + int len; + const u32 *p; + + bitmap_allocate_region(msi->fsl_msi_bitmap, 0, + get_count_order(NR_MSI_IRQS)); + + p = of_get_property(msi->of_node, "msi-available-ranges", &len); + + if (!p) { + /* No msi-available-ranges property, + * All the 256 MSI interrupts can be used + */ + fsl_msi_free_hwirqs(msi, 0, 0x100); + return 0; + } + + if ((len % (2 * sizeof(u32))) != 0) { + printk(KERN_WARNING "fsl_msi: Malformed msi-available-ranges " + "property on %s\n", msi->of_node->full_name); + return -EINVAL; + } + + /* Format is: ( )+ */ + len /= 2 * sizeof(u32); + for (i = 0; i < len; i++, p += 2) + fsl_msi_free_hwirqs(msi, *p, *(p + 1)); + + return 0; +} + static int fsl_msi_init_allocator(struct fsl_msi *msi_data) { int rc; + int size = BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(u32); - rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS, - msi_data->irqhost->of_node); - if (rc) - return rc; + msi_data->fsl_msi_bitmap = kzalloc(size, GFP_KERNEL); - rc = msi_bitmap_reserve_dt_hwirqs(&msi_data->bitmap); - if (rc < 0) { - msi_bitmap_free(&msi_data->bitmap); - return rc; + if (msi_data->fsl_msi_bitmap == NULL) { + pr_debug("%s: ENOMEM allocating allocator bitmap!\n", + __func__); + return -ENOMEM; } + rc = fsl_msi_free_dt_hwirqs(msi_data); + if (rc) + goto out_free; + return 0; +out_free: + kfree(msi_data->fsl_msi_bitmap); + + msi_data->fsl_msi_bitmap = NULL; + return rc; + } static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) @@ -101,8 +175,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) if (entry->irq == NO_IRQ) continue; set_irq_msi(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_data->bitmap, - virq_to_hw(entry->irq), 1); + fsl_msi_free_hwirqs(msi_data, virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); } @@ -124,14 +197,15 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { - int rc, hwirq; + irq_hw_number_t hwirq; + int rc; unsigned int virq; struct msi_desc *entry; struct msi_msg msg; struct fsl_msi *msi_data = fsl_msi; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); + hwirq = fsl_msi_alloc_hwirqs(msi_data, 1); if (hwirq < 0) { rc = hwirq; pr_debug("%s: fail allocating msi interrupt\n", @@ -142,9 +216,9 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) virq = irq_create_mapping(msi_data->irqhost, hwirq); if (virq == NO_IRQ) { - pr_debug("%s: fail mapping hwirq 0x%x\n", + pr_debug("%s: fail mapping hwirq 0x%lx\n", __func__, hwirq); - msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1); + fsl_msi_free_hwirqs(msi_data, hwirq, 1); rc = -ENOSPC; goto out_free; } @@ -243,11 +317,14 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR, - NR_MSI_IRQS, &fsl_msi_host_ops, 0); + msi->of_node = of_node_get(dev->node); + msi->irqhost = irq_alloc_host(of_node_get(dev->node), + IRQ_HOST_MAP_LINEAR, + NR_MSI_IRQS, &fsl_msi_host_ops, 0); if (msi->irqhost == NULL) { dev_err(&dev->dev, "No memory for MSI irqhost\n"); + of_node_put(dev->node); err = -ENOMEM; goto error_out; } diff --git a/trunk/arch/powerpc/sysdev/fsl_msi.h b/trunk/arch/powerpc/sysdev/fsl_msi.h index 331c7e7025b7..a653468521fa 100644 --- a/trunk/arch/powerpc/sysdev/fsl_msi.h +++ b/trunk/arch/powerpc/sysdev/fsl_msi.h @@ -13,8 +13,6 @@ #ifndef _POWERPC_SYSDEV_FSL_MSI_H #define _POWERPC_SYSDEV_FSL_MSI_H -#include - #define NR_MSI_REG 8 #define IRQS_PER_MSI_REG 32 #define NR_MSI_IRQS (NR_MSI_REG * IRQS_PER_MSI_REG) @@ -24,6 +22,9 @@ #define FSL_PIC_IP_IPIC 0x00000002 struct fsl_msi { + /* Device node of the MSI interrupt*/ + struct device_node *of_node; + struct irq_host *irqhost; unsigned long cascade_irq; @@ -33,7 +34,8 @@ struct fsl_msi { void __iomem *msi_regs; u32 feature; - struct msi_bitmap bitmap; + unsigned long *fsl_msi_bitmap; + spinlock_t bitmap_lock; }; #endif /* _POWERPC_SYSDEV_FSL_MSI_H */ diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.c b/trunk/arch/powerpc/sysdev/fsl_pci.c index 5b264eb4b1f7..61e6d77efa4f 100644 --- a/trunk/arch/powerpc/sysdev/fsl_pci.c +++ b/trunk/arch/powerpc/sysdev/fsl_pci.c @@ -1,7 +1,7 @@ /* - * MPC83xx/85xx/86xx PCI/PCIE support routing. + * MPC85xx/86xx PCI/PCIE support routing. * - * Copyright 2007,2008 Freescale Semiconductor, Inc + * Copyright 2007 Freescale Semiconductor, Inc * * Initial author: Xianghua Xiao * Recode: ZHANG WEI @@ -251,47 +251,20 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header); #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */ -#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) +#if defined(CONFIG_PPC_83xx) int __init mpc83xx_add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; - struct resource rsrc_reg; - struct resource rsrc_cfg; + struct resource rsrc; const int *bus_range; - int primary; + int primary = 1, has_address = 0; + phys_addr_t immr = get_immrbase(); pr_debug("Adding PCI host bridge %s\n", dev->full_name); /* Fetch host bridge registers address */ - if (of_address_to_resource(dev, 0, &rsrc_reg)) { - printk(KERN_WARNING "Can't get pci register base!\n"); - return -ENOMEM; - } - - memset(&rsrc_cfg, 0, sizeof(rsrc_cfg)); - - if (of_address_to_resource(dev, 1, &rsrc_cfg)) { - printk(KERN_WARNING - "No pci config register base in dev tree, " - "using default\n"); - /* - * MPC83xx supports up to two host controllers - * one at 0x8500 has config space registers at 0x8300 - * one at 0x8600 has config space registers at 0x8380 - */ - if ((rsrc_reg.start & 0xfffff) == 0x8500) - rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300; - else if ((rsrc_reg.start & 0xfffff) == 0x8600) - rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380; - } - /* - * Controller at offset 0x8500 is primary - */ - if ((rsrc_reg.start & 0xfffff) == 0x8500) - primary = 1; - else - primary = 0; + has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); @@ -308,11 +281,22 @@ int __init mpc83xx_add_bridge(struct device_node *dev) hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; - setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0); + /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar + * the other at 0x8600, we consider the 0x8500 the primary controller + */ + /* PCI 1 */ + if ((rsrc.start & 0xfffff) == 0x8500) { + setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0); + } + /* PCI 2 */ + if ((rsrc.start & 0xfffff) == 0x8600) { + setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0); + primary = 0; + } - printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " + printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - (unsigned long long)rsrc_reg.start, hose->first_busno, + (unsigned long long)rsrc.start, hose->first_busno, hose->last_busno); pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index 01b884b25696..214388e11807 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -412,6 +412,53 @@ static int __init gfar_of_init(void) arch_initcall(gfar_of_init); + +#ifdef CONFIG_PPC_83xx +static int __init mpc83xx_wdt_init(void) +{ + struct resource r; + struct device_node *np; + struct platform_device *dev; + u32 freq = fsl_get_sys_freq(); + int ret; + + np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); + + if (!np) { + ret = -ENODEV; + goto nodev; + } + + memset(&r, 0, sizeof(r)); + + ret = of_address_to_resource(np, 0, &r); + if (ret) + goto err; + + dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); + goto err; + } + + ret = platform_device_add_data(dev, &freq, sizeof(freq)); + if (ret) + goto unreg; + + of_node_put(np); + return 0; + +unreg: + platform_device_unregister(dev); +err: + of_node_put(np); +nodev: + return ret; +} + +arch_initcall(mpc83xx_wdt_init); +#endif + static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) { if (!phy_type) @@ -720,6 +767,42 @@ void fsl_rstcr_restart(char *cmd) #endif #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) -struct platform_diu_data_ops diu_ops; +struct platform_diu_data_ops diu_ops = { + .diu_size = 1280 * 1024 * 4, /* default one 1280x1024 buffer */ +}; EXPORT_SYMBOL(diu_ops); + +int __init preallocate_diu_videomemory(void) +{ + pr_debug("diu_size=%lu\n", diu_ops.diu_size); + + diu_ops.diu_mem = __alloc_bootmem(diu_ops.diu_size, 8, 0); + if (!diu_ops.diu_mem) { + printk(KERN_ERR "fsl-diu: cannot allocate %lu bytes\n", + diu_ops.diu_size); + return -ENOMEM; + } + + pr_debug("diu_mem=%p\n", diu_ops.diu_mem); + + rh_init(&diu_ops.diu_rh_info, 4096, ARRAY_SIZE(diu_ops.diu_rh_block), + diu_ops.diu_rh_block); + return rh_attach_region(&diu_ops.diu_rh_info, + (unsigned long) diu_ops.diu_mem, + diu_ops.diu_size); +} + +static int __init early_parse_diufb(char *p) +{ + if (!p) + return 1; + + diu_ops.diu_size = _ALIGN_UP(memparse(p, &p), 8); + + pr_debug("diu_size=%lu\n", diu_ops.diu_size); + + return 0; +} +early_param("diufb", early_parse_diufb); + #endif diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.h b/trunk/arch/powerpc/sysdev/fsl_soc.h index 60f7f227327c..024299887352 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.h +++ b/trunk/arch/powerpc/sysdev/fsl_soc.h @@ -20,7 +20,14 @@ extern int fsl_spi_init(struct spi_board_info *board_infos, extern void fsl_rstcr_restart(char *cmd); #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) +#include +#include struct platform_diu_data_ops { + rh_block_t diu_rh_block[16]; + rh_info_t diu_rh_info; + unsigned long diu_size; + void *diu_mem; + unsigned int (*get_pixel_format) (unsigned int bits_per_pixel, int monitor_port); void (*set_gamma_table) (int monitor_port, char *gamma_table_base); @@ -31,6 +38,7 @@ struct platform_diu_data_ops { }; extern struct platform_diu_data_ops diu_ops; +int __init preallocate_diu_videomemory(void); #endif #endif diff --git a/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c b/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c deleted file mode 100644 index 103eace36194..000000000000 --- a/trunk/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * GPIOs on MPC8349/8572/8610 and compatible - * - * Copyright (C) 2008 Peter Korsgaard - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MPC8XXX_GPIO_PINS 32 - -#define GPIO_DIR 0x00 -#define GPIO_ODR 0x04 -#define GPIO_DAT 0x08 -#define GPIO_IER 0x0c -#define GPIO_IMR 0x10 -#define GPIO_ICR 0x14 - -struct mpc8xxx_gpio_chip { - struct of_mm_gpio_chip mm_gc; - spinlock_t lock; - - /* - * shadowed data register to be able to clear/set output pins in - * open drain mode safely - */ - u32 data; -}; - -static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) -{ - return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); -} - -static inline struct mpc8xxx_gpio_chip * -to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm) -{ - return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc); -} - -static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) -{ - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); - - mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); -} - -static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); - - return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio); -} - -static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); - unsigned long flags; - - spin_lock_irqsave(&mpc8xxx_gc->lock, flags); - - if (val) - mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); - else - mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); - - out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); - - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); -} - -static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); - unsigned long flags; - - spin_lock_irqsave(&mpc8xxx_gc->lock, flags); - - clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); - - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); - - return 0; -} - -static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); - unsigned long flags; - - mpc8xxx_gpio_set(gc, gpio, val); - - spin_lock_irqsave(&mpc8xxx_gc->lock, flags); - - setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); - - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); - - return 0; -} - -static void __init mpc8xxx_add_controller(struct device_node *np) -{ - struct mpc8xxx_gpio_chip *mpc8xxx_gc; - struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; - struct gpio_chip *gc; - int ret; - - mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); - if (!mpc8xxx_gc) { - ret = -ENOMEM; - goto err; - } - - spin_lock_init(&mpc8xxx_gc->lock); - - mm_gc = &mpc8xxx_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; - - mm_gc->save_regs = mpc8xxx_gpio_save_regs; - of_gc->gpio_cells = 2; - gc->ngpio = MPC8XXX_GPIO_PINS; - gc->direction_input = mpc8xxx_gpio_dir_in; - gc->direction_output = mpc8xxx_gpio_dir_out; - gc->get = mpc8xxx_gpio_get; - gc->set = mpc8xxx_gpio_set; - - ret = of_mm_gpiochip_add(np, mm_gc); - if (ret) - goto err; - - return; - -err: - pr_err("%s: registration failed with status %d\n", - np->full_name, ret); - kfree(mpc8xxx_gc); - - return; -} - -static int __init mpc8xxx_add_gpiochips(void) -{ - struct device_node *np; - - for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio") - mpc8xxx_add_controller(np); - - for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio") - mpc8xxx_add_controller(np); - - for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio") - mpc8xxx_add_controller(np); - - return 0; -} -arch_initcall(mpc8xxx_add_gpiochips); diff --git a/trunk/arch/powerpc/sysdev/mpic.h b/trunk/arch/powerpc/sysdev/mpic.h index 6209c62a426d..fbf8a266941c 100644 --- a/trunk/arch/powerpc/sysdev/mpic.h +++ b/trunk/arch/powerpc/sysdev/mpic.h @@ -14,6 +14,8 @@ #ifdef CONFIG_PCI_MSI extern void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq); extern int mpic_msi_init_allocator(struct mpic *mpic); +extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num); +extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num); extern int mpic_u3msi_init(struct mpic *mpic); extern int mpic_pasemi_msi_init(struct mpic *mpic); #else diff --git a/trunk/arch/powerpc/sysdev/mpic_msi.c b/trunk/arch/powerpc/sysdev/mpic_msi.c index 1d44eee80fa1..de3e5e8bc324 100644 --- a/trunk/arch/powerpc/sysdev/mpic_msi.c +++ b/trunk/arch/powerpc/sysdev/mpic_msi.c @@ -15,17 +15,59 @@ #include #include #include -#include #include +static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) +{ + pr_debug("mpic: reserving hwirq 0x%lx\n", hwirq); + bitmap_allocate_region(mpic->hwirq_bitmap, hwirq, 0); +} + void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) { + unsigned long flags; + /* The mpic calls this even when there is no allocator setup */ - if (!mpic->msi_bitmap.bitmap) + if (!mpic->hwirq_bitmap) return; - msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq); + spin_lock_irqsave(&mpic->bitmap_lock, flags); + __mpic_msi_reserve_hwirq(mpic, hwirq); + spin_unlock_irqrestore(&mpic->bitmap_lock, flags); +} + +irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num) +{ + unsigned long flags; + int offset, order = get_count_order(num); + + spin_lock_irqsave(&mpic->bitmap_lock, flags); + /* + * This is fast, but stricter than we need. We might want to add + * a fallback routine which does a linear search with no alignment. + */ + offset = bitmap_find_free_region(mpic->hwirq_bitmap, mpic->irq_count, + order); + spin_unlock_irqrestore(&mpic->bitmap_lock, flags); + + pr_debug("mpic: allocated 0x%x (2^%d) at offset 0x%x\n", + num, order, offset); + + return offset; +} + +void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num) +{ + unsigned long flags; + int order = get_count_order(num); + + pr_debug("mpic: freeing 0x%x (2^%d) at offset 0x%x\n", + num, order, offset); + + spin_lock_irqsave(&mpic->bitmap_lock, flags); + bitmap_release_region(mpic->hwirq_bitmap, offset, order); + spin_unlock_irqrestore(&mpic->bitmap_lock, flags); } #ifdef CONFIG_MPIC_U3_HT_IRQS @@ -41,13 +83,13 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) /* Reserve source numbers we know are reserved in the HW */ for (i = 0; i < 8; i++) - msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); + __mpic_msi_reserve_hwirq(mpic, i); for (i = 42; i < 46; i++) - msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); + __mpic_msi_reserve_hwirq(mpic, i); for (i = 100; i < 105; i++) - msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); + __mpic_msi_reserve_hwirq(mpic, i); np = NULL; while ((np = of_find_all_nodes(np))) { @@ -57,7 +99,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) while (of_irq_map_one(np, index++, &oirq) == 0) { ops->xlate(mpic->irqhost, NULL, oirq.specifier, oirq.size, &hwirq, &flags); - msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq); + __mpic_msi_reserve_hwirq(mpic, hwirq); } } @@ -70,25 +112,70 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) } #endif +static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic) +{ + int i, len; + const u32 *p; + + p = of_get_property(mpic->irqhost->of_node, + "msi-available-ranges", &len); + if (!p) { + pr_debug("mpic: no msi-available-ranges property found on %s\n", + mpic->irqhost->of_node->full_name); + return -ENODEV; + } + + if (len % 8 != 0) { + printk(KERN_WARNING "mpic: Malformed msi-available-ranges " + "property on %s\n", mpic->irqhost->of_node->full_name); + return -EINVAL; + } + + bitmap_allocate_region(mpic->hwirq_bitmap, 0, + get_count_order(mpic->irq_count)); + + /* Format is: ( )+ */ + len /= sizeof(u32); + for (i = 0; i < len / 2; i++, p += 2) + mpic_msi_free_hwirqs(mpic, *p, *(p + 1)); + + return 0; +} + int mpic_msi_init_allocator(struct mpic *mpic) { - int rc; + int rc, size; + + BUG_ON(mpic->hwirq_bitmap); + spin_lock_init(&mpic->bitmap_lock); - rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->irq_count, - mpic->irqhost->of_node); - if (rc) - return rc; + size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long); + pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size); - rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap); - if (rc > 0) { + mpic->hwirq_bitmap = alloc_maybe_bootmem(size, GFP_KERNEL); + + if (!mpic->hwirq_bitmap) { + pr_debug("mpic: ENOMEM allocating allocator bitmap!\n"); + return -ENOMEM; + } + + memset(mpic->hwirq_bitmap, 0, size); + + rc = mpic_msi_reserve_dt_hwirqs(mpic); + if (rc) { if (mpic->flags & MPIC_U3_HT_IRQS) rc = mpic_msi_reserve_u3_hwirqs(mpic); - if (rc) { - msi_bitmap_free(&mpic->msi_bitmap); - return rc; - } + if (rc) + goto out_free; } return 0; + + out_free: + if (mem_init_done) + kfree(mpic->hwirq_bitmap); + + mpic->hwirq_bitmap = NULL; + return rc; } diff --git a/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c b/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c index 656cb772b691..68aff6076675 100644 --- a/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/trunk/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "mpic.h" @@ -82,8 +81,8 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) continue; set_irq_msi(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, - virq_to_hw(entry->irq), ALLOC_CHUNK); + mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), + ALLOC_CHUNK); irq_dispose_mapping(entry->irq); } @@ -92,10 +91,11 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { + irq_hw_number_t hwirq; unsigned int virq; struct msi_desc *entry; struct msi_msg msg; - int hwirq; + int ret; pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", pdev, nvec, type); @@ -109,19 +109,17 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) * few MSIs for someone, but restrictions will apply to how the * sources can be changed independently. */ - hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, - ALLOC_CHUNK); - if (hwirq < 0) { + ret = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK); + hwirq = ret; + if (ret < 0) { pr_debug("pasemi_msi: failed allocating hwirq\n"); return hwirq; } virq = irq_create_mapping(msi_mpic->irqhost, hwirq); if (virq == NO_IRQ) { - pr_debug("pasemi_msi: failed mapping hwirq 0x%x\n", - hwirq); - msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, - ALLOC_CHUNK); + pr_debug("pasemi_msi: failed mapping hwirq 0x%lx\n", hwirq); + mpic_msi_free_hwirqs(msi_mpic, hwirq, ALLOC_CHUNK); return -ENOSPC; } @@ -135,8 +133,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) set_irq_chip(virq, &mpic_pasemi_msi_chip); set_irq_type(virq, IRQ_TYPE_EDGE_RISING); - pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%x) " \ - "addr 0x%x\n", virq, hwirq, msg.address_lo); + pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%x\n", + virq, hwirq, msg.address_lo); /* Likewise, the device writes [0...511] into the target * register to generate MSI [512...1023] diff --git a/trunk/arch/powerpc/sysdev/mpic_u3msi.c b/trunk/arch/powerpc/sysdev/mpic_u3msi.c index 0a8f5a9e87c9..6e2f8686fdfc 100644 --- a/trunk/arch/powerpc/sysdev/mpic_u3msi.c +++ b/trunk/arch/powerpc/sysdev/mpic_u3msi.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "mpic.h" @@ -102,8 +101,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) continue; set_irq_msi(entry->irq, NULL); - msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, - virq_to_hw(entry->irq), 1); + mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), 1); irq_dispose_mapping(entry->irq); } @@ -112,27 +110,29 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { + irq_hw_number_t hwirq; unsigned int virq; struct msi_desc *entry; struct msi_msg msg; u64 addr; - int hwirq; + int ret; addr = find_ht_magic_addr(pdev); msg.address_lo = addr & 0xFFFFFFFF; msg.address_hi = addr >> 32; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); - if (hwirq < 0) { + ret = mpic_msi_alloc_hwirqs(msi_mpic, 1); + if (ret < 0) { pr_debug("u3msi: failed allocating hwirq\n"); - return hwirq; + return ret; } + hwirq = ret; virq = irq_create_mapping(msi_mpic->irqhost, hwirq); if (virq == NO_IRQ) { - pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq); - msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1); + pr_debug("u3msi: failed mapping hwirq 0x%lx\n", hwirq); + mpic_msi_free_hwirqs(msi_mpic, hwirq, 1); return -ENOSPC; } @@ -140,8 +140,8 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) set_irq_chip(virq, &mpic_u3msi_chip); set_irq_type(virq, IRQ_TYPE_EDGE_RISING); - pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n", - virq, hwirq, (unsigned long)addr); + pr_debug("u3msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n", + virq, hwirq, addr); msg.data = hwirq; write_msi_msg(virq, &msg); diff --git a/trunk/arch/powerpc/sysdev/msi_bitmap.c b/trunk/arch/powerpc/sysdev/msi_bitmap.c deleted file mode 100644 index f84217b8863a..000000000000 --- a/trunk/arch/powerpc/sysdev/msi_bitmap.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2006-2008, Michael Ellerman, IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the - * License. - * - */ - -#include -#include -#include - -int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num) -{ - unsigned long flags; - int offset, order = get_count_order(num); - - spin_lock_irqsave(&bmp->lock, flags); - /* - * This is fast, but stricter than we need. We might want to add - * a fallback routine which does a linear search with no alignment. - */ - offset = bitmap_find_free_region(bmp->bitmap, bmp->irq_count, order); - spin_unlock_irqrestore(&bmp->lock, flags); - - pr_debug("msi_bitmap: allocated 0x%x (2^%d) at offset 0x%x\n", - num, order, offset); - - return offset; -} - -void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset, - unsigned int num) -{ - unsigned long flags; - int order = get_count_order(num); - - pr_debug("msi_bitmap: freeing 0x%x (2^%d) at offset 0x%x\n", - num, order, offset); - - spin_lock_irqsave(&bmp->lock, flags); - bitmap_release_region(bmp->bitmap, offset, order); - spin_unlock_irqrestore(&bmp->lock, flags); -} - -void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq) -{ - unsigned long flags; - - pr_debug("msi_bitmap: reserving hwirq 0x%x\n", hwirq); - - spin_lock_irqsave(&bmp->lock, flags); - bitmap_allocate_region(bmp->bitmap, hwirq, 0); - spin_unlock_irqrestore(&bmp->lock, flags); -} - -/** - * msi_bitmap_reserve_dt_hwirqs - Reserve irqs specified in the device tree. - * @bmp: pointer to the MSI bitmap. - * - * Looks in the device tree to see if there is a property specifying which - * irqs can be used for MSI. If found those irqs reserved in the device tree - * are reserved in the bitmap. - * - * Returns 0 for success, < 0 if there was an error, and > 0 if no property - * was found in the device tree. - **/ -int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp) -{ - int i, j, len; - const u32 *p; - - if (!bmp->of_node) - return 1; - - p = of_get_property(bmp->of_node, "msi-available-ranges", &len); - if (!p) { - pr_debug("msi_bitmap: no msi-available-ranges property " \ - "found on %s\n", bmp->of_node->full_name); - return 1; - } - - if (len % (2 * sizeof(u32)) != 0) { - printk(KERN_WARNING "msi_bitmap: Malformed msi-available-ranges" - " property on %s\n", bmp->of_node->full_name); - return -EINVAL; - } - - bitmap_allocate_region(bmp->bitmap, 0, get_count_order(bmp->irq_count)); - - spin_lock(&bmp->lock); - - /* Format is: ( )+ */ - len /= 2 * sizeof(u32); - for (i = 0; i < len; i++, p += 2) { - for (j = 0; j < *(p + 1); j++) - bitmap_release_region(bmp->bitmap, *p + j, 0); - } - - spin_unlock(&bmp->lock); - - return 0; -} - -int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count, - struct device_node *of_node) -{ - int size; - - if (!irq_count) - return -EINVAL; - - size = BITS_TO_LONGS(irq_count) * sizeof(long); - pr_debug("msi_bitmap: allocator bitmap size is 0x%x bytes\n", size); - - bmp->bitmap = zalloc_maybe_bootmem(size, GFP_KERNEL); - if (!bmp->bitmap) { - pr_debug("msi_bitmap: ENOMEM allocating allocator bitmap!\n"); - return -ENOMEM; - } - - /* We zalloc'ed the bitmap, so all irqs are free by default */ - spin_lock_init(&bmp->lock); - bmp->of_node = of_node_get(of_node); - bmp->irq_count = irq_count; - - return 0; -} - -void msi_bitmap_free(struct msi_bitmap *bmp) -{ - /* we can't free the bitmap we don't know if it's bootmem etc. */ - of_node_put(bmp->of_node); - bmp->bitmap = NULL; -} - -#ifdef CONFIG_MSI_BITMAP_SELFTEST - -#define check(x) \ - if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__); - -void test_basics(void) -{ - struct msi_bitmap bmp; - int i, size = 512; - - /* Can't allocate a bitmap of 0 irqs */ - check(msi_bitmap_alloc(&bmp, 0, NULL) != 0); - - /* of_node may be NULL */ - check(0 == msi_bitmap_alloc(&bmp, size, NULL)); - - /* Should all be free by default */ - check(0 == bitmap_find_free_region(bmp.bitmap, size, - get_count_order(size))); - bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); - - /* With no node, there's no msi-available-ranges, so expect > 0 */ - check(msi_bitmap_reserve_dt_hwirqs(&bmp) > 0); - - /* Should all still be free */ - check(0 == bitmap_find_free_region(bmp.bitmap, size, - get_count_order(size))); - bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); - - /* Check we can fill it up and then no more */ - for (i = 0; i < size; i++) - check(msi_bitmap_alloc_hwirqs(&bmp, 1) >= 0); - - check(msi_bitmap_alloc_hwirqs(&bmp, 1) < 0); - - /* Should all be allocated */ - check(bitmap_find_free_region(bmp.bitmap, size, 0) < 0); - - /* And if we free one we can then allocate another */ - msi_bitmap_free_hwirqs(&bmp, size / 2, 1); - check(msi_bitmap_alloc_hwirqs(&bmp, 1) == size / 2); - - msi_bitmap_free(&bmp); - - /* Clients may check bitmap == NULL for "not-allocated" */ - check(bmp.bitmap == NULL); - - kfree(bmp.bitmap); -} - -void test_of_node(void) -{ - u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 }; - const char *expected_str = "0-9,20-24,28-39,41-99,220-255"; - char *prop_name = "msi-available-ranges"; - char *node_name = "/fakenode"; - struct device_node of_node; - struct property prop; - struct msi_bitmap bmp; - int size = 256; - DECLARE_BITMAP(expected, size); - - /* There should really be a struct device_node allocator */ - memset(&of_node, 0, sizeof(of_node)); - kref_init(&of_node.kref); - of_node.full_name = node_name; - - check(0 == msi_bitmap_alloc(&bmp, size, &of_node)); - - /* No msi-available-ranges, so expect > 0 */ - check(msi_bitmap_reserve_dt_hwirqs(&bmp) > 0); - - /* Should all still be free */ - check(0 == bitmap_find_free_region(bmp.bitmap, size, - get_count_order(size))); - bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); - - /* Now create a fake msi-available-ranges property */ - - /* There should really .. oh whatever */ - memset(&prop, 0, sizeof(prop)); - prop.name = prop_name; - prop.value = &prop_data; - prop.length = sizeof(prop_data); - - of_node.properties = ∝ - - /* msi-available-ranges, so expect == 0 */ - check(msi_bitmap_reserve_dt_hwirqs(&bmp) == 0); - - /* Check we got the expected result */ - check(0 == bitmap_parselist(expected_str, expected, size)); - check(bitmap_equal(expected, bmp.bitmap, size)); - - msi_bitmap_free(&bmp); - kfree(bmp.bitmap); -} - -int msi_bitmap_selftest(void) -{ - printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n"); - - test_basics(); - test_of_node(); - - return 0; -} -late_initcall(msi_bitmap_selftest); -#endif /* CONFIG_MSI_BITMAP_SELFTEST */ diff --git a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c index 9f6f73d584d6..fb368dfde5d4 100644 --- a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c @@ -30,12 +30,14 @@ #include #include #include -#include #include "ppc4xx_pci.h" static int dma_offset_set; +/* Move that to a useable header */ +extern unsigned long total_memory; + #define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL)) #define U64_TO_U32_HIGH(val) ((u32)((val) >> 32)) @@ -103,8 +105,7 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, /* Default */ res->start = 0; - size = 0x80000000; - res->end = size - 1; + res->end = size = 0x80000000; res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; /* Get dma-ranges property */ @@ -166,13 +167,13 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, */ if (size < total_memory) { printk(KERN_ERR "%s: dma-ranges too small " - "(size=%llx total_memory=%llx)\n", - hose->dn->full_name, size, (u64)total_memory); + "(size=%llx total_memory=%lx)\n", + hose->dn->full_name, size, total_memory); return -ENXIO; } /* Check we are a power of 2 size and that base is a multiple of size*/ - if ((size & (size - 1)) != 0 || + if (!is_power_of_2(size) || (res->start & (size - 1)) != 0) { printk(KERN_ERR "%s: dma-ranges unaligned\n", hose->dn->full_name); @@ -276,16 +277,9 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np) const int *bus_range; int primary = 0; - /* Check if device is enabled */ - if (!of_device_is_available(np)) { - printk(KERN_INFO "%s: Port disabled via device-tree\n", - np->full_name); - return; - } - /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { - printk(KERN_ERR "%s: Can't get PCI config register base !", + printk(KERN_ERR "%s:Can't get PCI config register base !", np->full_name); return; } @@ -816,7 +810,7 @@ static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) switch (port->index) { case 0: mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); - mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130); + mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000136); mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST,0x10000000); @@ -827,10 +821,10 @@ static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) mtdcri(SDR0, PESDR1_460EX_L1CDRCTL, 0x00003230); mtdcri(SDR0, PESDR1_460EX_L2CDRCTL, 0x00003230); mtdcri(SDR0, PESDR1_460EX_L3CDRCTL, 0x00003230); - mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000130); - mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000130); - mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000130); - mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000130); + mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000136); mtdcri(SDR0, PESDR1_460EX_L0CLK, 0x00000006); mtdcri(SDR0, PESDR1_460EX_L1CLK, 0x00000006); mtdcri(SDR0, PESDR1_460EX_L2CLK, 0x00000006); diff --git a/trunk/arch/powerpc/sysdev/qe_lib/Kconfig b/trunk/arch/powerpc/sysdev/qe_lib/Kconfig index 76ffbc48d4b9..1ce546462be5 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/trunk/arch/powerpc/sysdev/qe_lib/Kconfig @@ -24,3 +24,12 @@ config QE_USB bool help QE USB Host Controller support + +config QE_GPIO + bool "QE GPIO support" + depends on QUICC_ENGINE + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Say Y here if you're going to use hardware that connects to the + QE GPIOs. diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index 36313801cd5c..7383781f3e6a 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -219,7 +219,7 @@ static int hypfs_release(struct inode *inode, struct file *filp) enum { opt_uid, opt_gid, opt_err }; -static const match_table_t hypfs_tokens = { +static match_table_t hypfs_tokens = { {opt_uid, "uid=%u"}, {opt_gid, "gid=%u"}, {opt_err, NULL} diff --git a/trunk/arch/s390/include/asm/elf.h b/trunk/arch/s390/include/asm/elf.h index 261785ab5b22..3cad56923815 100644 --- a/trunk/arch/s390/include/asm/elf.h +++ b/trunk/arch/s390/include/asm/elf.h @@ -166,11 +166,13 @@ extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) #ifndef __s390x__ -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) #else /* __s390x__ */ -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY(ex, ibcs2) \ do { \ - if (current->personality != PER_LINUX32) \ + if (ibcs2) \ + set_personality(PER_SVR4); \ + else if (current->personality != PER_LINUX32) \ set_personality(PER_LINUX); \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ set_thread_flag(TIF_31BIT); \ diff --git a/trunk/arch/s390/include/asm/statfs.h b/trunk/arch/s390/include/asm/statfs.h index 06cc70307ece..099a45579190 100644 --- a/trunk/arch/s390/include/asm/statfs.h +++ b/trunk/arch/s390/include/asm/statfs.h @@ -12,16 +12,19 @@ #ifndef __s390x__ #include #else -/* - * We can't use because in 64-bit mode - * we mix ints of different sizes in our struct statfs. - */ #ifndef __KERNEL_STRICT_NAMES + #include + typedef __kernel_fsid_t fsid_t; + #endif +/* + * This is ugly -- we're already 64-bit clean, so just duplicate the + * definitions. + */ struct statfs { int f_type; int f_bsize; diff --git a/trunk/arch/s390/kernel/compat_linux.c b/trunk/arch/s390/kernel/compat_linux.c index 4646382af34f..98e246dc0233 100644 --- a/trunk/arch/s390/kernel/compat_linux.c +++ b/trunk/arch/s390/kernel/compat_linux.c @@ -279,6 +279,22 @@ asmlinkage long sys32_getegid16(void) return high2lowgid(current->egid); } +/* 32-bit timeval and related flotsam. */ + +static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i) +{ + return (!access_ok(VERIFY_READ, o, sizeof(*o)) || + (__get_user(o->tv_sec, &i->tv_sec) || + __get_user(o->tv_usec, &i->tv_usec))); +} + +static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) +{ + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || + (__put_user(i->tv_sec, &o->tv_sec) || + __put_user(i->tv_usec, &o->tv_usec))); +} + /* * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation. * @@ -346,6 +362,41 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned return sys_ftruncate(fd, (high << 32) | low); } +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) +{ + compat_ino_t ino; + int err; + + if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) + return -EOVERFLOW; + + ino = stat->ino; + if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) + return -EOVERFLOW; + + err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); + err |= put_user(stat->ino, &statbuf->st_ino); + err |= put_user(stat->mode, &statbuf->st_mode); + err |= put_user(stat->nlink, &statbuf->st_nlink); + err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid); + err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid); + err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev); + err |= put_user(stat->size, &statbuf->st_size); + err |= put_user(stat->atime.tv_sec, &statbuf->st_atime); + err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); + err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime); + err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); + err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime); + err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); + err |= put_user(stat->blksize, &statbuf->st_blksize); + err |= put_user(stat->blocks, &statbuf->st_blocks); +/* fixme + err |= put_user(0, &statbuf->__unused4[0]); + err |= put_user(0, &statbuf->__unused4[1]); +*/ + return err; +} + asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) { @@ -506,6 +557,57 @@ sys32_delete_module(const char __user *name_user, unsigned int flags) #endif /* CONFIG_MODULES */ +/* Translations due to time_t size differences. Which affects all + sorts of things, like timeval and itimerval. */ + +extern struct timezone sys_tz; + +asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + if (tv) { + struct timeval ktv; + do_gettimeofday(&ktv); + if (put_tv32(tv, &ktv)) + return -EFAULT; + } + if (tz) { + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + return 0; +} + +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) +{ + long usec; + + if (!access_ok(VERIFY_READ, i, sizeof(*i))) + return -EFAULT; + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + +asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +{ + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_ts32(&kts, tv)) + return -EFAULT; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, u32 poshi, u32 poslo) { diff --git a/trunk/arch/s390/kernel/compat_linux.h b/trunk/arch/s390/kernel/compat_linux.h index 836a28842900..05f8516366ab 100644 --- a/trunk/arch/s390/kernel/compat_linux.h +++ b/trunk/arch/s390/kernel/compat_linux.h @@ -202,6 +202,10 @@ long sys32_execve(void); long sys32_init_module(void __user *umod, unsigned long len, const char __user *uargs); long sys32_delete_module(const char __user *name_user, unsigned int flags); +long sys32_gettimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz); +long sys32_settimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz); long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, u32 poshi, u32 poslo); long sys32_pwrite64(unsigned int fd, const char __user *ubuf, diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index fc2c97197a53..ee51ca9e23b5 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -332,17 +332,17 @@ compat_sys_getrusage_wrapper: llgtr %r3,%r3 # struct rusage_emu31 * jg compat_sys_getrusage # branch to system call - .globl compat_sys_gettimeofday_wrapper -compat_sys_gettimeofday_wrapper: + .globl sys32_gettimeofday_wrapper +sys32_gettimeofday_wrapper: llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * - jg compat_sys_gettimeofday # branch to system call + jg sys32_gettimeofday # branch to system call - .globl compat_sys_settimeofday_wrapper -compat_sys_settimeofday_wrapper: + .globl sys32_settimeofday_wrapper +sys32_settimeofday_wrapper: llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * - jg compat_sys_settimeofday # branch to system call + jg sys32_settimeofday # branch to system call .globl sys32_getgroups16_wrapper sys32_getgroups16_wrapper: diff --git a/trunk/arch/s390/kernel/syscalls.S b/trunk/arch/s390/kernel/syscalls.S index 2d61787949d5..3ae303914b42 100644 --- a/trunk/arch/s390/kernel/syscalls.S +++ b/trunk/arch/s390/kernel/syscalls.S @@ -86,8 +86,8 @@ SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper) SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper) /* 75 */ SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper) SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage_wrapper) -SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper) -SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper) +SYSCALL(sys_gettimeofday,sys_gettimeofday,sys32_gettimeofday_wrapper) +SYSCALL(sys_settimeofday,sys_settimeofday,sys32_settimeofday_wrapper) SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper) /* 80 old getgroups16 syscall */ SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */ NI_SYSCALL /* old select syscall */ diff --git a/trunk/arch/sh/include/asm/elf.h b/trunk/arch/sh/include/asm/elf.h index ee02db110f0d..f01449a8d378 100644 --- a/trunk/arch/sh/include/asm/elf.h +++ b/trunk/arch/sh/include/asm/elf.h @@ -189,7 +189,7 @@ do { \ } while (0) #endif -#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT) +#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) struct task_struct; extern int dump_task_regs (struct task_struct *, elf_gregset_t *); extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); diff --git a/trunk/arch/sparc/include/asm/Kbuild b/trunk/arch/sparc/include/asm/Kbuild index 2d2769d766ec..2ba7183bc1f0 100644 --- a/trunk/arch/sparc/include/asm/Kbuild +++ b/trunk/arch/sparc/include/asm/Kbuild @@ -15,6 +15,8 @@ header-y += signal_32.h header-y += signal_64.h header-y += stat_32.h header-y += stat_64.h +header-y += statfs_32.h +header-y += statfs_64.h header-y += unistd_32.h header-y += unistd_64.h diff --git a/trunk/arch/sparc/include/asm/elf_32.h b/trunk/arch/sparc/include/asm/elf_32.h index 381a1b5256d6..b7ab60547827 100644 --- a/trunk/arch/sparc/include/asm/elf_32.h +++ b/trunk/arch/sparc/include/asm/elf_32.h @@ -137,6 +137,6 @@ typedef struct { #define ELF_PLATFORM (NULL) -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) #endif /* !(__ASMSPARC_ELF_H) */ diff --git a/trunk/arch/sparc/include/asm/elf_64.h b/trunk/arch/sparc/include/asm/elf_64.h index 425c2f9be6d5..0818a1308f4e 100644 --- a/trunk/arch/sparc/include/asm/elf_64.h +++ b/trunk/arch/sparc/include/asm/elf_64.h @@ -195,7 +195,7 @@ static inline unsigned int sparc64_elf_hwcap(void) #define ELF_PLATFORM (NULL) -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY(ex, ibcs2) \ do { unsigned long new_flags = current_thread_info()->flags; \ new_flags &= _TIF_32BIT; \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ @@ -208,7 +208,9 @@ do { unsigned long new_flags = current_thread_info()->flags; \ else \ clear_thread_flag(TIF_ABI_PENDING); \ /* flush_thread will update pgd cache */ \ - if (current->personality != PER_LINUX32) \ + if (ibcs2) \ + set_personality(PER_SVR4); \ + else if (current->personality != PER_LINUX32) \ set_personality(PER_LINUX); \ } while (0) diff --git a/trunk/arch/sparc/include/asm/serial.h b/trunk/arch/sparc/include/asm/serial.h deleted file mode 100644 index f90d61c28059..000000000000 --- a/trunk/arch/sparc/include/asm/serial.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SPARC_SERIAL_H -#define __SPARC_SERIAL_H - -#define BASE_BAUD ( 1843200 / 16 ) - -#endif /* __SPARC_SERIAL_H */ diff --git a/trunk/arch/sparc/include/asm/statfs.h b/trunk/arch/sparc/include/asm/statfs.h index 55e607ad461d..5e937a73743d 100644 --- a/trunk/arch/sparc/include/asm/statfs.h +++ b/trunk/arch/sparc/include/asm/statfs.h @@ -1,6 +1,8 @@ #ifndef ___ASM_SPARC_STATFS_H #define ___ASM_SPARC_STATFS_H - -#include - +#if defined(__sparc__) && defined(__arch64__) +#include +#else +#include +#endif #endif diff --git a/trunk/arch/sparc/include/asm/statfs_32.h b/trunk/arch/sparc/include/asm/statfs_32.h new file mode 100644 index 000000000000..304520fa8863 --- /dev/null +++ b/trunk/arch/sparc/include/asm/statfs_32.h @@ -0,0 +1,6 @@ +#ifndef _SPARC_STATFS_H +#define _SPARC_STATFS_H + +#include + +#endif diff --git a/trunk/arch/sparc/include/asm/statfs_64.h b/trunk/arch/sparc/include/asm/statfs_64.h new file mode 100644 index 000000000000..79b3c890a5fa --- /dev/null +++ b/trunk/arch/sparc/include/asm/statfs_64.h @@ -0,0 +1,54 @@ +#ifndef _SPARC64_STATFS_H +#define _SPARC64_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; + +struct statfs64 { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_frsize; + long f_spare[5]; +}; + +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +}; + +#endif diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index 7a6a5e795928..ce3d45db94e9 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index 5fc386d08c47..0c564ba9e709 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/sparc64/kernel/chmc.c b/trunk/arch/sparc64/kernel/chmc.c index 3b9f4d6e14a9..967b04886822 100644 --- a/trunk/arch/sparc64/kernel/chmc.c +++ b/trunk/arch/sparc64/kernel/chmc.c @@ -831,7 +831,7 @@ static int __init us3mc_init(void) if (!us3mc_platform()) return -ENODEV; - __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver)); + __asm__ ("rdpr %%ver, %0" : "=r" (ver)); if ((ver >> 32UL) == __JALAPENO_ID || (ver >> 32UL) == __SERRANO_ID) { mc_type = MC_TYPE_JBUS; diff --git a/trunk/arch/sparc64/kernel/iommu.c b/trunk/arch/sparc64/kernel/iommu.c index 1cc1995531e2..2a37a6ca2a16 100644 --- a/trunk/arch/sparc64/kernel/iommu.c +++ b/trunk/arch/sparc64/kernel/iommu.c @@ -575,7 +575,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, } /* Allocate iommu entries for that segment */ paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s); - npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE); + npages = iommu_num_pages(paddr, slen); entry = iommu_range_alloc(dev, iommu, npages, &handle); /* Handle failure */ @@ -647,8 +647,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, iopte_t *base; vaddr = s->dma_address & IO_PAGE_MASK; - npages = iommu_num_pages(s->dma_address, s->dma_length, - IO_PAGE_SIZE); + npages = iommu_num_pages(s->dma_address, s->dma_length); iommu_range_free(iommu, vaddr, npages); entry = (vaddr - iommu->page_table_map_base) @@ -716,7 +715,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, if (!len) break; - npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE); + npages = iommu_num_pages(dma_handle, len); iommu_range_free(iommu, dma_handle, npages); entry = ((dma_handle - iommu->page_table_map_base) diff --git a/trunk/arch/sparc64/kernel/iommu_common.h b/trunk/arch/sparc64/kernel/iommu_common.h index 591f5879039c..53b19c8231a9 100644 --- a/trunk/arch/sparc64/kernel/iommu_common.h +++ b/trunk/arch/sparc64/kernel/iommu_common.h @@ -35,6 +35,17 @@ #define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG)))) +static inline unsigned long iommu_num_pages(unsigned long vaddr, + unsigned long slen) +{ + unsigned long npages; + + npages = IO_PAGE_ALIGN(vaddr + slen) - (vaddr & IO_PAGE_MASK); + npages >>= IO_PAGE_SHIFT; + + return npages; +} + static inline int is_span_boundary(unsigned long entry, unsigned long shift, unsigned long boundary_size, @@ -42,8 +53,7 @@ static inline int is_span_boundary(unsigned long entry, struct scatterlist *sg) { unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs); - int nr = iommu_num_pages(paddr, outs->dma_length + sg->length, - IO_PAGE_SIZE); + int nr = iommu_num_pages(paddr, outs->dma_length + sg->length); return iommu_is_span_boundary(entry, nr, shift, boundary_size); } diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index 34a1fded3941..e86c73ec167b 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -384,7 +384,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, } /* Allocate iommu entries for that segment */ paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s); - npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE); + npages = iommu_num_pages(paddr, slen); entry = iommu_range_alloc(dev, iommu, npages, &handle); /* Handle failure */ @@ -461,8 +461,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, unsigned long vaddr, npages; vaddr = s->dma_address & IO_PAGE_MASK; - npages = iommu_num_pages(s->dma_address, s->dma_length, - IO_PAGE_SIZE); + npages = iommu_num_pages(s->dma_address, s->dma_length); iommu_range_free(iommu, vaddr, npages); /* XXX demap? XXX */ s->dma_address = DMA_ERROR_CODE; @@ -501,7 +500,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, if (!len) break; - npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE); + npages = iommu_num_pages(dma_handle, len); iommu_range_free(iommu, dma_handle, npages); entry = ((dma_handle - iommu->page_table_map_base) >> IO_PAGE_SHIFT); diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index e5627118e613..2be166c544ca 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -116,9 +115,6 @@ void __cpuinit smp_callin(void) atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - /* inform the notifiers about the new cpu */ - notify_cpu_starting(cpuid); - while (!cpu_isset(cpuid, smp_commenced_mask)) rmb(); diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index e800503879e4..3320c9d0075f 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -58,6 +58,15 @@ #include #include +/* 32-bit timeval and related flotsam. */ + +static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) +{ + return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || + (__put_user(i->tv_sec, &o->tv_sec) | + __put_user(i->tv_usec, &o->tv_usec))); +} + #ifdef CONFIG_SYSVIPC asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth) { @@ -139,6 +148,41 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned return sys_ftruncate(fd, (high << 32) | low); } +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) +{ + compat_ino_t ino; + int err; + + if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || + !old_valid_dev(stat->rdev)) + return -EOVERFLOW; + + ino = stat->ino; + if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) + return -EOVERFLOW; + + err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); + err |= put_user(stat->ino, &statbuf->st_ino); + err |= put_user(stat->mode, &statbuf->st_mode); + err |= put_user(stat->nlink, &statbuf->st_nlink); + err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid); + err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid); + err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev); + err |= put_user(stat->size, &statbuf->st_size); + err |= put_user(stat->atime.tv_sec, &statbuf->st_atime); + err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); + err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime); + err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); + err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime); + err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); + err |= put_user(stat->blksize, &statbuf->st_blksize); + err |= put_user(stat->blocks, &statbuf->st_blocks); + err |= put_user(0, &statbuf->__unused4[0]); + err |= put_user(0, &statbuf->__unused4[1]); + + return err; +} + static int cp_compat_stat64(struct kstat *stat, struct compat_stat64 __user *statbuf) { @@ -478,6 +522,59 @@ asmlinkage long sys32_delete_module(const char __user *name_user) #endif /* CONFIG_MODULES */ +/* Translations due to time_t size differences. Which affects all + sorts of things, like timeval and itimerval. */ + +extern struct timezone sys_tz; + +asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz) +{ + if (tv) { + struct timeval ktv; + do_gettimeofday(&ktv); + if (put_tv32(tv, &ktv)) + return -EFAULT; + } + if (tz) { + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + return 0; +} + +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) +{ + long usec; + + if (!access_ok(VERIFY_READ, i, sizeof(*i))) + return -EFAULT; + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + +asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz) +{ + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_ts32(&kts, tv)) + return -EFAULT; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index b2fa4c163638..5daee4b04dd5 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -41,8 +41,8 @@ sys_call_table32: /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall - .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd -/*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod + .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd +/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys_fchown16, sys_fchmod .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate /*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 diff --git a/trunk/arch/sparc64/kernel/us3_cpufreq.c b/trunk/arch/sparc64/kernel/us3_cpufreq.c index 365b6464e2ce..47e3acafb5be 100644 --- a/trunk/arch/sparc64/kernel/us3_cpufreq.c +++ b/trunk/arch/sparc64/kernel/us3_cpufreq.c @@ -183,6 +183,7 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) table[3].index = 0; table[3].frequency = CPUFREQ_TABLE_END; + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 0; policy->cur = clock_tick; diff --git a/trunk/arch/um/Kconfig.i386 b/trunk/arch/um/Kconfig.i386 index 1f57c113df6d..e09edfa560da 100644 --- a/trunk/arch/um/Kconfig.i386 +++ b/trunk/arch/um/Kconfig.i386 @@ -9,9 +9,8 @@ config UML_X86 default y config X86_32 - bool - default y - select HAVE_AOUT + bool + default y config RWSEM_XCHGADD_ALGORITHM def_bool y @@ -43,3 +42,6 @@ config ARCH_REUSE_HOST_VSYSCALL_AREA config GENERIC_HWEIGHT bool default y + +config ARCH_SUPPORTS_AOUT + def_bool y diff --git a/trunk/arch/um/Kconfig.x86_64 b/trunk/arch/um/Kconfig.x86_64 index 40b3407cfe16..5696e7b374b3 100644 --- a/trunk/arch/um/Kconfig.x86_64 +++ b/trunk/arch/um/Kconfig.x86_64 @@ -37,3 +37,6 @@ config SMP_BROKEN config GENERIC_HWEIGHT bool default y + +config ARCH_SUPPORTS_AOUT + def_bool y diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 14a102e877d6..d741f35d7b3a 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -275,8 +275,6 @@ int line_ioctl(struct tty_struct *tty, struct file * file, case TIOCGLTC: case TIOCSLTC: #endif - /* Note: these are out of date as we now have TCGETS2 etc but this - whole lot should probably go away */ case TCGETS: case TCSETSF: case TCSETSW: diff --git a/trunk/arch/um/kernel/exec.c b/trunk/arch/um/kernel/exec.c index 598711c62c82..f5d7f4569ba7 100644 --- a/trunk/arch/um/kernel/exec.c +++ b/trunk/arch/um/kernel/exec.c @@ -42,11 +42,23 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) PT_REGS_SP(regs) = esp; } +#ifdef CONFIG_TTY_LOG +extern void log_exec(char **argv, void *tty); +#endif + static long execve1(char *file, char __user * __user *argv, char __user *__user *env) { long error; +#ifdef CONFIG_TTY_LOG + struct tty_struct *tty; + mutex_lock(&tty_mutex); + tty = get_current_tty(); + if (tty) + log_exec(argv, tty); + mutex_unlock(&tty_mutex); +#endif error = do_execve(file, argv, env, ¤t->thread.regs); if (error == 0) { task_lock(current); diff --git a/trunk/arch/um/os-Linux/Makefile b/trunk/arch/um/os-Linux/Makefile index d66f0388f091..8a48d6a30064 100644 --- a/trunk/arch/um/os-Linux/Makefile +++ b/trunk/arch/um/os-Linux/Makefile @@ -7,6 +7,9 @@ obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ +obj-$(CONFIG_TTY_LOG) += tty_log.o +user-objs-$(CONFIG_TTY_LOG) += tty_log.o + USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ tty.o tls.o uaccess.o umid.o util.o diff --git a/trunk/arch/um/os-Linux/tty_log.c b/trunk/arch/um/os-Linux/tty_log.c new file mode 100644 index 000000000000..cc648e6fd3a2 --- /dev/null +++ b/trunk/arch/um/os-Linux/tty_log.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and + * geoffrey hing + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include "init.h" +#include "user.h" +#include "os.h" + +#define TTY_LOG_DIR "./" + +/* Set early in boot and then unchanged */ +static char *tty_log_dir = TTY_LOG_DIR; +static int tty_log_fd = -1; + +#define TTY_LOG_OPEN 1 +#define TTY_LOG_CLOSE 2 +#define TTY_LOG_WRITE 3 +#define TTY_LOG_EXEC 4 + +#define TTY_READ 1 +#define TTY_WRITE 2 + +struct tty_log_buf { + int what; + unsigned long tty; + int len; + int direction; + unsigned long sec; + unsigned long usec; +}; + +int open_tty_log(void *tty, void *current_tty) +{ + struct timeval tv; + struct tty_log_buf data; + char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")]; + int fd; + + gettimeofday(&tv, NULL); + if(tty_log_fd != -1){ + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN, + .tty = (unsigned long) tty, + .len = sizeof(current_tty), + .direction = 0, + .sec = tv.tv_sec, + .usec = tv.tv_usec } ); + write(tty_log_fd, &data, sizeof(data)); + write(tty_log_fd, ¤t_tty, data.len); + return tty_log_fd; + } + + sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, + (unsigned int) tv.tv_usec); + + fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))), + 0644); + if(fd < 0){ + printk("open_tty_log : couldn't open '%s', errno = %d\n", + buf, -fd); + } + return fd; +} + +void close_tty_log(int fd, void *tty) +{ + struct tty_log_buf data; + struct timeval tv; + + if(tty_log_fd != -1){ + gettimeofday(&tv, NULL); + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE, + .tty = (unsigned long) tty, + .len = 0, + .direction = 0, + .sec = tv.tv_sec, + .usec = tv.tv_usec } ); + write(tty_log_fd, &data, sizeof(data)); + return; + } + os_close_file(fd); +} + +static int log_chunk(int fd, const char *buf, int len) +{ + int total = 0, try, missed, n; + char chunk[64]; + + while(len > 0){ + try = (len > sizeof(chunk)) ? sizeof(chunk) : len; + missed = copy_from_user_proc(chunk, (char *) buf, try); + try -= missed; + n = write(fd, chunk, try); + if(n != try) { + if(n < 0) + return -errno; + return -EIO; + } + if(missed != 0) + return -EFAULT; + + len -= try; + total += try; + buf += try; + } + + return total; +} + +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) +{ + struct timeval tv; + struct tty_log_buf data; + int direction; + + if(fd == tty_log_fd){ + gettimeofday(&tv, NULL); + direction = is_read ? TTY_READ : TTY_WRITE; + data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE, + .tty = (unsigned long) tty, + .len = len, + .direction = direction, + .sec = tv.tv_sec, + .usec = tv.tv_usec } ); + write(tty_log_fd, &data, sizeof(data)); + } + + return log_chunk(fd, buf, len); +} + +void log_exec(char **argv, void *tty) +{ + struct timeval tv; + struct tty_log_buf data; + char **ptr,*arg; + int len; + + if(tty_log_fd == -1) return; + + gettimeofday(&tv, NULL); + + len = 0; + for(ptr = argv; ; ptr++){ + if(copy_from_user_proc(&arg, ptr, sizeof(arg))) + return; + if(arg == NULL) break; + len += strlen_user_proc(arg); + } + + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC, + .tty = (unsigned long) tty, + .len = len, + .direction = 0, + .sec = tv.tv_sec, + .usec = tv.tv_usec } ); + write(tty_log_fd, &data, sizeof(data)); + + for(ptr = argv; ; ptr++){ + if(copy_from_user_proc(&arg, ptr, sizeof(arg))) + return; + if(arg == NULL) break; + log_chunk(tty_log_fd, arg, strlen_user_proc(arg)); + } +} + +extern void register_tty_logger(int (*opener)(void *, void *), + int (*writer)(int, const char *, int, + void *, int), + void (*closer)(int, void *)); + +static int register_logger(void) +{ + register_tty_logger(open_tty_log, write_tty_log, close_tty_log); + return 0; +} + +__uml_initcall(register_logger); + +static int __init set_tty_log_dir(char *name, int *add) +{ + tty_log_dir = name; + return 0; +} + +__uml_setup("tty_log_dir=", set_tty_log_dir, +"tty_log_dir=\n" +" This is used to specify the directory where the logs of all pty\n" +" data from this UML machine will be written.\n\n" +); + +static int __init set_tty_log_fd(char *name, int *add) +{ + char *end; + + tty_log_fd = strtoul(name, &end, 0); + if((*end != '\0') || (end == name)){ + printf("set_tty_log_fd - strtoul failed on '%s'\n", name); + tty_log_fd = -1; + } + + *add = 0; + return 0; +} + +__uml_setup("tty_log_fd=", set_tty_log_fd, +"tty_log_fd=\n" +" This is used to specify a preconfigured file descriptor to which all\n" +" tty data will be written. Preconfigure the descriptor with something\n" +" like '10>tty_log tty_log_fd=10'.\n\n" +); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 7ccb6e60e60c..fc8351f374fd 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -18,7 +18,6 @@ config X86_64 ### Arch settings config X86 def_bool y - select HAVE_AOUT if X86_32 select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_IDE select HAVE_OPROFILE @@ -39,6 +38,10 @@ config ARCH_DEFCONFIG default "arch/x86/configs/i386_defconfig" if X86_32 default "arch/x86/configs/x86_64_defconfig" if X86_64 + +config GENERIC_LOCKBREAK + def_bool n + config GENERIC_TIME def_bool y @@ -91,7 +94,7 @@ config GENERIC_HWEIGHT def_bool y config GENERIC_GPIO - bool + def_bool n config ARCH_MAY_HAVE_PC_FDC def_bool y @@ -102,6 +105,12 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM def_bool X86_XADD +config ARCH_HAS_ILOG2_U32 + def_bool n + +config ARCH_HAS_ILOG2_U64 + def_bool n + config ARCH_HAS_CPU_IDLE_WAIT def_bool y @@ -143,6 +152,9 @@ config AUDIT_ARCH bool default X86_64 +config ARCH_SUPPORTS_AOUT + def_bool y + config ARCH_SUPPORTS_OPTIMIZED_INLINING def_bool y @@ -748,8 +760,9 @@ config I8K Say N otherwise. config X86_REBOOTFIXUPS - bool "Enable X86 board specific fixups for reboot" - depends on X86_32 + def_bool n + prompt "Enable X86 board specific fixups for reboot" + depends on X86_32 && X86 ---help--- This enables chipset and/or board specific fixups to be done in order to get reboot to work correctly. This is only needed on @@ -933,7 +946,8 @@ config HIGHMEM depends on X86_32 && (HIGHMEM64G || HIGHMEM4G) config X86_PAE - bool "PAE (Physical Address Extension) Support" + def_bool n + prompt "PAE (Physical Address Extension) Support" depends on X86_32 && !HIGHMEM4G select RESOURCES_64BIT help @@ -1226,7 +1240,8 @@ config X86_PAT If unsure, say Y. config EFI - bool "EFI runtime service support" + def_bool n + prompt "EFI runtime service support" depends on ACPI ---help--- This enables the kernel to use EFI runtime services that are @@ -1870,7 +1885,7 @@ config IA32_EMULATION config IA32_AOUT tristate "IA32 a.out support" - depends on IA32_EMULATION + depends on IA32_EMULATION && ARCH_SUPPORTS_AOUT help Support old a.out binaries in the 32bit emulation. diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index 0b7c4a3f0651..c5f101360520 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -38,7 +38,8 @@ config M386 - "Crusoe" for the Transmeta Crusoe series. - "Efficeon" for the Transmeta Efficeon series. - "Winchip-C6" for original IDT Winchip. - - "Winchip-2" for IDT Winchips with 3dNow! capabilities. + - "Winchip-2" for IDT Winchip 2. + - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). - "Geode GX/LX" For AMD Geode GX and LX processors. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. @@ -193,11 +194,19 @@ config MWINCHIPC6 treat this chip as a 586TSC with some extended instructions and alignment requirements. +config MWINCHIP2 + bool "Winchip-2" + depends on X86_32 + help + Select this for an IDT Winchip-2. Linux and GCC + treat this chip as a 586TSC with some extended instructions + and alignment requirements. + config MWINCHIP3D - bool "Winchip-2/Winchip-2A/Winchip-3" + bool "Winchip-2A/Winchip-3" depends on X86_32 help - Select this for an IDT Winchip-2, 2A or 3. Linux and GCC + Select this for an IDT Winchip-2A or 3. Linux and GCC treat this chip as a 586TSC with some extended instructions and alignment requirements. Also enable out of order memory stores for this CPU, which can increase performance of some @@ -309,7 +318,7 @@ config X86_L1_CACHE_SHIFT int default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 - default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX + default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 config X86_XADD @@ -351,7 +360,7 @@ config X86_POPAD_OK config X86_ALIGNMENT_16 def_bool y - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 config X86_INTEL_USERCOPY def_bool y @@ -359,7 +368,7 @@ config X86_INTEL_USERCOPY config X86_USE_PPRO_CHECKSUM def_bool y - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 config X86_USE_3DNOW def_bool y @@ -367,7 +376,7 @@ config X86_USE_3DNOW config X86_OOSTORE def_bool y - depends on (MWINCHIP3D || MWINCHIPC6) && MTRR + depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR # # P6_NOPs are a relatively minor optimization that require a family >= @@ -387,7 +396,7 @@ config X86_P6_NOP config X86_TSC def_bool y - depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 + depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 config X86_CMPXCHG64 def_bool y @@ -397,7 +406,7 @@ config X86_CMPXCHG64 # generates cmov. config X86_CMOV def_bool y - depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64) + depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64) config X86_MINIMUM_CPU_FAMILY int @@ -408,7 +417,7 @@ config X86_MINIMUM_CPU_FAMILY config X86_DEBUGCTLMSR def_bool y - depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) + depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) menuconfig PROCESSOR_SELECT bool "Supported processor vendors" if EMBEDDED diff --git a/trunk/arch/x86/Makefile_32.cpu b/trunk/arch/x86/Makefile_32.cpu index 80177ec052f0..b72b4f753113 100644 --- a/trunk/arch/x86/Makefile_32.cpu +++ b/trunk/arch/x86/Makefile_32.cpu @@ -28,6 +28,7 @@ cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon) cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586) +cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) diff --git a/trunk/arch/x86/boot/video-vesa.c b/trunk/arch/x86/boot/video-vesa.c index 99b3079dc6ab..1e6fe0214c85 100644 --- a/trunk/arch/x86/boot/video-vesa.c +++ b/trunk/arch/x86/boot/video-vesa.c @@ -88,11 +88,14 @@ static int vesa_probe(void) (vminfo.memory_layout == 4 || vminfo.memory_layout == 6) && vminfo.memory_planes == 1) { -#ifdef CONFIG_FB_BOOT_VESA_SUPPORT +#ifdef CONFIG_FB /* Graphics mode, color, linear frame buffer supported. Only register the mode if if framebuffer is configured, however, - otherwise the user will be left without a screen. */ + otherwise the user will be left without a screen. + We don't require CONFIG_FB_VESA, however, since + some of the other framebuffer drivers can use + this mode-setting, too. */ mi = GET_HEAP(struct mode_info, 1); mi->mode = mode + VIDEO_FIRST_VESA; mi->depth = vminfo.bpp; @@ -130,12 +133,10 @@ static int vesa_set_mode(struct mode_info *mode) if ((vminfo.mode_attr & 0x15) == 0x05) { /* It's a supported text mode */ is_graphic = 0; -#ifdef CONFIG_FB_BOOT_VESA_SUPPORT } else if ((vminfo.mode_attr & 0x99) == 0x99) { /* It's a graphics mode with linear frame buffer */ is_graphic = 1; vesa_mode |= 0x4000; /* Request linear frame buffer */ -#endif } else { return -1; /* Invalid mode */ } diff --git a/trunk/arch/x86/configs/i386_defconfig b/trunk/arch/x86/configs/i386_defconfig index 52d0359719d7..ca226ca31288 100644 --- a/trunk/arch/x86/configs/i386_defconfig +++ b/trunk/arch/x86/configs/i386_defconfig @@ -213,6 +213,7 @@ CONFIG_M686=y # CONFIG_MCRUSOE is not set # CONFIG_MEFFICEON is not set # CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set # CONFIG_MWINCHIP3D is not set # CONFIG_MGEODEGX1 is not set # CONFIG_MGEODE_LX is not set diff --git a/trunk/arch/x86/configs/x86_64_defconfig b/trunk/arch/x86/configs/x86_64_defconfig index f0a03d7a7d63..2c4b1c771e28 100644 --- a/trunk/arch/x86/configs/x86_64_defconfig +++ b/trunk/arch/x86/configs/x86_64_defconfig @@ -210,6 +210,7 @@ CONFIG_X86_PC=y # CONFIG_MCRUSOE is not set # CONFIG_MEFFICEON is not set # CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set # CONFIG_MWINCHIP3D is not set # CONFIG_MGEODEGX1 is not set # CONFIG_MGEODE_LX is not set diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index 256b00b61892..ffc1bb4fed7d 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -39,11 +39,11 @@ .endm /* clobbers %eax */ - .macro CLEAR_RREGS _r9=rax + .macro CLEAR_RREGS xorl %eax,%eax movq %rax,R11(%rsp) movq %rax,R10(%rsp) - movq %\_r9,R9(%rsp) + movq %rax,R9(%rsp) movq %rax,R8(%rsp) .endm @@ -52,10 +52,11 @@ * We don't reload %eax because syscall_trace_enter() returned * the value it wants us to use in the table lookup. */ - .macro LOAD_ARGS32 offset, _r9=0 - .if \_r9 + .macro LOAD_ARGS32 offset + movl \offset(%rsp),%r11d + movl \offset+8(%rsp),%r10d movl \offset+16(%rsp),%r9d - .endif + movl \offset+24(%rsp),%r8d movl \offset+40(%rsp),%ecx movl \offset+48(%rsp),%edx movl \offset+56(%rsp),%esi @@ -144,7 +145,7 @@ ENTRY(ia32_sysenter_target) SAVE_ARGS 0,0,1 /* no need to do an access_ok check here because rbp has been 32bit zero extended */ -1: movl (%rbp),%ebp +1: movl (%rbp),%r9d .section __ex_table,"a" .quad 1b,ia32_badarg .previous @@ -156,7 +157,7 @@ ENTRY(ia32_sysenter_target) cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys sysenter_do_call: - IA32_ARG_FIXUP + IA32_ARG_FIXUP 1 sysenter_dispatch: call *ia32_sys_call_table(,%rax,8) movq %rax,RAX-ARGOFFSET(%rsp) @@ -233,17 +234,20 @@ sysexit_audit: #endif sysenter_tracesys: + xchgl %r9d,%ebp #ifdef CONFIG_AUDITSYSCALL testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) jz sysenter_auditsys #endif SAVE_REST CLEAR_RREGS + movq %r9,R9(%rsp) movq $-ENOSYS,RAX(%rsp)/* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST + xchgl %ebp,%r9d cmpl $(IA32_NR_syscalls-1),%eax ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ jmp sysenter_do_call @@ -310,9 +314,9 @@ ENTRY(ia32_cstar_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz cstar_tracesys +cstar_do_call: cmpl $IA32_NR_syscalls-1,%eax ja ia32_badsys -cstar_do_call: IA32_ARG_FIXUP 1 cstar_dispatch: call *ia32_sys_call_table(,%rax,8) @@ -353,13 +357,15 @@ cstar_tracesys: #endif xchgl %r9d,%ebp SAVE_REST - CLEAR_RREGS r9 + CLEAR_RREGS + movq %r9,R9(%rsp) movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST xchgl %ebp,%r9d + movl RSP-ARGOFFSET(%rsp), %r8d cmpl $(IA32_NR_syscalls-1),%eax ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ jmp cstar_do_call @@ -571,8 +577,8 @@ ia32_sys_call_table: .quad compat_sys_setrlimit /* 75 */ .quad compat_sys_old_getrlimit /* old_getrlimit */ .quad compat_sys_getrusage - .quad compat_sys_gettimeofday - .quad compat_sys_settimeofday + .quad sys32_gettimeofday + .quad sys32_settimeofday .quad sys_getgroups16 /* 80 */ .quad sys_setgroups16 .quad sys32_old_select diff --git a/trunk/arch/x86/ia32/sys_ia32.c b/trunk/arch/x86/ia32/sys_ia32.c index 2e09dcd3c0a6..beda4232ce69 100644 --- a/trunk/arch/x86/ia32/sys_ia32.c +++ b/trunk/arch/x86/ia32/sys_ia32.c @@ -49,6 +49,41 @@ #define AA(__x) ((unsigned long)(__x)) +int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) +{ + compat_ino_t ino; + + typeof(ubuf->st_uid) uid = 0; + typeof(ubuf->st_gid) gid = 0; + SET_UID(uid, kbuf->uid); + SET_GID(gid, kbuf->gid); + if (!old_valid_dev(kbuf->dev) || !old_valid_dev(kbuf->rdev)) + return -EOVERFLOW; + if (kbuf->size >= 0x7fffffff) + return -EOVERFLOW; + ino = kbuf->ino; + if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) + return -EOVERFLOW; + if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || + __put_user(old_encode_dev(kbuf->dev), &ubuf->st_dev) || + __put_user(ino, &ubuf->st_ino) || + __put_user(kbuf->mode, &ubuf->st_mode) || + __put_user(kbuf->nlink, &ubuf->st_nlink) || + __put_user(uid, &ubuf->st_uid) || + __put_user(gid, &ubuf->st_gid) || + __put_user(old_encode_dev(kbuf->rdev), &ubuf->st_rdev) || + __put_user(kbuf->size, &ubuf->st_size) || + __put_user(kbuf->atime.tv_sec, &ubuf->st_atime) || + __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) || + __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime) || + __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) || + __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime) || + __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) || + __put_user(kbuf->blksize, &ubuf->st_blksize) || + __put_user(kbuf->blocks, &ubuf->st_blocks)) + return -EFAULT; + return 0; +} asmlinkage long sys32_truncate64(char __user *filename, unsigned long offset_low, @@ -367,11 +402,75 @@ asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, return 0; } +static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i) +{ + int err = -EFAULT; + + if (access_ok(VERIFY_READ, i, sizeof(*i))) { + err = __get_user(o->tv_sec, &i->tv_sec); + err |= __get_user(o->tv_usec, &i->tv_usec); + } + return err; +} + +static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) +{ + int err = -EFAULT; + + if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { + err = __put_user(i->tv_sec, &o->tv_sec); + err |= __put_user(i->tv_usec, &o->tv_usec); + } + return err; +} + asmlinkage long sys32_alarm(unsigned int seconds) { return alarm_setitimer(seconds); } +/* + * Translations due to time_t size differences. Which affects all + * sorts of things, like timeval and itimerval. + */ +asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz) +{ + if (tv) { + struct timeval ktv; + + do_gettimeofday(&ktv); + if (put_tv32(tv, &ktv)) + return -EFAULT; + } + if (tz) { + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) + return -EFAULT; + } + return 0; +} + +asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz) +{ + struct timeval ktv; + struct timespec kts; + struct timezone ktz; + + if (tv) { + if (get_tv32(&ktv, tv)) + return -EFAULT; + kts.tv_sec = ktv.tv_sec; + kts.tv_nsec = ktv.tv_usec * NSEC_PER_USEC; + } + if (tz) { + if (copy_from_user(&ktz, tz, sizeof(ktz))) + return -EFAULT; + } + + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); +} + struct sel_arg_struct { unsigned int n; unsigned int inp; diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile index 0d41f0343dc0..5098585f87ce 100644 --- a/trunk/arch/x86/kernel/Makefile +++ b/trunk/arch/x86/kernel/Makefile @@ -23,7 +23,7 @@ CFLAGS_hpet.o := $(nostackp) CFLAGS_tsc.o := $(nostackp) obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o -obj-y += traps.o irq_$(BITS).o dumpstack_$(BITS).o +obj-y += traps_$(BITS).o irq_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o obj-$(CONFIG_X86_VISWS) += visws_quirks.o diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c index a84ac7b570e6..fb04e49776ba 100644 --- a/trunk/arch/x86/kernel/alternative.c +++ b/trunk/arch/x86/kernel/alternative.c @@ -444,7 +444,7 @@ void __init alternative_instructions(void) _text, _etext); /* Only switch to UP mode if we don't immediately boot others */ - if (num_present_cpus() == 1 || setup_max_cpus <= 1) + if (num_possible_cpus() == 1 || setup_max_cpus <= 1) alternatives_smp_switch(0); } #endif diff --git a/trunk/arch/x86/kernel/amd_iommu.c b/trunk/arch/x86/kernel/amd_iommu.c index a8fd9ebdc8e2..34e4d112b1ef 100644 --- a/trunk/arch/x86/kernel/amd_iommu.c +++ b/trunk/arch/x86/kernel/amd_iommu.c @@ -295,7 +295,7 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid, u64 address, size_t size) { int s = 0; - unsigned pages = iommu_num_pages(address, size, PAGE_SIZE); + unsigned pages = iommu_num_pages(address, size); address &= PAGE_MASK; @@ -680,8 +680,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, iommu->exclusion_start < dma_dom->aperture_size) { unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; int pages = iommu_num_pages(iommu->exclusion_start, - iommu->exclusion_length, - PAGE_SIZE); + iommu->exclusion_length); dma_ops_reserve_addresses(dma_dom, startpage, pages); } @@ -936,7 +935,7 @@ static dma_addr_t __map_single(struct device *dev, unsigned long align_mask = 0; int i; - pages = iommu_num_pages(paddr, size, PAGE_SIZE); + pages = iommu_num_pages(paddr, size); paddr &= PAGE_MASK; if (align) @@ -981,7 +980,7 @@ static void __unmap_single(struct amd_iommu *iommu, if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size)) return; - pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); + pages = iommu_num_pages(dma_addr, size); dma_addr &= PAGE_MASK; start = dma_addr; diff --git a/trunk/arch/x86/kernel/apic_32.c b/trunk/arch/x86/kernel/apic_32.c index 21c831d96af3..a91c57cb666a 100644 --- a/trunk/arch/x86/kernel/apic_32.c +++ b/trunk/arch/x86/kernel/apic_32.c @@ -295,9 +295,6 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) * * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and * MCE interrupts are supported. Thus MCE offset must be set to 0. - * - * If mask=1, the LVT entry does not generate interrupts while mask=0 - * enables the vector. See also the BKDGs. */ #define APIC_EILVT_LVTOFF_MCE 0 @@ -322,7 +319,6 @@ u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask) setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); return APIC_EILVT_LVTOFF_IBS; } -EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs); /* * Program the next event, relative to now diff --git a/trunk/arch/x86/kernel/apic_64.c b/trunk/arch/x86/kernel/apic_64.c index 94ddb69ae15e..53898b65a6ae 100644 --- a/trunk/arch/x86/kernel/apic_64.c +++ b/trunk/arch/x86/kernel/apic_64.c @@ -307,9 +307,6 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) * * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and * MCE interrupts are supported. Thus MCE offset must be set to 0. - * - * If mask=1, the LVT entry does not generate interrupts while mask=0 - * enables the vector. See also the BKDGs. */ #define APIC_EILVT_LVTOFF_MCE 0 @@ -334,7 +331,6 @@ u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask) setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); return APIC_EILVT_LVTOFF_IBS; } -EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs); /* * Program the next event, relative to now diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index 25581dcb280e..fb789dd9e691 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -124,25 +124,18 @@ static inline int flag_is_changeable_p(u32 flag) { u32 f1, f2; - /* - * Cyrix and IDT cpus allow disabling of CPUID - * so the code below may return different results - * when it is executed before and after enabling - * the CPUID. Add "volatile" to not allow gcc to - * optimize the subsequent calls to this function. - */ - asm volatile ("pushfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "movl %0,%1\n\t" - "xorl %2,%0\n\t" - "pushl %0\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "popfl\n\t" - : "=&r" (f1), "=&r" (f2) - : "ir" (flag)); + asm("pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl %2,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl\n\t" + : "=&r" (f1), "=&r" (f2) + : "ir" (flag)); return ((f1^f2) & flag) != 0; } @@ -726,24 +719,12 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #endif } -#ifdef CONFIG_X86_64 -static void vgetcpu_set_mode(void) -{ - if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) - vgetcpu_mode = VGETCPU_RDTSCP; - else - vgetcpu_mode = VGETCPU_LSL; -} -#endif - void __init identify_boot_cpu(void) { identify_cpu(&boot_cpu_data); #ifdef CONFIG_X86_32 sysenter_setup(); enable_sep_cpu(); -#else - vgetcpu_set_mode(); #endif } @@ -816,7 +797,7 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) else if (c->cpuid_level >= 0) vendor = c->x86_vendor_id; - if (vendor && !strstr(c->x86_model_id, vendor)) + if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor))) printk(KERN_CONT "%s ", vendor); if (c->x86_model_id[0]) diff --git a/trunk/arch/x86/kernel/cpuid.c b/trunk/arch/x86/kernel/cpuid.c index 72cefd1e649b..6a44d6465991 100644 --- a/trunk/arch/x86/kernel/cpuid.c +++ b/trunk/arch/x86/kernel/cpuid.c @@ -147,8 +147,8 @@ static __cpuinit int cpuid_device_create(int cpu) { struct device *dev; - dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL, - "cpu%d", cpu); + dev = device_create_drvdata(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), + NULL, "cpu%d", cpu); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } diff --git a/trunk/arch/x86/kernel/doublefault_32.c b/trunk/arch/x86/kernel/doublefault_32.c index b4f14c6c09d9..395acb12b0d1 100644 --- a/trunk/arch/x86/kernel/doublefault_32.c +++ b/trunk/arch/x86/kernel/doublefault_32.c @@ -66,6 +66,6 @@ struct tss_struct doublefault_tss __cacheline_aligned = { .ds = __USER_DS, .fs = __KERNEL_PERCPU, - .__cr3 = __pa_nodebug(swapper_pg_dir), + .__cr3 = __phys_addr_const((unsigned long)swapper_pg_dir) } }; diff --git a/trunk/arch/x86/kernel/dumpstack_32.c b/trunk/arch/x86/kernel/dumpstack_32.c deleted file mode 100644 index 1a78180f08d3..000000000000 --- a/trunk/arch/x86/kernel/dumpstack_32.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define STACKSLOTS_PER_LINE 8 -#define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :) - -int panic_on_unrecovered_nmi; -int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; -static unsigned int code_bytes = 64; -static int die_counter; - -void printk_address(unsigned long address, int reliable) -{ - printk(" [<%p>] %s%pS\n", (void *) address, - reliable ? "" : "? ", (void *) address); -} - -static inline int valid_stack_ptr(struct thread_info *tinfo, - void *p, unsigned int size, void *end) -{ - void *t = tinfo; - if (end) { - if (p < end && p >= (end-THREAD_SIZE)) - return 1; - else - return 0; - } - return p > t && p < t + THREAD_SIZE - size; -} - -/* The form of the top of the frame on the stack */ -struct stack_frame { - struct stack_frame *next_frame; - unsigned long return_address; -}; - -static inline unsigned long -print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data, - unsigned long *end) -{ - struct stack_frame *frame = (struct stack_frame *)bp; - - while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) { - unsigned long addr; - - addr = *stack; - if (__kernel_text_address(addr)) { - if ((unsigned long) stack == bp + sizeof(long)) { - ops->address(data, addr, 1); - frame = frame->next_frame; - bp = (unsigned long) frame; - } else { - ops->address(data, addr, bp == 0); - } - } - stack++; - } - return bp; -} - -void dump_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) -{ - if (!task) - task = current; - - if (!stack) { - unsigned long dummy; - stack = &dummy; - if (task && task != current) - stack = (unsigned long *)task->thread.sp; - } - -#ifdef CONFIG_FRAME_POINTER - if (!bp) { - if (task == current) { - /* Grab bp right from our regs */ - get_bp(bp); - } else { - /* bp is the last reg pushed by switch_to */ - bp = *(unsigned long *) task->thread.sp; - } - } -#endif - - for (;;) { - struct thread_info *context; - - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - bp = print_context_stack(context, stack, bp, ops, data, NULL); - - stack = (unsigned long *)context->previous_esp; - if (!stack) - break; - if (ops->stack(data, "IRQ") < 0) - break; - touch_nmi_watchdog(); - } -} -EXPORT_SYMBOL(dump_trace); - -static void -print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) -{ - printk(data); - print_symbol(msg, symbol); - printk("\n"); -} - -static void print_trace_warning(void *data, char *msg) -{ - printk("%s%s\n", (char *)data, msg); -} - -static int print_trace_stack(void *data, char *name) -{ - printk("%s <%s> ", (char *)data, name); - return 0; -} - -/* - * Print one address/symbol entries per line. - */ -static void print_trace_address(void *data, unsigned long addr, int reliable) -{ - touch_nmi_watchdog(); - printk(data); - printk_address(addr, reliable); -} - -static const struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, -}; - -static void -show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp, char *log_lvl) -{ - printk("%sCall Trace:\n", log_lvl); - dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); -} - -void show_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp) -{ - show_trace_log_lvl(task, regs, stack, bp, ""); -} - -static void -show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long *sp, unsigned long bp, char *log_lvl) -{ - unsigned long *stack; - int i; - - if (sp == NULL) { - if (task) - sp = (unsigned long *)task->thread.sp; - else - sp = (unsigned long *)&sp; - } - - stack = sp; - for (i = 0; i < kstack_depth_to_print; i++) { - if (kstack_end(stack)) - break; - if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - printk("\n%s", log_lvl); - printk(" %08lx", *stack++); - touch_nmi_watchdog(); - } - printk("\n"); - show_trace_log_lvl(task, regs, sp, bp, log_lvl); -} - -void show_stack(struct task_struct *task, unsigned long *sp) -{ - show_stack_log_lvl(task, NULL, sp, 0, ""); -} - -/* - * The architecture-independent dump_stack generator - */ -void dump_stack(void) -{ - unsigned long bp = 0; - unsigned long stack; - -#ifdef CONFIG_FRAME_POINTER - if (!bp) - get_bp(bp); -#endif - - printk("Pid: %d, comm: %.20s %s %s %.*s\n", - current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - show_trace(NULL, NULL, &stack, bp); -} - -EXPORT_SYMBOL(dump_stack); - -void show_registers(struct pt_regs *regs) -{ - int i; - - print_modules(); - __show_regs(regs, 0); - - printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", - TASK_COMM_LEN, current->comm, task_pid_nr(current), - current_thread_info(), current, task_thread_info(current)); - /* - * When in-kernel, we also print out the stack and code at the - * time of the fault.. - */ - if (!user_mode_vm(regs)) { - unsigned int code_prologue = code_bytes * 43 / 64; - unsigned int code_len = code_bytes; - unsigned char c; - u8 *ip; - - printk(KERN_EMERG "Stack:\n"); - show_stack_log_lvl(NULL, regs, ®s->sp, - 0, KERN_EMERG); - - printk(KERN_EMERG "Code: "); - - ip = (u8 *)regs->ip - code_prologue; - if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - /* try starting at IP */ - ip = (u8 *)regs->ip; - code_len = code_len - code_prologue + 1; - } - for (i = 0; i < code_len; i++, ip++) { - if (ip < (u8 *)PAGE_OFFSET || - probe_kernel_address(ip, c)) { - printk(" Bad EIP value."); - break; - } - if (ip == (u8 *)regs->ip) - printk("<%02x> ", c); - else - printk("%02x ", c); - } - } - printk("\n"); -} - -int is_valid_bugaddr(unsigned long ip) -{ - unsigned short ud2; - - if (ip < PAGE_OFFSET) - return 0; - if (probe_kernel_address((unsigned short *)ip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} - -static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; -static int die_owner = -1; -static unsigned int die_nest_count; - -unsigned __kprobes long oops_begin(void) -{ - unsigned long flags; - - oops_enter(); - - if (die_owner != raw_smp_processor_id()) { - console_verbose(); - raw_local_irq_save(flags); - __raw_spin_lock(&die_lock); - die_owner = smp_processor_id(); - die_nest_count = 0; - bust_spinlocks(1); - } else { - raw_local_irq_save(flags); - } - die_nest_count++; - return flags; -} - -void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) -{ - bust_spinlocks(0); - die_owner = -1; - add_taint(TAINT_DIE); - __raw_spin_unlock(&die_lock); - raw_local_irq_restore(flags); - - if (!regs) - return; - - if (kexec_should_crash(current)) - crash_kexec(regs); - if (in_interrupt()) - panic("Fatal exception in interrupt"); - if (panic_on_oops) - panic("Fatal exception"); - oops_exit(); - do_exit(signr); -} - -int __kprobes __die(const char *str, struct pt_regs *regs, long err) -{ - unsigned short ss; - unsigned long sp; - - printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); -#endif -#ifdef CONFIG_SMP - printk("SMP "); -#endif -#ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC"); -#endif - printk("\n"); - sysfs_printk_last_file(); - if (notify_die(DIE_OOPS, str, regs, err, - current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) - return 1; - - show_registers(regs); - /* Executive summary in case the oops scrolled away */ - sp = (unsigned long) (®s->sp); - savesegment(ss, ss); - if (user_mode(regs)) { - sp = regs->sp; - ss = regs->ss & 0xffff; - } - printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); - print_symbol("%s", regs->ip); - printk(" SS:ESP %04x:%08lx\n", ss, sp); - return 0; -} - -/* - * This is gone through when something in the kernel has done something bad - * and is about to be terminated: - */ -void die(const char *str, struct pt_regs *regs, long err) -{ - unsigned long flags = oops_begin(); - - if (die_nest_count < 3) { - report_bug(regs->ip, regs); - - if (__die(str, regs, err)) - regs = NULL; - } else { - printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); - } - - oops_end(flags, regs, SIGSEGV); -} - -static DEFINE_SPINLOCK(nmi_print_lock); - -void notrace __kprobes -die_nmi(char *str, struct pt_regs *regs, int do_panic) -{ - if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP) - return; - - spin_lock(&nmi_print_lock); - /* - * We are in trouble anyway, lets at least try - * to get a message out: - */ - bust_spinlocks(1); - printk(KERN_EMERG "%s", str); - printk(" on CPU%d, ip %08lx, registers:\n", - smp_processor_id(), regs->ip); - show_registers(regs); - if (do_panic) - panic("Non maskable interrupt"); - console_silent(); - spin_unlock(&nmi_print_lock); - bust_spinlocks(0); - - /* - * If we are in kernel we are probably nested up pretty bad - * and might aswell get out now while we still can: - */ - if (!user_mode_vm(regs)) { - current->thread.trap_no = 2; - crash_kexec(regs); - } - - do_exit(SIGSEGV); -} - -static int __init oops_setup(char *s) -{ - if (!s) - return -EINVAL; - if (!strcmp(s, "panic")) - panic_on_oops = 1; - return 0; -} -early_param("oops", oops_setup); - -static int __init kstack_setup(char *s) -{ - if (!s) - return -EINVAL; - kstack_depth_to_print = simple_strtoul(s, NULL, 0); - return 0; -} -early_param("kstack", kstack_setup); - -static int __init code_bytes_setup(char *s) -{ - code_bytes = simple_strtoul(s, NULL, 0); - if (code_bytes > 8192) - code_bytes = 8192; - - return 1; -} -__setup("code_bytes=", code_bytes_setup); diff --git a/trunk/arch/x86/kernel/dumpstack_64.c b/trunk/arch/x86/kernel/dumpstack_64.c deleted file mode 100644 index 96a5db7da8a7..000000000000 --- a/trunk/arch/x86/kernel/dumpstack_64.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define STACKSLOTS_PER_LINE 4 -#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) - -int panic_on_unrecovered_nmi; -int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; -static unsigned int code_bytes = 64; -static int die_counter; - -void printk_address(unsigned long address, int reliable) -{ - printk(" [<%p>] %s%pS\n", (void *) address, - reliable ? "" : "? ", (void *) address); -} - -static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, - unsigned *usedp, char **idp) -{ - static char ids[][8] = { - [DEBUG_STACK - 1] = "#DB", - [NMI_STACK - 1] = "NMI", - [DOUBLEFAULT_STACK - 1] = "#DF", - [STACKFAULT_STACK - 1] = "#SS", - [MCE_STACK - 1] = "#MC", -#if DEBUG_STKSZ > EXCEPTION_STKSZ - [N_EXCEPTION_STACKS ... - N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" -#endif - }; - unsigned k; - - /* - * Iterate over all exception stacks, and figure out whether - * 'stack' is in one of them: - */ - for (k = 0; k < N_EXCEPTION_STACKS; k++) { - unsigned long end = per_cpu(orig_ist, cpu).ist[k]; - /* - * Is 'stack' above this exception frame's end? - * If yes then skip to the next frame. - */ - if (stack >= end) - continue; - /* - * Is 'stack' above this exception frame's start address? - * If yes then we found the right frame. - */ - if (stack >= end - EXCEPTION_STKSZ) { - /* - * Make sure we only iterate through an exception - * stack once. If it comes up for the second time - * then there's something wrong going on - just - * break out and return NULL: - */ - if (*usedp & (1U << k)) - break; - *usedp |= 1U << k; - *idp = ids[k]; - return (unsigned long *)end; - } - /* - * If this is a debug stack, and if it has a larger size than - * the usual exception stacks, then 'stack' might still - * be within the lower portion of the debug stack: - */ -#if DEBUG_STKSZ > EXCEPTION_STKSZ - if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) { - unsigned j = N_EXCEPTION_STACKS - 1; - - /* - * Black magic. A large debug stack is composed of - * multiple exception stack entries, which we - * iterate through now. Dont look: - */ - do { - ++j; - end -= EXCEPTION_STKSZ; - ids[j][4] = '1' + (j - N_EXCEPTION_STACKS); - } while (stack < end - EXCEPTION_STKSZ); - if (*usedp & (1U << j)) - break; - *usedp |= 1U << j; - *idp = ids[j]; - return (unsigned long *)end; - } -#endif - } - return NULL; -} - -/* - * x86-64 can have up to three kernel stacks: - * process stack - * interrupt stack - * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack - */ - -static inline int valid_stack_ptr(struct thread_info *tinfo, - void *p, unsigned int size, void *end) -{ - void *t = tinfo; - if (end) { - if (p < end && p >= (end-THREAD_SIZE)) - return 1; - else - return 0; - } - return p > t && p < t + THREAD_SIZE - size; -} - -/* The form of the top of the frame on the stack */ -struct stack_frame { - struct stack_frame *next_frame; - unsigned long return_address; -}; - -static inline unsigned long -print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data, - unsigned long *end) -{ - struct stack_frame *frame = (struct stack_frame *)bp; - - while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) { - unsigned long addr; - - addr = *stack; - if (__kernel_text_address(addr)) { - if ((unsigned long) stack == bp + sizeof(long)) { - ops->address(data, addr, 1); - frame = frame->next_frame; - bp = (unsigned long) frame; - } else { - ops->address(data, addr, bp == 0); - } - } - stack++; - } - return bp; -} - -void dump_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) -{ - const unsigned cpu = get_cpu(); - unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; - unsigned used = 0; - struct thread_info *tinfo; - - if (!task) - task = current; - - if (!stack) { - unsigned long dummy; - stack = &dummy; - if (task && task != current) - stack = (unsigned long *)task->thread.sp; - } - -#ifdef CONFIG_FRAME_POINTER - if (!bp) { - if (task == current) { - /* Grab bp right from our regs */ - get_bp(bp); - } else { - /* bp is the last reg pushed by switch_to */ - bp = *(unsigned long *) task->thread.sp; - } - } -#endif - - /* - * Print function call entries in all stacks, starting at the - * current stack address. If the stacks consist of nested - * exceptions - */ - tinfo = task_thread_info(task); - for (;;) { - char *id; - unsigned long *estack_end; - estack_end = in_exception_stack(cpu, (unsigned long)stack, - &used, &id); - - if (estack_end) { - if (ops->stack(data, id) < 0) - break; - - bp = print_context_stack(tinfo, stack, bp, ops, - data, estack_end); - ops->stack(data, ""); - /* - * We link to the next stack via the - * second-to-last pointer (index -2 to end) in the - * exception stack: - */ - stack = (unsigned long *) estack_end[-2]; - continue; - } - if (irqstack_end) { - unsigned long *irqstack; - irqstack = irqstack_end - - (IRQSTACKSIZE - 64) / sizeof(*irqstack); - - if (stack >= irqstack && stack < irqstack_end) { - if (ops->stack(data, "IRQ") < 0) - break; - bp = print_context_stack(tinfo, stack, bp, - ops, data, irqstack_end); - /* - * We link to the next stack (which would be - * the process stack normally) the last - * pointer (index -1 to end) in the IRQ stack: - */ - stack = (unsigned long *) (irqstack_end[-1]); - irqstack_end = NULL; - ops->stack(data, "EOI"); - continue; - } - } - break; - } - - /* - * This handles the process stack: - */ - bp = print_context_stack(tinfo, stack, bp, ops, data, NULL); - put_cpu(); -} -EXPORT_SYMBOL(dump_trace); - -static void -print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) -{ - printk(data); - print_symbol(msg, symbol); - printk("\n"); -} - -static void print_trace_warning(void *data, char *msg) -{ - printk("%s%s\n", (char *)data, msg); -} - -static int print_trace_stack(void *data, char *name) -{ - printk("%s <%s> ", (char *)data, name); - return 0; -} - -/* - * Print one address/symbol entries per line. - */ -static void print_trace_address(void *data, unsigned long addr, int reliable) -{ - touch_nmi_watchdog(); - printk(data); - printk_address(addr, reliable); -} - -static const struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, -}; - -static void -show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp, char *log_lvl) -{ - printk("%sCall Trace:\n", log_lvl); - dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); -} - -void show_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp) -{ - show_trace_log_lvl(task, regs, stack, bp, ""); -} - -static void -show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long *sp, unsigned long bp, char *log_lvl) -{ - unsigned long *stack; - int i; - const int cpu = smp_processor_id(); - unsigned long *irqstack_end = - (unsigned long *) (cpu_pda(cpu)->irqstackptr); - unsigned long *irqstack = - (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); - - /* - * debugging aid: "show_stack(NULL, NULL);" prints the - * back trace for this cpu. - */ - - if (sp == NULL) { - if (task) - sp = (unsigned long *)task->thread.sp; - else - sp = (unsigned long *)&sp; - } - - stack = sp; - for (i = 0; i < kstack_depth_to_print; i++) { - if (stack >= irqstack && stack <= irqstack_end) { - if (stack == irqstack_end) { - stack = (unsigned long *) (irqstack_end[-1]); - printk(" "); - } - } else { - if (((long) stack & (THREAD_SIZE-1)) == 0) - break; - } - if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - printk("\n%s", log_lvl); - printk(" %016lx", *stack++); - touch_nmi_watchdog(); - } - printk("\n"); - show_trace_log_lvl(task, regs, sp, bp, log_lvl); -} - -void show_stack(struct task_struct *task, unsigned long *sp) -{ - show_stack_log_lvl(task, NULL, sp, 0, ""); -} - -/* - * The architecture-independent dump_stack generator - */ -void dump_stack(void) -{ - unsigned long bp = 0; - unsigned long stack; - -#ifdef CONFIG_FRAME_POINTER - if (!bp) - get_bp(bp); -#endif - - printk("Pid: %d, comm: %.20s %s %s %.*s\n", - current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - show_trace(NULL, NULL, &stack, bp); -} -EXPORT_SYMBOL(dump_stack); - -void show_registers(struct pt_regs *regs) -{ - int i; - unsigned long sp; - const int cpu = smp_processor_id(); - struct task_struct *cur = cpu_pda(cpu)->pcurrent; - - sp = regs->sp; - printk("CPU %d ", cpu); - __show_regs(regs, 1); - printk("Process %s (pid: %d, threadinfo %p, task %p)\n", - cur->comm, cur->pid, task_thread_info(cur), cur); - - /* - * When in-kernel, we also print out the stack and code at the - * time of the fault.. - */ - if (!user_mode(regs)) { - unsigned int code_prologue = code_bytes * 43 / 64; - unsigned int code_len = code_bytes; - unsigned char c; - u8 *ip; - - printk(KERN_EMERG "Stack:\n"); - show_stack_log_lvl(NULL, regs, (unsigned long *)sp, - regs->bp, KERN_EMERG); - - printk(KERN_EMERG "Code: "); - - ip = (u8 *)regs->ip - code_prologue; - if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - /* try starting at IP */ - ip = (u8 *)regs->ip; - code_len = code_len - code_prologue + 1; - } - for (i = 0; i < code_len; i++, ip++) { - if (ip < (u8 *)PAGE_OFFSET || - probe_kernel_address(ip, c)) { - printk(" Bad RIP value."); - break; - } - if (ip == (u8 *)regs->ip) - printk("<%02x> ", c); - else - printk("%02x ", c); - } - } - printk("\n"); -} - -int is_valid_bugaddr(unsigned long ip) -{ - unsigned short ud2; - - if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2))) - return 0; - - return ud2 == 0x0b0f; -} - -static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; -static int die_owner = -1; -static unsigned int die_nest_count; - -unsigned __kprobes long oops_begin(void) -{ - int cpu; - unsigned long flags; - - oops_enter(); - - /* racy, but better than risking deadlock. */ - raw_local_irq_save(flags); - cpu = smp_processor_id(); - if (!__raw_spin_trylock(&die_lock)) { - if (cpu == die_owner) - /* nested oops. should stop eventually */; - else - __raw_spin_lock(&die_lock); - } - die_nest_count++; - die_owner = cpu; - console_verbose(); - bust_spinlocks(1); - return flags; -} - -void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) -{ - die_owner = -1; - bust_spinlocks(0); - die_nest_count--; - if (!die_nest_count) - /* Nest count reaches zero, release the lock. */ - __raw_spin_unlock(&die_lock); - raw_local_irq_restore(flags); - if (!regs) { - oops_exit(); - return; - } - if (in_interrupt()) - panic("Fatal exception in interrupt"); - if (panic_on_oops) - panic("Fatal exception"); - oops_exit(); - do_exit(signr); -} - -int __kprobes __die(const char *str, struct pt_regs *regs, long err) -{ - printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); -#endif -#ifdef CONFIG_SMP - printk("SMP "); -#endif -#ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC"); -#endif - printk("\n"); - sysfs_printk_last_file(); - if (notify_die(DIE_OOPS, str, regs, err, - current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) - return 1; - - show_registers(regs); - add_taint(TAINT_DIE); - /* Executive summary in case the oops scrolled away */ - printk(KERN_ALERT "RIP "); - printk_address(regs->ip, 1); - printk(" RSP <%016lx>\n", regs->sp); - if (kexec_should_crash(current)) - crash_kexec(regs); - return 0; -} - -void die(const char *str, struct pt_regs *regs, long err) -{ - unsigned long flags = oops_begin(); - - if (!user_mode(regs)) - report_bug(regs->ip, regs); - - if (__die(str, regs, err)) - regs = NULL; - oops_end(flags, regs, SIGSEGV); -} - -notrace __kprobes void -die_nmi(char *str, struct pt_regs *regs, int do_panic) -{ - unsigned long flags; - - if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP) - return; - - flags = oops_begin(); - /* - * We are in trouble anyway, lets at least try - * to get a message out. - */ - printk(KERN_EMERG "%s", str); - printk(" on CPU%d, ip %08lx, registers:\n", - smp_processor_id(), regs->ip); - show_registers(regs); - if (kexec_should_crash(current)) - crash_kexec(regs); - if (do_panic || panic_on_oops) - panic("Non maskable interrupt"); - oops_end(flags, NULL, SIGBUS); - nmi_exit(); - local_irq_enable(); - do_exit(SIGBUS); -} - -static int __init oops_setup(char *s) -{ - if (!s) - return -EINVAL; - if (!strcmp(s, "panic")) - panic_on_oops = 1; - return 0; -} -early_param("oops", oops_setup); - -static int __init kstack_setup(char *s) -{ - if (!s) - return -EINVAL; - kstack_depth_to_print = simple_strtoul(s, NULL, 0); - return 0; -} -early_param("kstack", kstack_setup); - -static int __init code_bytes_setup(char *s) -{ - code_bytes = simple_strtoul(s, NULL, 0); - if (code_bytes > 8192) - code_bytes = 8192; - - return 1; -} -__setup("code_bytes=", code_bytes_setup); diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S index b21fbfaffe39..109792bc7cfa 100644 --- a/trunk/arch/x86/kernel/entry_32.S +++ b/trunk/arch/x86/kernel/entry_32.S @@ -730,7 +730,6 @@ error_code: movl $(__USER_DS), %ecx movl %ecx, %ds movl %ecx, %es - TRACE_IRQS_OFF movl %esp,%eax # pt_regs pointer call *%edi jmp ret_from_exception @@ -761,9 +760,20 @@ ENTRY(device_not_available) RING0_INT_FRAME pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 - pushl $do_device_not_available + SAVE_ALL + GET_CR0_INTO_EAX + testl $0x4, %eax # EM (math emulation bit) + jne device_not_available_emulate + preempt_stop(CLBR_ANY) + call math_state_restore + jmp ret_from_exception +device_not_available_emulate: + pushl $0 # temporary storage for ORIG_EIP CFI_ADJUST_CFA_OFFSET 4 - jmp error_code + call math_emulate + addl $4, %esp + CFI_ADJUST_CFA_OFFSET -4 + jmp ret_from_exception CFI_ENDPROC END(device_not_available) @@ -804,7 +814,6 @@ debug_stack_correct: pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - TRACE_IRQS_OFF xorl %edx,%edx # error code 0 movl %esp,%eax # pt_regs pointer call do_debug @@ -849,7 +858,6 @@ nmi_stack_correct: pushl %eax CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - TRACE_IRQS_OFF xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_nmi @@ -890,7 +898,6 @@ nmi_espfix_stack: pushl %eax CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - TRACE_IRQS_OFF FIXUP_ESPFIX_STACK # %eax == %esp xorl %edx,%edx # zero error code call do_nmi @@ -921,7 +928,6 @@ KPROBE_ENTRY(int3) pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - TRACE_IRQS_OFF xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_int3 @@ -1024,7 +1030,7 @@ ENTRY(machine_check) RING0_INT_FRAME pushl $0 CFI_ADJUST_CFA_OFFSET 4 - pushl $do_machine_check + pushl machine_check_vector CFI_ADJUST_CFA_OFFSET 4 jmp error_code CFI_ENDPROC diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index 1db6ce4314e1..cf3a0b2d0059 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -667,13 +667,6 @@ END(stub_rt_sigreturn) SAVE_ARGS leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler pushq %rbp - /* - * Save rbp twice: One is for marking the stack frame, as usual, and the - * other, to fill pt_regs properly. This is because bx comes right - * before the last saved register in that structure, and not bp. If the - * base pointer were in the place bx is today, this would not be needed. - */ - movq %rbp, -8(%rsp) CFI_ADJUST_CFA_OFFSET 8 CFI_REL_OFFSET rbp, 0 movq %rsp,%rbp @@ -939,9 +932,6 @@ END(spurious_interrupt) .if \ist movq %gs:pda_data_offset, %rbp .endif - .if \irqtrace - TRACE_IRQS_OFF - .endif movq %rsp,%rdi movq ORIG_RAX(%rsp),%rsi movq $-1,ORIG_RAX(%rsp) @@ -1068,8 +1058,7 @@ KPROBE_ENTRY(error_entry) je error_kernelspace error_swapgs: SWAPGS -error_sti: - TRACE_IRQS_OFF +error_sti: movq %rdi,RDI(%rsp) CFI_REL_OFFSET rdi,RDI movq %rsp,%rdi @@ -1243,7 +1232,7 @@ ENTRY(simd_coprocessor_error) END(simd_coprocessor_error) ENTRY(device_not_available) - zeroentry do_device_not_available + zeroentry math_state_restore END(device_not_available) /* runs on exception stack */ diff --git a/trunk/arch/x86/kernel/es7000_32.c b/trunk/arch/x86/kernel/es7000_32.c index f454c78fcef6..849e5cd485b8 100644 --- a/trunk/arch/x86/kernel/es7000_32.c +++ b/trunk/arch/x86/kernel/es7000_32.c @@ -109,7 +109,6 @@ struct oem_table { }; extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); -extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); #endif struct mip_reg { @@ -244,38 +243,21 @@ parse_unisys_oem (char *oemptr) } #ifdef CONFIG_ACPI -static unsigned long oem_addrX; -static unsigned long oem_size; -int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) +int __init +find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; int i = 0; - acpi_size tbl_size; - - while (ACPI_SUCCESS(acpi_get_table_with_size("OEM1", i++, &header, &tbl_size))) { + while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) { if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { struct oem_table *t = (struct oem_table *)header; - - oem_addrX = t->OEMTableAddr; - oem_size = t->OEMTableSize; - early_acpi_os_unmap_memory(header, tbl_size); - - *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, - oem_size); + *oem_addr = (unsigned long)__acpi_map_table(t->OEMTableAddr, + t->OEMTableSize); return 0; } - early_acpi_os_unmap_memory(header, tbl_size); } return -1; } - -void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) -{ - if (!oem_addr) - return; - - __acpi_unmap_table((char *)oem_addr, oem_size); -} #endif static void diff --git a/trunk/arch/x86/kernel/genx2apic_uv_x.c b/trunk/arch/x86/kernel/genx2apic_uv_x.c index 33581d94a90e..ae2ffc8a400c 100644 --- a/trunk/arch/x86/kernel/genx2apic_uv_x.c +++ b/trunk/arch/x86/kernel/genx2apic_uv_x.c @@ -114,7 +114,7 @@ static void uv_send_IPI_one(int cpu, int vector) unsigned long val, apicid, lapicid; int pnode; - apicid = per_cpu(x86_cpu_to_apicid, cpu); + apicid = per_cpu(x86_cpu_to_apicid, cpu); /* ZZZ - cache node-local ? */ lapicid = apicid & 0x3f; /* ZZZ macro needed */ pnode = uv_apicid_to_pnode(apicid); val = @@ -202,10 +202,12 @@ static unsigned int phys_pkg_id(int index_msb) return uv_read_apic_id() >> index_msb; } +#ifdef ZZZ /* Needs x2apic patch */ static void uv_send_IPI_self(int vector) { apic_write(APIC_SELF_IPI, vector); } +#endif struct genapic apic_x2apic_uv_x = { .name = "UV large system", @@ -213,15 +215,15 @@ struct genapic apic_x2apic_uv_x = { .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), .target_cpus = uv_target_cpus, - .vector_allocation_domain = uv_vector_allocation_domain, + .vector_allocation_domain = uv_vector_allocation_domain,/* Fixme ZZZ */ .apic_id_registered = uv_apic_id_registered, .init_apic_ldr = uv_init_apic_ldr, .send_IPI_all = uv_send_IPI_all, .send_IPI_allbutself = uv_send_IPI_allbutself, .send_IPI_mask = uv_send_IPI_mask, - .send_IPI_self = uv_send_IPI_self, + /* ZZZ.send_IPI_self = uv_send_IPI_self, */ .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, - .phys_pkg_id = phys_pkg_id, + .phys_pkg_id = phys_pkg_id, /* Fixme ZZZ */ .get_apic_id = get_apic_id, .set_apic_id = set_apic_id, .apic_id_mask = (0xFFFFFFFFu), @@ -284,13 +286,12 @@ static __init void map_low_mmrs(void) enum map_type {map_wb, map_uc}; -static __init void map_high(char *id, unsigned long base, int shift, - int max_pnode, enum map_type map_type) +static __init void map_high(char *id, unsigned long base, int shift, enum map_type map_type) { unsigned long bytes, paddr; paddr = base << shift; - bytes = (1UL << shift) * (max_pnode + 1); + bytes = (1UL << shift); printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes); if (map_type == map_uc) @@ -306,7 +307,7 @@ static __init void map_gru_high(int max_pnode) gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); if (gru.s.enable) - map_high("GRU", gru.s.base, shift, max_pnode, map_wb); + map_high("GRU", gru.s.base, shift, map_wb); } static __init void map_config_high(int max_pnode) @@ -316,7 +317,7 @@ static __init void map_config_high(int max_pnode) cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR); if (cfg.s.enable) - map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc); + map_high("CONFIG", cfg.s.base, shift, map_uc); } static __init void map_mmr_high(int max_pnode) @@ -326,7 +327,7 @@ static __init void map_mmr_high(int max_pnode) mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); if (mmr.s.enable) - map_high("MMR", mmr.s.base, shift, max_pnode, map_uc); + map_high("MMR", mmr.s.base, shift, map_uc); } static __init void map_mmioh_high(int max_pnode) @@ -336,7 +337,7 @@ static __init void map_mmioh_high(int max_pnode) mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); if (mmioh.s.enable) - map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc); + map_high("MMIOH", mmioh.s.base, shift, map_uc); } static __init void uv_rtc_init(void) diff --git a/trunk/arch/x86/kernel/head.c b/trunk/arch/x86/kernel/head.c index 1dcb0f13897e..3e66bd364a9d 100644 --- a/trunk/arch/x86/kernel/head.c +++ b/trunk/arch/x86/kernel/head.c @@ -35,7 +35,6 @@ void __init reserve_ebda_region(void) /* start of EBDA area */ ebda_addr = get_bios_ebda(); - printk(KERN_INFO "BIOS EBDA/lowmem at: %08x/%08x\n", ebda_addr, lowmem); /* Fixup: bios puts an EBDA in the top 64K segment */ /* of conventional memory, but does not adjust lowmem. */ diff --git a/trunk/arch/x86/kernel/hpet.c b/trunk/arch/x86/kernel/hpet.c index acf62fc233da..73deaffadd03 100644 --- a/trunk/arch/x86/kernel/hpet.c +++ b/trunk/arch/x86/kernel/hpet.c @@ -115,17 +115,13 @@ static void hpet_reserve_platform_timers(unsigned long id) hd.hd_phys_address = hpet_address; hd.hd_address = hpet; hd.hd_nirqs = nrtimers; + hd.hd_flags = HPET_DATA_PLATFORM; hpet_reserve_timer(&hd, 0); #ifdef CONFIG_HPET_EMULATE_RTC hpet_reserve_timer(&hd, 1); #endif - /* - * NOTE that hd_irq[] reflects IOAPIC input pins (LEGACY_8254 - * is wrong for i8259!) not the output IRQ. Many BIOS writers - * don't bother configuring *any* comparator interrupts. - */ hd.hd_irq[0] = HPET_LEGACY_8254; hd.hd_irq[1] = HPET_LEGACY_RTC; diff --git a/trunk/arch/x86/kernel/irqinit_64.c b/trunk/arch/x86/kernel/irqinit_64.c index 5b5be9d43c2a..1f26fd9ec4f4 100644 --- a/trunk/arch/x86/kernel/irqinit_64.c +++ b/trunk/arch/x86/kernel/irqinit_64.c @@ -135,7 +135,7 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = { [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1 }; -void __init init_ISA_irqs(void) +static void __init init_ISA_irqs (void) { int i; @@ -164,8 +164,22 @@ void __init init_ISA_irqs(void) void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); -static void __init smp_intr_init(void) +void __init native_init_IRQ(void) { + int i; + + init_ISA_irqs(); + /* + * Cover the whole vector space, no vector can escape + * us. (some of these will be overridden and become + * 'special' SMP interrupts) + */ + for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { + int vector = FIRST_EXTERNAL_VECTOR + i; + if (vector != IA32_SYSCALL_VECTOR) + set_intr_gate(vector, interrupt[i]); + } + #ifdef CONFIG_SMP /* * The reschedule interrupt is a CPU-to-CPU reschedule-helper @@ -193,12 +207,6 @@ static void __init smp_intr_init(void) /* Low priority IPI to cleanup after moving an irq */ set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); #endif -} - -static void __init apic_intr_init(void) -{ - smp_intr_init(); - alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); @@ -208,25 +216,6 @@ static void __init apic_intr_init(void) /* IPI vectors for APIC spurious and error interrupts */ alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); -} - -void __init native_init_IRQ(void) -{ - int i; - - init_ISA_irqs(); - /* - * Cover the whole vector space, no vector can escape - * us. (some of these will be overridden and become - * 'special' SMP interrupts) - */ - for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { - int vector = FIRST_EXTERNAL_VECTOR + i; - if (vector != IA32_SYSCALL_VECTOR) - set_intr_gate(vector, interrupt[i]); - } - - apic_intr_init(); if (!acpi_ioapic) setup_irq(2, &irq2); diff --git a/trunk/arch/x86/kernel/msr.c b/trunk/arch/x86/kernel/msr.c index 82a7c7ed6d45..2e2af5d18191 100644 --- a/trunk/arch/x86/kernel/msr.c +++ b/trunk/arch/x86/kernel/msr.c @@ -163,8 +163,8 @@ static int __cpuinit msr_device_create(int cpu) { struct device *dev; - dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL, - "msr%d", cpu); + dev = device_create_drvdata(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), + NULL, "msr%d", cpu); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } diff --git a/trunk/arch/x86/kernel/pci-calgary_64.c b/trunk/arch/x86/kernel/pci-calgary_64.c index e1e731d78f38..080d1d27f37a 100644 --- a/trunk/arch/x86/kernel/pci-calgary_64.c +++ b/trunk/arch/x86/kernel/pci-calgary_64.c @@ -217,6 +217,16 @@ static inline unsigned long verify_bit_range(unsigned long* bitmap, #endif /* CONFIG_IOMMU_DEBUG */ +static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) +{ + unsigned int npages; + + npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK); + npages >>= PAGE_SHIFT; + + return npages; +} + static inline int translation_enabled(struct iommu_table *tbl) { /* only PHBs with translation enabled have an IOMMU table */ @@ -398,7 +408,7 @@ static void calgary_unmap_sg(struct device *dev, if (dmalen == 0) break; - npages = iommu_num_pages(dma, dmalen, PAGE_SIZE); + npages = num_dma_pages(dma, dmalen); iommu_free(tbl, dma, npages); } } @@ -417,7 +427,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, BUG_ON(!sg_page(s)); vaddr = (unsigned long) sg_virt(s); - npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE); + npages = num_dma_pages(vaddr, s->length); entry = iommu_range_alloc(dev, tbl, npages); if (entry == bad_dma_address) { @@ -454,7 +464,7 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, struct iommu_table *tbl = find_iommu_table(dev); uaddr = (unsigned long)vaddr; - npages = iommu_num_pages(uaddr, size, PAGE_SIZE); + npages = num_dma_pages(uaddr, size); return iommu_alloc(dev, tbl, vaddr, npages, direction); } @@ -465,7 +475,7 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; - npages = iommu_num_pages(dma_handle, size, PAGE_SIZE); + npages = num_dma_pages(dma_handle, size); iommu_free(tbl, dma_handle, npages); } diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 192624820217..0a3824e837b4 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -125,13 +125,13 @@ void __init pci_iommu_alloc(void) pci_swiotlb_init(); } -unsigned long iommu_nr_pages(unsigned long addr, unsigned long len) +unsigned long iommu_num_pages(unsigned long addr, unsigned long len) { unsigned long size = roundup((addr & ~PAGE_MASK) + len, PAGE_SIZE); return size >> PAGE_SHIFT; } -EXPORT_SYMBOL(iommu_nr_pages); +EXPORT_SYMBOL(iommu_num_pages); #endif void *dma_generic_alloc_coherent(struct device *dev, size_t size, diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c index e3f75bbcedea..145f1c83369f 100644 --- a/trunk/arch/x86/kernel/pci-gart_64.c +++ b/trunk/arch/x86/kernel/pci-gart_64.c @@ -231,7 +231,7 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size) static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, size_t size, int dir, unsigned long align_mask) { - unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); + unsigned long npages = iommu_num_pages(phys_mem, size); unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); int i; @@ -285,7 +285,7 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, return; iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; - npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); + npages = iommu_num_pages(dma_addr, size); for (i = 0; i < npages; i++) { iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; CLEAR_LEAK(iommu_page + i); @@ -368,7 +368,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, } addr = phys_addr; - pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE); + pages = iommu_num_pages(s->offset, s->length); while (pages--) { iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); SET_LEAK(iommu_page); @@ -451,7 +451,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) seg_size += s->length; need = nextneed; - pages += iommu_num_pages(s->offset, s->length, PAGE_SIZE); + pages += iommu_num_pages(s->offset, s->length); ps = s; } if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0) diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c index 0a1302fe6d45..922c14058f97 100644 --- a/trunk/arch/x86/kernel/process_32.c +++ b/trunk/arch/x86/kernel/process_32.c @@ -123,7 +123,7 @@ void cpu_idle(void) } } -void __show_regs(struct pt_regs *regs, int all) +void __show_registers(struct pt_regs *regs, int all) { unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; unsigned long d0, d1, d2, d3, d6, d7; @@ -189,7 +189,7 @@ void __show_regs(struct pt_regs *regs, int all) void show_regs(struct pt_regs *regs) { - __show_regs(regs, 1); + __show_registers(regs, 1); show_trace(NULL, regs, ®s->sp, regs->bp); } diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index cd8c0ed02b7e..ca80394ef5b8 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -136,7 +136,7 @@ void cpu_idle(void) } /* Prints also some state that isn't saved in the pt_regs */ -void __show_regs(struct pt_regs *regs, int all) +void __show_regs(struct pt_regs *regs) { unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; unsigned long d0, d1, d2, d3, d6, d7; @@ -175,9 +175,6 @@ void __show_regs(struct pt_regs *regs, int all) rdmsrl(MSR_GS_BASE, gs); rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); - if (!all) - return; - cr0 = read_cr0(); cr2 = read_cr2(); cr3 = read_cr3(); @@ -203,7 +200,7 @@ void __show_regs(struct pt_regs *regs, int all) void show_regs(struct pt_regs *regs) { printk(KERN_INFO "CPU %d:", smp_processor_id()); - __show_regs(regs, 1); + __show_regs(regs); show_trace(NULL, regs, (void *)(regs + 1), regs->bp); } diff --git a/trunk/arch/x86/kernel/quirks.c b/trunk/arch/x86/kernel/quirks.c index f6a11b9b1f98..d13858818100 100644 --- a/trunk/arch/x86/kernel/quirks.c +++ b/trunk/arch/x86/kernel/quirks.c @@ -354,27 +354,9 @@ static void ati_force_hpet_resume(void) printk(KERN_DEBUG "Force enabled HPET at resume\n"); } -static u32 ati_ixp4x0_rev(struct pci_dev *dev) -{ - u32 d; - u8 b; - - pci_read_config_byte(dev, 0xac, &b); - b &= ~(1<<5); - pci_write_config_byte(dev, 0xac, b); - pci_read_config_dword(dev, 0x70, &d); - d |= 1<<8; - pci_write_config_dword(dev, 0x70, d); - pci_read_config_dword(dev, 0x8, &d); - d &= 0xff; - dev_printk(KERN_DEBUG, &dev->dev, "SB4X0 revision 0x%x\n", d); - return d; -} - static void ati_force_enable_hpet(struct pci_dev *dev) { - u32 d, val; - u8 b; + u32 uninitialized_var(val); if (hpet_address || force_hpet_address) return; @@ -384,33 +366,14 @@ static void ati_force_enable_hpet(struct pci_dev *dev) return; } - d = ati_ixp4x0_rev(dev); - if (d < 0x82) - return; - - /* base address */ pci_write_config_dword(dev, 0x14, 0xfed00000); pci_read_config_dword(dev, 0x14, &val); - - /* enable interrupt */ - outb(0x72, 0xcd6); b = inb(0xcd7); - b |= 0x1; - outb(0x72, 0xcd6); outb(b, 0xcd7); - outb(0x72, 0xcd6); b = inb(0xcd7); - if (!(b & 0x1)) - return; - pci_read_config_dword(dev, 0x64, &d); - d |= (1<<10); - pci_write_config_dword(dev, 0x64, d); - pci_read_config_dword(dev, 0x64, &d); - if (!(d & (1<<10))) - return; - force_hpet_address = val; force_hpet_resume_type = ATI_FORCE_HPET_RESUME; dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n", force_hpet_address); cached_dev = dev; + return; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS, ati_force_enable_hpet); diff --git a/trunk/arch/x86/kernel/rtc.c b/trunk/arch/x86/kernel/rtc.c index 0a23b5795b25..05191bbc68b8 100644 --- a/trunk/arch/x86/kernel/rtc.c +++ b/trunk/arch/x86/kernel/rtc.c @@ -223,25 +223,11 @@ static struct platform_device rtc_device = { static __init int add_rtc_cmos(void) { #ifdef CONFIG_PNP - static const char *ids[] __initconst = - { "PNP0b00", "PNP0b01", "PNP0b02", }; - struct pnp_dev *dev; - struct pnp_id *id; - int i; - - pnp_for_each_dev(dev) { - for (id = dev->id; id; id = id->next) { - for (i = 0; i < ARRAY_SIZE(ids); i++) { - if (compare_pnp_id(id, ids[i]) != 0) - return 0; - } - } - } -#endif - + if (!pnp_platform_devices) + platform_device_register(&rtc_device); +#else platform_device_register(&rtc_device); - dev_info(&rtc_device.dev, - "registered platform RTC device (no PNP device found)\n"); +#endif /* CONFIG_PNP */ return 0; } device_initcall(add_rtc_cmos); diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index 2255782e8d4b..21b8e0a59780 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -302,7 +302,7 @@ static void __init relocate_initrd(void) if (clen > MAX_MAP_CHUNK-slop) clen = MAX_MAP_CHUNK-slop; mapaddr = ramdisk_image & PAGE_MASK; - p = early_memremap(mapaddr, clen+slop); + p = early_ioremap(mapaddr, clen+slop); memcpy(q, p+slop, clen); early_iounmap(p, clen+slop); q += clen; @@ -379,7 +379,7 @@ static void __init parse_setup_data(void) return; pa_data = boot_params.hdr.setup_data; while (pa_data) { - data = early_memremap(pa_data, PAGE_SIZE); + data = early_ioremap(pa_data, PAGE_SIZE); switch (data->type) { case SETUP_E820_EXT: parse_e820_ext(data, pa_data); @@ -402,7 +402,7 @@ static void __init e820_reserve_setup_data(void) return; pa_data = boot_params.hdr.setup_data; while (pa_data) { - data = early_memremap(pa_data, sizeof(*data)); + data = early_ioremap(pa_data, sizeof(*data)); e820_update_range(pa_data, sizeof(*data)+data->len, E820_RAM, E820_RESERVED_KERN); found = 1; @@ -428,7 +428,7 @@ static void __init reserve_early_setup_data(void) return; pa_data = boot_params.hdr.setup_data; while (pa_data) { - data = early_memremap(pa_data, sizeof(*data)); + data = early_ioremap(pa_data, sizeof(*data)); sprintf(buf, "setup data %x", data->type); reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf); pa_data = data->next; @@ -998,8 +998,6 @@ void __init setup_arch(char **cmdline_p) */ acpi_boot_table_init(); - early_acpi_boot_init(); - #ifdef CONFIG_ACPI_NUMA /* * Parse SRAT to discover nodes. diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 7ed9e070a6e9..76b6f50978f7 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -282,8 +282,6 @@ static void __cpuinit smp_callin(void) cpu_set(cpuid, cpu_callin_map); } -static int __cpuinitdata unsafe_smp; - /* * Activate a secondary processor. */ @@ -336,17 +334,14 @@ static void __cpuinit start_secondary(void *unused) * does not change while we are assigning vectors to cpus. Holding * this lock ensures we don't half assign or remove an irq from a cpu. */ - ipi_call_lock(); + ipi_call_lock_irq(); lock_vector_lock(); __setup_vector_irq(smp_processor_id()); cpu_set(smp_processor_id(), cpu_online_map); unlock_vector_lock(); - ipi_call_unlock(); + ipi_call_unlock_irq(); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; - /* enable local interrupts */ - local_irq_enable(); - setup_secondary_clock(); wmb(); @@ -399,7 +394,7 @@ static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c) goto valid_k7; /* If we get here, not a certified SMP capable AMD system. */ - unsafe_smp = 1; + add_taint(TAINT_UNSAFE_SMP); } valid_k7: @@ -416,10 +411,12 @@ static void __cpuinit smp_checks(void) * Don't taint if we are running SMP kernel on a single non-MP * approved Athlon */ - if (unsafe_smp && num_online_cpus() > 1) { - printk(KERN_INFO "WARNING: This combination of AMD" - "processors is not suitable for SMP.\n"); - add_taint(TAINT_UNSAFE_SMP); + if (tainted & TAINT_UNSAFE_SMP) { + if (num_online_cpus()) + printk(KERN_INFO "WARNING: This combination of AMD" + "processors is not suitable for SMP.\n"); + else + tainted &= ~TAINT_UNSAFE_SMP; } } @@ -599,12 +596,10 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) * Give the other CPU some time to accept the IPI. */ udelay(200); - if (APIC_INTEGRATED(apic_version[phys_apicid])) { - maxlvt = lapic_get_maxlvt(); - if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); - } + maxlvt = lapic_get_maxlvt(); + if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ + apic_write(APIC_ESR, 0); + accept_status = (apic_read(APIC_ESR) & 0xEF); pr_debug("NMI sent.\n"); if (send_status) @@ -1261,6 +1256,39 @@ void __init native_smp_cpus_done(unsigned int max_cpus) check_nmi_watchdog(); } +#ifdef CONFIG_HOTPLUG_CPU + +static void remove_siblinginfo(int cpu) +{ + int sibling; + struct cpuinfo_x86 *c = &cpu_data(cpu); + + for_each_cpu_mask_nr(sibling, per_cpu(cpu_core_map, cpu)) { + cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); + /*/ + * last thread sibling in this cpu core going down + */ + if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) + cpu_data(sibling).booted_cores--; + } + + for_each_cpu_mask_nr(sibling, per_cpu(cpu_sibling_map, cpu)) + cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); + cpus_clear(per_cpu(cpu_sibling_map, cpu)); + cpus_clear(per_cpu(cpu_core_map, cpu)); + c->phys_proc_id = 0; + c->cpu_core_id = 0; + cpu_clear(cpu, cpu_sibling_setup_map); +} + +static int additional_cpus __initdata = -1; + +static __init int setup_additional_cpus(char *s) +{ + return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL; +} +early_param("additional_cpus", setup_additional_cpus); + /* * cpu_possible_map should be static, it cannot change as cpu's * are onlined, or offlined. The reason is per-cpu data-structures @@ -1280,13 +1308,21 @@ void __init native_smp_cpus_done(unsigned int max_cpus) */ __init void prefill_possible_map(void) { - int i, possible; + int i; + int possible; /* no processor from mptable or madt */ if (!num_processors) num_processors = 1; - possible = num_processors + disabled_cpus; + if (additional_cpus == -1) { + if (disabled_cpus > 0) + additional_cpus = disabled_cpus; + else + additional_cpus = 0; + } + + possible = num_processors + additional_cpus; if (possible > NR_CPUS) possible = NR_CPUS; @@ -1299,31 +1335,6 @@ __init void prefill_possible_map(void) nr_cpu_ids = possible; } -#ifdef CONFIG_HOTPLUG_CPU - -static void remove_siblinginfo(int cpu) -{ - int sibling; - struct cpuinfo_x86 *c = &cpu_data(cpu); - - for_each_cpu_mask_nr(sibling, per_cpu(cpu_core_map, cpu)) { - cpu_clear(cpu, per_cpu(cpu_core_map, sibling)); - /*/ - * last thread sibling in this cpu core going down - */ - if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) - cpu_data(sibling).booted_cores--; - } - - for_each_cpu_mask_nr(sibling, per_cpu(cpu_sibling_map, cpu)) - cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling)); - cpus_clear(per_cpu(cpu_sibling_map, cpu)); - cpus_clear(per_cpu(cpu_core_map, cpu)); - c->phys_proc_id = 0; - c->cpu_core_id = 0; - cpu_clear(cpu, cpu_sibling_setup_map); -} - static void __ref remove_cpu_from_maps(int cpu) { cpu_clear(cpu, cpu_online_map); diff --git a/trunk/arch/x86/kernel/time_32.c b/trunk/arch/x86/kernel/time_32.c index 77b400f06ea2..bbecf8b6bf96 100644 --- a/trunk/arch/x86/kernel/time_32.c +++ b/trunk/arch/x86/kernel/time_32.c @@ -47,9 +47,10 @@ unsigned long profile_pc(struct pt_regs *regs) unsigned long pc = instruction_pointer(regs); #ifdef CONFIG_SMP - if (!user_mode_vm(regs) && in_lock_functions(pc)) { + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) && + in_lock_functions(pc)) { #ifdef CONFIG_FRAME_POINTER - return *(unsigned long *)(regs->bp + sizeof(long)); + return *(unsigned long *)(regs->bp + 4); #else unsigned long *sp = (unsigned long *)®s->sp; @@ -94,7 +95,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) do_timer_interrupt_hook(); -#ifdef CONFIG_MCA if (MCA_bus) { /* The PS/2 uses level-triggered interrupts. You can't turn them off, nor would you want to (any attempt to @@ -108,7 +108,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) u8 irq_v = inb_p( 0x61 ); /* read the current state */ outb_p( irq_v|0x80, 0x61 ); /* reset the IRQ */ } -#endif return IRQ_HANDLED; } diff --git a/trunk/arch/x86/kernel/time_64.c b/trunk/arch/x86/kernel/time_64.c index cb19d650c216..e3d49c553af2 100644 --- a/trunk/arch/x86/kernel/time_64.c +++ b/trunk/arch/x86/kernel/time_64.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -34,34 +33,23 @@ unsigned long profile_pc(struct pt_regs *regs) /* Assume the lock function has either no stack frame or a copy of flags from PUSHF Eflags always has bits 22 and up cleared unlike kernel addresses. */ - if (!user_mode_vm(regs) && in_lock_functions(pc)) { -#ifdef CONFIG_FRAME_POINTER - return *(unsigned long *)(regs->bp + sizeof(long)); -#else + if (!user_mode(regs) && in_lock_functions(pc)) { unsigned long *sp = (unsigned long *)regs->sp; if (sp[0] >> 22) return sp[0]; if (sp[1] >> 22) return sp[1]; -#endif } return pc; } EXPORT_SYMBOL(profile_pc); -irqreturn_t timer_interrupt(int irq, void *dev_id) +static irqreturn_t timer_event_interrupt(int irq, void *dev_id) { add_pda(irq0_irqs, 1); global_clock_event->event_handler(global_clock_event); -#ifdef CONFIG_MCA - if (MCA_bus) { - u8 irq_v = inb_p(0x61); /* read the current state */ - outb_p(irq_v|0x80, 0x61); /* reset the IRQ */ - } -#endif - return IRQ_HANDLED; } @@ -112,7 +100,7 @@ unsigned long __init calibrate_cpu(void) } static struct irqaction irq0 = { - .handler = timer_interrupt, + .handler = timer_event_interrupt, .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, .mask = CPU_MASK_NONE, .name = "timer" @@ -123,13 +111,16 @@ void __init hpet_time_init(void) if (!hpet_enable()) setup_pit_timer(); - irq0.mask = cpumask_of_cpu(0); setup_irq(0, &irq0); } void __init time_init(void) { tsc_init(); + if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) + vgetcpu_mode = VGETCPU_RDTSCP; + else + vgetcpu_mode = VGETCPU_LSL; late_time_init = choose_time_init(); } diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps_32.c similarity index 57% rename from trunk/arch/x86/kernel/traps.c rename to trunk/arch/x86/kernel/traps_32.c index e062974cce34..0429c5de5ea9 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps_32.c @@ -7,11 +7,13 @@ */ /* - * Handle hardware traps and faults. + * 'Traps.c' handles hardware traps and faults after we have saved some + * state in 'asm.s'. */ #include #include #include +#include #include #include #include @@ -30,8 +32,6 @@ #include #include #include -#include -#include #ifdef CONFIG_EISA #include @@ -46,31 +46,21 @@ #include #endif +#include #include #include #include #include #include #include -#include #include #include - -#include - -#ifdef CONFIG_X86_64 -#include -#include -#include -#else -#include -#include #include #include #include #include -#include "cpu/mcheck/mce.h" +#include "mach_traps.h" DECLARE_BITMAP(used_vectors, NR_VECTORS); EXPORT_SYMBOL_GPL(used_vectors); @@ -87,104 +77,418 @@ char ignore_fpu_irq; */ gate_desc idt_table[256] __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; -#endif +int panic_on_unrecovered_nmi; +int kstack_depth_to_print = 24; +static unsigned int code_bytes = 64; static int ignore_nmis; +static int die_counter; -static inline void conditional_sti(struct pt_regs *regs) +void printk_address(unsigned long address, int reliable) { - if (regs->flags & X86_EFLAGS_IF) - local_irq_enable(); +#ifdef CONFIG_KALLSYMS + unsigned long offset = 0; + unsigned long symsize; + const char *symname; + char *modname; + char *delim = ":"; + char namebuf[KSYM_NAME_LEN]; + char reliab[4] = ""; + + symname = kallsyms_lookup(address, &symsize, &offset, + &modname, namebuf); + if (!symname) { + printk(" [<%08lx>]\n", address); + return; + } + if (!reliable) + strcpy(reliab, "? "); + + if (!modname) + modname = delim = ""; + printk(" [<%08lx>] %s%s%s%s%s+0x%lx/0x%lx\n", + address, reliab, delim, modname, delim, symname, offset, symsize); +#else + printk(" [<%08lx>]\n", address); +#endif } -static inline void preempt_conditional_sti(struct pt_regs *regs) +static inline int valid_stack_ptr(struct thread_info *tinfo, + void *p, unsigned int size) { - inc_preempt_count(); - if (regs->flags & X86_EFLAGS_IF) - local_irq_enable(); + void *t = tinfo; + return p > t && p <= t + THREAD_SIZE - size; } -static inline void preempt_conditional_cli(struct pt_regs *regs) +/* The form of the top of the frame on the stack */ +struct stack_frame { + struct stack_frame *next_frame; + unsigned long return_address; +}; + +static inline unsigned long +print_context_stack(struct thread_info *tinfo, + unsigned long *stack, unsigned long bp, + const struct stacktrace_ops *ops, void *data) { - if (regs->flags & X86_EFLAGS_IF) - local_irq_disable(); - dec_preempt_count(); + struct stack_frame *frame = (struct stack_frame *)bp; + + while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) { + unsigned long addr; + + addr = *stack; + if (__kernel_text_address(addr)) { + if ((unsigned long) stack == bp + 4) { + ops->address(data, addr, 1); + frame = frame->next_frame; + bp = (unsigned long) frame; + } else { + ops->address(data, addr, bp == 0); + } + } + stack++; + } + return bp; } -#ifdef CONFIG_X86_32 -static inline void -die_if_kernel(const char *str, struct pt_regs *regs, long err) +void dump_trace(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp, + const struct stacktrace_ops *ops, void *data) { - if (!user_mode_vm(regs)) - die(str, regs, err); + if (!task) + task = current; + + if (!stack) { + unsigned long dummy; + stack = &dummy; + if (task != current) + stack = (unsigned long *)task->thread.sp; + } + +#ifdef CONFIG_FRAME_POINTER + if (!bp) { + if (task == current) { + /* Grab bp right from our regs */ + asm("movl %%ebp, %0" : "=r" (bp) :); + } else { + /* bp is the last reg pushed by switch_to */ + bp = *(unsigned long *) task->thread.sp; + } + } +#endif + + for (;;) { + struct thread_info *context; + + context = (struct thread_info *) + ((unsigned long)stack & (~(THREAD_SIZE - 1))); + bp = print_context_stack(context, stack, bp, ops, data); + /* + * Should be after the line below, but somewhere + * in early boot context comes out corrupted and we + * can't reference it: + */ + if (ops->stack(data, "IRQ") < 0) + break; + stack = (unsigned long *)context->previous_esp; + if (!stack) + break; + touch_nmi_watchdog(); + } +} +EXPORT_SYMBOL(dump_trace); + +static void +print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) +{ + printk(data); + print_symbol(msg, symbol); + printk("\n"); +} + +static void print_trace_warning(void *data, char *msg) +{ + printk("%s%s\n", (char *)data, msg); +} + +static int print_trace_stack(void *data, char *name) +{ + return 0; } /* - * Perform the lazy TSS's I/O bitmap copy. If the TSS has an - * invalid offset set (the LAZY one) and the faulting thread has - * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS, - * we set the offset field correctly and return 1. + * Print one address/symbol entries per line. */ -static int lazy_iobitmap_copy(void) +static void print_trace_address(void *data, unsigned long addr, int reliable) { - struct thread_struct *thread; - struct tss_struct *tss; - int cpu; + printk("%s [<%08lx>] ", (char *)data, addr); + if (!reliable) + printk("? "); + print_symbol("%s\n", addr); + touch_nmi_watchdog(); +} - cpu = get_cpu(); - tss = &per_cpu(init_tss, cpu); - thread = ¤t->thread; +static const struct stacktrace_ops print_trace_ops = { + .warning = print_trace_warning, + .warning_symbol = print_trace_warning_symbol, + .stack = print_trace_stack, + .address = print_trace_address, +}; - if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && - thread->io_bitmap_ptr) { - memcpy(tss->io_bitmap, thread->io_bitmap_ptr, - thread->io_bitmap_max); - /* - * If the previously set map was extending to higher ports - * than the current one, pad extra space with 0xff (no access). - */ - if (thread->io_bitmap_max < tss->io_bitmap_max) { - memset((char *) tss->io_bitmap + - thread->io_bitmap_max, 0xff, - tss->io_bitmap_max - thread->io_bitmap_max); +static void +show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp, char *log_lvl) +{ + dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); + printk("%s =======================\n", log_lvl); +} + +void show_trace(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp) +{ + show_trace_log_lvl(task, regs, stack, bp, ""); +} + +static void +show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *sp, unsigned long bp, char *log_lvl) +{ + unsigned long *stack; + int i; + + if (sp == NULL) { + if (task) + sp = (unsigned long *)task->thread.sp; + else + sp = (unsigned long *)&sp; + } + + stack = sp; + for (i = 0; i < kstack_depth_to_print; i++) { + if (kstack_end(stack)) + break; + if (i && ((i % 8) == 0)) + printk("\n%s ", log_lvl); + printk("%08lx ", *stack++); + } + printk("\n%sCall Trace:\n", log_lvl); + + show_trace_log_lvl(task, regs, sp, bp, log_lvl); +} + +void show_stack(struct task_struct *task, unsigned long *sp) +{ + printk(" "); + show_stack_log_lvl(task, NULL, sp, 0, ""); +} + +/* + * The architecture-independent dump_stack generator + */ +void dump_stack(void) +{ + unsigned long bp = 0; + unsigned long stack; + +#ifdef CONFIG_FRAME_POINTER + if (!bp) + asm("movl %%ebp, %0" : "=r" (bp):); +#endif + + printk("Pid: %d, comm: %.20s %s %s %.*s\n", + current->pid, current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + + show_trace(current, NULL, &stack, bp); +} + +EXPORT_SYMBOL(dump_stack); + +void show_registers(struct pt_regs *regs) +{ + int i; + + print_modules(); + __show_registers(regs, 0); + + printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", + TASK_COMM_LEN, current->comm, task_pid_nr(current), + current_thread_info(), current, task_thread_info(current)); + /* + * When in-kernel, we also print out the stack and code at the + * time of the fault.. + */ + if (!user_mode_vm(regs)) { + unsigned int code_prologue = code_bytes * 43 / 64; + unsigned int code_len = code_bytes; + unsigned char c; + u8 *ip; + + printk("\n" KERN_EMERG "Stack: "); + show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); + + printk(KERN_EMERG "Code: "); + + ip = (u8 *)regs->ip - code_prologue; + if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { + /* try starting at EIP */ + ip = (u8 *)regs->ip; + code_len = code_len - code_prologue + 1; } - tss->io_bitmap_max = thread->io_bitmap_max; - tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; - tss->io_bitmap_owner = thread; - put_cpu(); + for (i = 0; i < code_len; i++, ip++) { + if (ip < (u8 *)PAGE_OFFSET || + probe_kernel_address(ip, c)) { + printk(" Bad EIP value."); + break; + } + if (ip == (u8 *)regs->ip) + printk("<%02x> ", c); + else + printk("%02x ", c); + } + } + printk("\n"); +} - return 1; +int is_valid_bugaddr(unsigned long ip) +{ + unsigned short ud2; + + if (ip < PAGE_OFFSET) + return 0; + if (probe_kernel_address((unsigned short *)ip, ud2)) + return 0; + + return ud2 == 0x0b0f; +} + +static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; +static int die_owner = -1; +static unsigned int die_nest_count; + +unsigned __kprobes long oops_begin(void) +{ + unsigned long flags; + + oops_enter(); + + if (die_owner != raw_smp_processor_id()) { + console_verbose(); + raw_local_irq_save(flags); + __raw_spin_lock(&die_lock); + die_owner = smp_processor_id(); + die_nest_count = 0; + bust_spinlocks(1); + } else { + raw_local_irq_save(flags); } - put_cpu(); + die_nest_count++; + return flags; +} - return 0; +void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) +{ + bust_spinlocks(0); + die_owner = -1; + add_taint(TAINT_DIE); + __raw_spin_unlock(&die_lock); + raw_local_irq_restore(flags); + + if (!regs) + return; + + if (kexec_should_crash(current)) + crash_kexec(regs); + + if (in_interrupt()) + panic("Fatal exception in interrupt"); + + if (panic_on_oops) + panic("Fatal exception"); + + oops_exit(); + do_exit(signr); } + +int __kprobes __die(const char *str, struct pt_regs *regs, long err) +{ + unsigned short ss; + unsigned long sp; + + printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); +#endif +#ifdef CONFIG_SMP + printk("SMP "); +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC"); #endif + printk("\n"); + if (notify_die(DIE_OOPS, str, regs, err, + current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) + return 1; + + show_registers(regs); + /* Executive summary in case the oops scrolled away */ + sp = (unsigned long) (®s->sp); + savesegment(ss, ss); + if (user_mode(regs)) { + sp = regs->sp; + ss = regs->ss & 0xffff; + } + printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); + print_symbol("%s", regs->ip); + printk(" SS:ESP %04x:%08lx\n", ss, sp); + return 0; +} + +/* + * This is gone through when something in the kernel has done something bad + * and is about to be terminated: + */ +void die(const char *str, struct pt_regs *regs, long err) +{ + unsigned long flags = oops_begin(); + + if (die_nest_count < 3) { + report_bug(regs->ip, regs); + + if (__die(str, regs, err)) + regs = NULL; + } else { + printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); + } + + oops_end(flags, regs, SIGSEGV); +} + +static inline void +die_if_kernel(const char *str, struct pt_regs *regs, long err) +{ + if (!user_mode_vm(regs)) + die(str, regs, err); +} static void __kprobes -do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, +do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs *regs, long error_code, siginfo_t *info) { struct task_struct *tsk = current; -#ifdef CONFIG_X86_32 if (regs->flags & X86_VM_MASK) { - /* - * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. - * On nmi (interrupt 2), do_trap should not be called. - */ - if (trapnr < 6) + if (vm86) goto vm86_trap; goto trap_signal; } -#endif if (!user_mode(regs)) goto kernel_trap; -#ifdef CONFIG_X86_32 trap_signal: -#endif /* * We want error_code and trap_no set for userspace faults and * kernelspace faults which result in die(), but not @@ -197,18 +501,6 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; -#ifdef CONFIG_X86_64 - if (show_unhandled_signals && unhandled_signal(tsk, signr) && - printk_ratelimit()) { - printk(KERN_INFO - "%s[%d] trap %s ip:%lx sp:%lx error:%lx", - tsk->comm, tsk->pid, str, - regs->ip, regs->sp, error_code); - print_vma_addr(" in ", regs->ip); - printk("\n"); - } -#endif - if (info) force_sig_info(signr, info, tsk); else @@ -223,29 +515,29 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, } return; -#ifdef CONFIG_X86_32 vm86_trap: if (handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr)) goto trap_signal; return; -#endif } #define DO_ERROR(trapnr, signr, str, name) \ -dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ +void do_##name(struct pt_regs *regs, long error_code) \ { \ + trace_hardirqs_fixup(); \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ - conditional_sti(regs); \ - do_trap(trapnr, signr, str, regs, error_code, NULL); \ + do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ } -#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ -dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ +#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \ +void do_##name(struct pt_regs *regs, long error_code) \ { \ siginfo_t info; \ + if (irq) \ + local_irq_enable(); \ info.si_signo = signr; \ info.si_errno = 0; \ info.si_code = sicode; \ @@ -253,68 +545,90 @@ dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ - conditional_sti(regs); \ - do_trap(trapnr, signr, str, regs, error_code, &info); \ + do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ } -DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) -DO_ERROR(4, SIGSEGV, "overflow", overflow) -DO_ERROR(5, SIGSEGV, "bounds", bounds) -DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip) -DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) -DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) -DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) -#ifdef CONFIG_X86_32 -DO_ERROR(12, SIGBUS, "stack segment", stack_segment) -#endif -DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) - -#ifdef CONFIG_X86_64 -/* Runs on IST stack */ -dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) -{ - if (notify_die(DIE_TRAP, "stack segment", regs, error_code, - 12, SIGBUS) == NOTIFY_STOP) - return; - preempt_conditional_sti(regs); - do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); - preempt_conditional_cli(regs); +#define DO_VM86_ERROR(trapnr, signr, str, name) \ +void do_##name(struct pt_regs *regs, long error_code) \ +{ \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ + == NOTIFY_STOP) \ + return; \ + do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ } -dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) -{ - static const char str[] = "double fault"; - struct task_struct *tsk = current; - - /* Return not checked because double check cannot be ignored */ - notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV); - - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 8; - - /* This is always a kernel trap and never fixable (and thus must - never return). */ - for (;;) - die(str, regs, error_code); +#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ +void do_##name(struct pt_regs *regs, long error_code) \ +{ \ + siginfo_t info; \ + info.si_signo = signr; \ + info.si_errno = 0; \ + info.si_code = sicode; \ + info.si_addr = (void __user *)siaddr; \ + trace_hardirqs_fixup(); \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ + == NOTIFY_STOP) \ + return; \ + do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ } + +DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) +#ifndef CONFIG_KPROBES +DO_VM86_ERROR(3, SIGTRAP, "int3", int3) #endif +DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) +DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds) +DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) +DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) +DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) +DO_ERROR(12, SIGBUS, "stack segment", stack_segment) +DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) +DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) -dotraplinkage void __kprobes +void __kprobes do_general_protection(struct pt_regs *regs, long error_code) { struct task_struct *tsk; + struct thread_struct *thread; + struct tss_struct *tss; + int cpu; - conditional_sti(regs); + cpu = get_cpu(); + tss = &per_cpu(init_tss, cpu); + thread = ¤t->thread; + + /* + * Perform the lazy TSS's I/O bitmap copy. If the TSS has an + * invalid offset set (the LAZY one) and the faulting thread has + * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS + * and we set the offset field correctly. Then we let the CPU to + * restart the faulting instruction. + */ + if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && + thread->io_bitmap_ptr) { + memcpy(tss->io_bitmap, thread->io_bitmap_ptr, + thread->io_bitmap_max); + /* + * If the previously set map was extending to higher ports + * than the current one, pad extra space with 0xff (no access). + */ + if (thread->io_bitmap_max < tss->io_bitmap_max) { + memset((char *) tss->io_bitmap + + thread->io_bitmap_max, 0xff, + tss->io_bitmap_max - thread->io_bitmap_max); + } + tss->io_bitmap_max = thread->io_bitmap_max; + tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; + tss->io_bitmap_owner = thread; + put_cpu(); -#ifdef CONFIG_X86_32 - if (lazy_iobitmap_copy()) { - /* restart the faulting instruction */ return; } + put_cpu(); if (regs->flags & X86_VM_MASK) goto gp_in_vm86; -#endif tsk = current; if (!user_mode(regs)) @@ -336,12 +650,10 @@ do_general_protection(struct pt_regs *regs, long error_code) force_sig(SIGSEGV, tsk); return; -#ifdef CONFIG_X86_32 gp_in_vm86: local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); return; -#endif gp_in_kernel: if (fixup_exception(regs)) @@ -378,8 +690,7 @@ mem_parity_error(unsigned char reason, struct pt_regs *regs) printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); /* Clear and disable the memory parity error line. */ - reason = (reason & 0xf) | 4; - outb(reason, 0x61); + clear_mem_error(reason); } static notrace __kprobes void @@ -405,8 +716,7 @@ io_check_error(unsigned char reason, struct pt_regs *regs) static notrace __kprobes void unknown_nmi_error(unsigned char reason, struct pt_regs *regs) { - if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == - NOTIFY_STOP) + if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) return; #ifdef CONFIG_MCA /* @@ -429,6 +739,41 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs) printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); } +static DEFINE_SPINLOCK(nmi_print_lock); + +void notrace __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) +{ + if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP) + return; + + spin_lock(&nmi_print_lock); + /* + * We are in trouble anyway, lets at least try + * to get a message out: + */ + bust_spinlocks(1); + printk(KERN_EMERG "%s", str); + printk(" on CPU%d, ip %08lx, registers:\n", + smp_processor_id(), regs->ip); + show_registers(regs); + if (do_panic) + panic("Non maskable interrupt"); + console_silent(); + spin_unlock(&nmi_print_lock); + bust_spinlocks(0); + + /* + * If we are in kernel we are probably nested up pretty bad + * and might aswell get out now while we still can: + */ + if (!user_mode_vm(regs)) { + current->thread.trap_no = 2; + crash_kexec(regs); + } + + do_exit(SIGSEGV); +} + static notrace __kprobes void default_do_nmi(struct pt_regs *regs) { unsigned char reason = 0; @@ -467,25 +812,22 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) mem_parity_error(reason, regs); if (reason & 0x40) io_check_error(reason, regs); -#ifdef CONFIG_X86_32 /* * Reassert NMI in case it became active meanwhile * as it's edge-triggered: */ reassert_nmi(); -#endif } -dotraplinkage notrace __kprobes void -do_nmi(struct pt_regs *regs, long error_code) +notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) { + int cpu; + nmi_enter(); -#ifdef CONFIG_X86_32 - { int cpu; cpu = smp_processor_id(); ++nmi_count(cpu); } -#else - add_pda(__nmi_count, 1); -#endif + cpu = smp_processor_id(); + + ++nmi_count(cpu); if (!ignore_nmis) default_do_nmi(regs); @@ -505,44 +847,21 @@ void restart_nmi(void) acpi_nmi_enable(); } -/* May run on IST stack. */ -dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) -{ #ifdef CONFIG_KPROBES +void __kprobes do_int3(struct pt_regs *regs, long error_code) +{ + trace_hardirqs_fixup(); + if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) return; -#else - if (notify_die(DIE_TRAP, "int3", regs, error_code, 3, SIGTRAP) - == NOTIFY_STOP) - return; -#endif - - preempt_conditional_sti(regs); - do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); - preempt_conditional_cli(regs); -} + /* + * This is an interrupt gate, because kprobes wants interrupts + * disabled. Normal trap handlers don't. + */ + restore_interrupts(regs); -#ifdef CONFIG_X86_64 -/* Help handler running on IST stack to switch back to user stack - for scheduling or signal handling. The actual stack switch is done in - entry.S */ -asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) -{ - struct pt_regs *regs = eregs; - /* Did already sync */ - if (eregs == (struct pt_regs *)eregs->sp) - ; - /* Exception from user space */ - else if (user_mode(eregs)) - regs = task_pt_regs(current); - /* Exception from kernel and interrupts are enabled. Move to - kernel process stack. */ - else if (eregs->flags & X86_EFLAGS_IF) - regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); - if (eregs != regs) - *regs = *eregs; - return regs; + do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); } #endif @@ -567,15 +886,15 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) * about restoring all the debug state, and ptrace doesn't have to * find every occurrence of the TF bit that could be saved away even * by user code) - * - * May run on IST stack. */ -dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) +void __kprobes do_debug(struct pt_regs *regs, long error_code) { struct task_struct *tsk = current; - unsigned long condition; + unsigned int condition; int si_code; + trace_hardirqs_fixup(); + get_debugreg(condition, 6); /* @@ -587,9 +906,9 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, SIGTRAP) == NOTIFY_STOP) return; - /* It's safe to allow irq's after DR6 has been saved */ - preempt_conditional_sti(regs); + if (regs->flags & X86_EFLAGS_IF) + local_irq_enable(); /* Mask out spurious debug traps due to lazy DR7 setting */ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { @@ -597,10 +916,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) goto clear_dr7; } -#ifdef CONFIG_X86_32 if (regs->flags & X86_VM_MASK) goto debug_vm86; -#endif /* Save debug status register where ptrace can see it */ tsk->thread.debugreg6 = condition; @@ -610,11 +927,16 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) * kernel space (but re-enable TF when returning to user mode). */ if (condition & DR_STEP) { + /* + * We already checked v86 mode above, so we can + * check for kernel mode by just checking the CPL + * of CS. + */ if (!user_mode(regs)) goto clear_TF_reenable; } - si_code = get_si_code(condition); + si_code = get_si_code((unsigned long)condition); /* Ok, finally something we can handle */ send_sigtrap(tsk, regs, error_code, si_code); @@ -624,37 +946,18 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) */ clear_dr7: set_debugreg(0, 7); - preempt_conditional_cli(regs); return; -#ifdef CONFIG_X86_32 debug_vm86: handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - preempt_conditional_cli(regs); return; -#endif clear_TF_reenable: set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs->flags &= ~X86_EFLAGS_TF; - preempt_conditional_cli(regs); return; } -#ifdef CONFIG_X86_64 -static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) -{ - if (fixup_exception(regs)) - return 1; - - notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE); - /* Illegal floating point operation in the kernel */ - current->thread.trap_no = trapnr; - die(str, regs, 0); - return 0; -} -#endif - /* * Note that we play around with the 'TS' bit in an attempt to get * the correct behaviour even in the presence of the asynchronous @@ -691,9 +994,7 @@ void math_error(void __user *ip) swd = get_fpu_swd(task); switch (swd & ~cwd & 0x3f) { case 0x000: /* No unmasked exception */ -#ifdef CONFIG_X86_32 return; -#endif default: /* Multiple exceptions */ break; case 0x001: /* Invalid Op */ @@ -721,18 +1022,9 @@ void math_error(void __user *ip) force_sig_info(SIGFPE, &info, task); } -dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) +void do_coprocessor_error(struct pt_regs *regs, long error_code) { - conditional_sti(regs); - -#ifdef CONFIG_X86_32 ignore_fpu_irq = 1; -#else - if (!user_mode(regs) && - kernel_math_error(regs, "kernel x87 math error", 16)) - return; -#endif - math_error((void __user *)regs->ip); } @@ -784,12 +1076,8 @@ static void simd_math_error(void __user *ip) force_sig_info(SIGFPE, &info, task); } -dotraplinkage void -do_simd_coprocessor_error(struct pt_regs *regs, long error_code) +void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) { - conditional_sti(regs); - -#ifdef CONFIG_X86_32 if (cpu_has_xmm) { /* Handle SIMD FPU exceptions on PIII+ processors. */ ignore_fpu_irq = 1; @@ -808,25 +1096,16 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code) current->thread.error_code = error_code; die_if_kernel("cache flush denied", regs, error_code); force_sig(SIGSEGV, current); -#else - if (!user_mode(regs) && - kernel_math_error(regs, "kernel simd math error", 19)) - return; - simd_math_error((void __user *)regs->ip); -#endif } -dotraplinkage void -do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) +void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) { - conditional_sti(regs); #if 0 /* No need to warn about this any longer. */ printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); #endif } -#ifdef CONFIG_X86_32 unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) { struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id()); @@ -845,15 +1124,6 @@ unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) return new_kesp; } -#else -asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) -{ -} - -asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void) -{ -} -#endif /* * 'math_state_restore()' saves the current math information in the @@ -886,24 +1156,14 @@ asmlinkage void math_state_restore(void) } clts(); /* Allow maths ops (or we recurse) */ -#ifdef CONFIG_X86_32 restore_fpu(tsk); -#else - /* - * Paranoid restore. send a SIGSEGV if we fail to restore the state. - */ - if (unlikely(restore_fpu_checking(tsk))) { - stts(); - force_sig(SIGSEGV, tsk); - return; - } -#endif thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ tsk->fpu_counter++; } EXPORT_SYMBOL_GPL(math_state_restore); #ifndef CONFIG_MATH_EMULATION + asmlinkage void math_emulate(long arg) { printk(KERN_EMERG @@ -912,54 +1172,12 @@ asmlinkage void math_emulate(long arg) force_sig(SIGFPE, current); schedule(); } -#endif /* CONFIG_MATH_EMULATION */ - -dotraplinkage void __kprobes -do_device_not_available(struct pt_regs *regs, long error) -{ -#ifdef CONFIG_X86_32 - if (read_cr0() & X86_CR0_EM) { - conditional_sti(regs); - math_emulate(0); - } else { - math_state_restore(); /* interrupts still off */ - conditional_sti(regs); - } -#else - math_state_restore(); -#endif -} - -#ifdef CONFIG_X86_32 -#ifdef CONFIG_X86_MCE -dotraplinkage void __kprobes do_machine_check(struct pt_regs *regs, long error) -{ - conditional_sti(regs); - machine_check_vector(regs, error); -} -#endif - -dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) -{ - siginfo_t info; - local_irq_enable(); - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_code = ILL_BADSTK; - info.si_addr = 0; - if (notify_die(DIE_TRAP, "iret exception", - regs, error_code, 32, SIGILL) == NOTIFY_STOP) - return; - do_trap(32, SIGILL, "iret exception", regs, error_code, &info); -} -#endif +#endif /* CONFIG_MATH_EMULATION */ void __init trap_init(void) { -#ifdef CONFIG_X86_32 int i; -#endif #ifdef CONFIG_EISA void __iomem *p = early_ioremap(0x0FFFD9, 4); @@ -969,40 +1187,29 @@ void __init trap_init(void) early_iounmap(p, 4); #endif - set_intr_gate(0, ÷_error); - set_intr_gate_ist(1, &debug, DEBUG_STACK); - set_intr_gate_ist(2, &nmi, NMI_STACK); - /* int3 can be called from all */ - set_system_intr_gate_ist(3, &int3, DEBUG_STACK); - /* int4 can be called from all */ - set_system_intr_gate(4, &overflow); - set_intr_gate(5, &bounds); - set_intr_gate(6, &invalid_op); - set_intr_gate(7, &device_not_available); -#ifdef CONFIG_X86_32 + set_trap_gate(0, ÷_error); + set_intr_gate(1, &debug); + set_intr_gate(2, &nmi); + set_system_intr_gate(3, &int3); /* int3 can be called from all */ + set_system_gate(4, &overflow); /* int4 can be called from all */ + set_trap_gate(5, &bounds); + set_trap_gate(6, &invalid_op); + set_trap_gate(7, &device_not_available); set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); -#else - set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK); -#endif - set_intr_gate(9, &coprocessor_segment_overrun); - set_intr_gate(10, &invalid_TSS); - set_intr_gate(11, &segment_not_present); - set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); - set_intr_gate(13, &general_protection); + set_trap_gate(9, &coprocessor_segment_overrun); + set_trap_gate(10, &invalid_TSS); + set_trap_gate(11, &segment_not_present); + set_trap_gate(12, &stack_segment); + set_trap_gate(13, &general_protection); set_intr_gate(14, &page_fault); - set_intr_gate(15, &spurious_interrupt_bug); - set_intr_gate(16, &coprocessor_error); - set_intr_gate(17, &alignment_check); + set_trap_gate(15, &spurious_interrupt_bug); + set_trap_gate(16, &coprocessor_error); + set_trap_gate(17, &alignment_check); #ifdef CONFIG_X86_MCE - set_intr_gate_ist(18, &machine_check, MCE_STACK); + set_trap_gate(18, &machine_check); #endif - set_intr_gate(19, &simd_coprocessor_error); + set_trap_gate(19, &simd_coprocessor_error); -#ifdef CONFIG_IA32_EMULATION - set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall); -#endif - -#ifdef CONFIG_X86_32 if (cpu_has_fxsr) { printk(KERN_INFO "Enabling fast FPU save and restore... "); set_in_cr4(X86_CR4_OSFXSR); @@ -1015,20 +1222,36 @@ void __init trap_init(void) printk("done.\n"); } - set_system_trap_gate(SYSCALL_VECTOR, &system_call); + set_system_gate(SYSCALL_VECTOR, &system_call); /* Reserve all the builtin and the syscall vector: */ for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) set_bit(i, used_vectors); set_bit(SYSCALL_VECTOR, used_vectors); -#endif + /* * Should be a barrier for any external CPU state: */ cpu_init(); -#ifdef CONFIG_X86_32 trap_init_hook(); -#endif } + +static int __init kstack_setup(char *s) +{ + kstack_depth_to_print = simple_strtoul(s, NULL, 0); + + return 1; +} +__setup("kstack=", kstack_setup); + +static int __init code_bytes_setup(char *s) +{ + code_bytes = simple_strtoul(s, NULL, 0); + if (code_bytes > 8192) + code_bytes = 8192; + + return 1; +} +__setup("code_bytes=", code_bytes_setup); diff --git a/trunk/arch/x86/kernel/traps_64.c b/trunk/arch/x86/kernel/traps_64.c new file mode 100644 index 000000000000..9c0ac0cab013 --- /dev/null +++ b/trunk/arch/x86/kernel/traps_64.c @@ -0,0 +1,1214 @@ +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + */ + +/* + * 'Traps.c' handles hardware traps and faults after we have saved some + * state in 'entry.S'. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_EDAC) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int panic_on_unrecovered_nmi; +int kstack_depth_to_print = 12; +static unsigned int code_bytes = 64; +static int ignore_nmis; +static int die_counter; + +static inline void conditional_sti(struct pt_regs *regs) +{ + if (regs->flags & X86_EFLAGS_IF) + local_irq_enable(); +} + +static inline void preempt_conditional_sti(struct pt_regs *regs) +{ + inc_preempt_count(); + if (regs->flags & X86_EFLAGS_IF) + local_irq_enable(); +} + +static inline void preempt_conditional_cli(struct pt_regs *regs) +{ + if (regs->flags & X86_EFLAGS_IF) + local_irq_disable(); + /* Make sure to not schedule here because we could be running + on an exception stack. */ + dec_preempt_count(); +} + +void printk_address(unsigned long address, int reliable) +{ + printk(" [<%016lx>] %s%pS\n", + address, reliable ? "" : "? ", (void *) address); +} + +static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, + unsigned *usedp, char **idp) +{ + static char ids[][8] = { + [DEBUG_STACK - 1] = "#DB", + [NMI_STACK - 1] = "NMI", + [DOUBLEFAULT_STACK - 1] = "#DF", + [STACKFAULT_STACK - 1] = "#SS", + [MCE_STACK - 1] = "#MC", +#if DEBUG_STKSZ > EXCEPTION_STKSZ + [N_EXCEPTION_STACKS ... + N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" +#endif + }; + unsigned k; + + /* + * Iterate over all exception stacks, and figure out whether + * 'stack' is in one of them: + */ + for (k = 0; k < N_EXCEPTION_STACKS; k++) { + unsigned long end = per_cpu(orig_ist, cpu).ist[k]; + /* + * Is 'stack' above this exception frame's end? + * If yes then skip to the next frame. + */ + if (stack >= end) + continue; + /* + * Is 'stack' above this exception frame's start address? + * If yes then we found the right frame. + */ + if (stack >= end - EXCEPTION_STKSZ) { + /* + * Make sure we only iterate through an exception + * stack once. If it comes up for the second time + * then there's something wrong going on - just + * break out and return NULL: + */ + if (*usedp & (1U << k)) + break; + *usedp |= 1U << k; + *idp = ids[k]; + return (unsigned long *)end; + } + /* + * If this is a debug stack, and if it has a larger size than + * the usual exception stacks, then 'stack' might still + * be within the lower portion of the debug stack: + */ +#if DEBUG_STKSZ > EXCEPTION_STKSZ + if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) { + unsigned j = N_EXCEPTION_STACKS - 1; + + /* + * Black magic. A large debug stack is composed of + * multiple exception stack entries, which we + * iterate through now. Dont look: + */ + do { + ++j; + end -= EXCEPTION_STKSZ; + ids[j][4] = '1' + (j - N_EXCEPTION_STACKS); + } while (stack < end - EXCEPTION_STKSZ); + if (*usedp & (1U << j)) + break; + *usedp |= 1U << j; + *idp = ids[j]; + return (unsigned long *)end; + } +#endif + } + return NULL; +} + +/* + * x86-64 can have up to three kernel stacks: + * process stack + * interrupt stack + * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack + */ + +static inline int valid_stack_ptr(struct thread_info *tinfo, + void *p, unsigned int size, void *end) +{ + void *t = tinfo; + if (end) { + if (p < end && p >= (end-THREAD_SIZE)) + return 1; + else + return 0; + } + return p > t && p < t + THREAD_SIZE - size; +} + +/* The form of the top of the frame on the stack */ +struct stack_frame { + struct stack_frame *next_frame; + unsigned long return_address; +}; + +static inline unsigned long +print_context_stack(struct thread_info *tinfo, + unsigned long *stack, unsigned long bp, + const struct stacktrace_ops *ops, void *data, + unsigned long *end) +{ + struct stack_frame *frame = (struct stack_frame *)bp; + + while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) { + unsigned long addr; + + addr = *stack; + if (__kernel_text_address(addr)) { + if ((unsigned long) stack == bp + 8) { + ops->address(data, addr, 1); + frame = frame->next_frame; + bp = (unsigned long) frame; + } else { + ops->address(data, addr, bp == 0); + } + } + stack++; + } + return bp; +} + +void dump_trace(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp, + const struct stacktrace_ops *ops, void *data) +{ + const unsigned cpu = get_cpu(); + unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; + unsigned used = 0; + struct thread_info *tinfo; + + if (!task) + task = current; + + if (!stack) { + unsigned long dummy; + stack = &dummy; + if (task && task != current) + stack = (unsigned long *)task->thread.sp; + } + +#ifdef CONFIG_FRAME_POINTER + if (!bp) { + if (task == current) { + /* Grab bp right from our regs */ + asm("movq %%rbp, %0" : "=r" (bp) : ); + } else { + /* bp is the last reg pushed by switch_to */ + bp = *(unsigned long *) task->thread.sp; + } + } +#endif + + /* + * Print function call entries in all stacks, starting at the + * current stack address. If the stacks consist of nested + * exceptions + */ + tinfo = task_thread_info(task); + for (;;) { + char *id; + unsigned long *estack_end; + estack_end = in_exception_stack(cpu, (unsigned long)stack, + &used, &id); + + if (estack_end) { + if (ops->stack(data, id) < 0) + break; + + bp = print_context_stack(tinfo, stack, bp, ops, + data, estack_end); + ops->stack(data, ""); + /* + * We link to the next stack via the + * second-to-last pointer (index -2 to end) in the + * exception stack: + */ + stack = (unsigned long *) estack_end[-2]; + continue; + } + if (irqstack_end) { + unsigned long *irqstack; + irqstack = irqstack_end - + (IRQSTACKSIZE - 64) / sizeof(*irqstack); + + if (stack >= irqstack && stack < irqstack_end) { + if (ops->stack(data, "IRQ") < 0) + break; + bp = print_context_stack(tinfo, stack, bp, + ops, data, irqstack_end); + /* + * We link to the next stack (which would be + * the process stack normally) the last + * pointer (index -1 to end) in the IRQ stack: + */ + stack = (unsigned long *) (irqstack_end[-1]); + irqstack_end = NULL; + ops->stack(data, "EOI"); + continue; + } + } + break; + } + + /* + * This handles the process stack: + */ + bp = print_context_stack(tinfo, stack, bp, ops, data, NULL); + put_cpu(); +} +EXPORT_SYMBOL(dump_trace); + +static void +print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) +{ + print_symbol(msg, symbol); + printk("\n"); +} + +static void print_trace_warning(void *data, char *msg) +{ + printk("%s\n", msg); +} + +static int print_trace_stack(void *data, char *name) +{ + printk(" <%s> ", name); + return 0; +} + +static void print_trace_address(void *data, unsigned long addr, int reliable) +{ + touch_nmi_watchdog(); + printk_address(addr, reliable); +} + +static const struct stacktrace_ops print_trace_ops = { + .warning = print_trace_warning, + .warning_symbol = print_trace_warning_symbol, + .stack = print_trace_stack, + .address = print_trace_address, +}; + +static void +show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp, char *log_lvl) +{ + printk("Call Trace:\n"); + dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); +} + +void show_trace(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp) +{ + show_trace_log_lvl(task, regs, stack, bp, ""); +} + +static void +show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *sp, unsigned long bp, char *log_lvl) +{ + unsigned long *stack; + int i; + const int cpu = smp_processor_id(); + unsigned long *irqstack_end = + (unsigned long *) (cpu_pda(cpu)->irqstackptr); + unsigned long *irqstack = + (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); + + /* + * debugging aid: "show_stack(NULL, NULL);" prints the + * back trace for this cpu. + */ + + if (sp == NULL) { + if (task) + sp = (unsigned long *)task->thread.sp; + else + sp = (unsigned long *)&sp; + } + + stack = sp; + for (i = 0; i < kstack_depth_to_print; i++) { + if (stack >= irqstack && stack <= irqstack_end) { + if (stack == irqstack_end) { + stack = (unsigned long *) (irqstack_end[-1]); + printk(" "); + } + } else { + if (((long) stack & (THREAD_SIZE-1)) == 0) + break; + } + if (i && ((i % 4) == 0)) + printk("\n"); + printk(" %016lx", *stack++); + touch_nmi_watchdog(); + } + printk("\n"); + show_trace_log_lvl(task, regs, sp, bp, log_lvl); +} + +void show_stack(struct task_struct *task, unsigned long *sp) +{ + show_stack_log_lvl(task, NULL, sp, 0, ""); +} + +/* + * The architecture-independent dump_stack generator + */ +void dump_stack(void) +{ + unsigned long bp = 0; + unsigned long stack; + +#ifdef CONFIG_FRAME_POINTER + if (!bp) + asm("movq %%rbp, %0" : "=r" (bp) : ); +#endif + + printk("Pid: %d, comm: %.20s %s %s %.*s\n", + current->pid, current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + show_trace(NULL, NULL, &stack, bp); +} +EXPORT_SYMBOL(dump_stack); + +void show_registers(struct pt_regs *regs) +{ + int i; + unsigned long sp; + const int cpu = smp_processor_id(); + struct task_struct *cur = cpu_pda(cpu)->pcurrent; + + sp = regs->sp; + printk("CPU %d ", cpu); + __show_regs(regs); + printk("Process %s (pid: %d, threadinfo %p, task %p)\n", + cur->comm, cur->pid, task_thread_info(cur), cur); + + /* + * When in-kernel, we also print out the stack and code at the + * time of the fault.. + */ + if (!user_mode(regs)) { + unsigned int code_prologue = code_bytes * 43 / 64; + unsigned int code_len = code_bytes; + unsigned char c; + u8 *ip; + + printk("Stack: "); + show_stack_log_lvl(NULL, regs, (unsigned long *)sp, + regs->bp, ""); + + printk(KERN_EMERG "Code: "); + + ip = (u8 *)regs->ip - code_prologue; + if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { + /* try starting at RIP */ + ip = (u8 *)regs->ip; + code_len = code_len - code_prologue + 1; + } + for (i = 0; i < code_len; i++, ip++) { + if (ip < (u8 *)PAGE_OFFSET || + probe_kernel_address(ip, c)) { + printk(" Bad RIP value."); + break; + } + if (ip == (u8 *)regs->ip) + printk("<%02x> ", c); + else + printk("%02x ", c); + } + } + printk("\n"); +} + +int is_valid_bugaddr(unsigned long ip) +{ + unsigned short ud2; + + if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2))) + return 0; + + return ud2 == 0x0b0f; +} + +static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; +static int die_owner = -1; +static unsigned int die_nest_count; + +unsigned __kprobes long oops_begin(void) +{ + int cpu; + unsigned long flags; + + oops_enter(); + + /* racy, but better than risking deadlock. */ + raw_local_irq_save(flags); + cpu = smp_processor_id(); + if (!__raw_spin_trylock(&die_lock)) { + if (cpu == die_owner) + /* nested oops. should stop eventually */; + else + __raw_spin_lock(&die_lock); + } + die_nest_count++; + die_owner = cpu; + console_verbose(); + bust_spinlocks(1); + return flags; +} + +void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) +{ + die_owner = -1; + bust_spinlocks(0); + die_nest_count--; + if (!die_nest_count) + /* Nest count reaches zero, release the lock. */ + __raw_spin_unlock(&die_lock); + raw_local_irq_restore(flags); + if (!regs) { + oops_exit(); + return; + } + if (panic_on_oops) + panic("Fatal exception"); + oops_exit(); + do_exit(signr); +} + +int __kprobes __die(const char *str, struct pt_regs *regs, long err) +{ + printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff, ++die_counter); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); +#endif +#ifdef CONFIG_SMP + printk("SMP "); +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC"); +#endif + printk("\n"); + if (notify_die(DIE_OOPS, str, regs, err, + current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) + return 1; + + show_registers(regs); + add_taint(TAINT_DIE); + /* Executive summary in case the oops scrolled away */ + printk(KERN_ALERT "RIP "); + printk_address(regs->ip, 1); + printk(" RSP <%016lx>\n", regs->sp); + if (kexec_should_crash(current)) + crash_kexec(regs); + return 0; +} + +void die(const char *str, struct pt_regs *regs, long err) +{ + unsigned long flags = oops_begin(); + + if (!user_mode(regs)) + report_bug(regs->ip, regs); + + if (__die(str, regs, err)) + regs = NULL; + oops_end(flags, regs, SIGSEGV); +} + +notrace __kprobes void +die_nmi(char *str, struct pt_regs *regs, int do_panic) +{ + unsigned long flags; + + if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP) + return; + + flags = oops_begin(); + /* + * We are in trouble anyway, lets at least try + * to get a message out. + */ + printk(KERN_EMERG "%s", str); + printk(" on CPU%d, ip %08lx, registers:\n", + smp_processor_id(), regs->ip); + show_registers(regs); + if (kexec_should_crash(current)) + crash_kexec(regs); + if (do_panic || panic_on_oops) + panic("Non maskable interrupt"); + oops_end(flags, NULL, SIGBUS); + nmi_exit(); + local_irq_enable(); + do_exit(SIGBUS); +} + +static void __kprobes +do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, + long error_code, siginfo_t *info) +{ + struct task_struct *tsk = current; + + if (!user_mode(regs)) + goto kernel_trap; + + /* + * We want error_code and trap_no set for userspace faults and + * kernelspace faults which result in die(), but not + * kernelspace faults which are fixed up. die() gives the + * process no chance to handle the signal and notice the + * kernel fault information, so that won't result in polluting + * the information about previously queued, but not yet + * delivered, faults. See also do_general_protection below. + */ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + + if (show_unhandled_signals && unhandled_signal(tsk, signr) && + printk_ratelimit()) { + printk(KERN_INFO + "%s[%d] trap %s ip:%lx sp:%lx error:%lx", + tsk->comm, tsk->pid, str, + regs->ip, regs->sp, error_code); + print_vma_addr(" in ", regs->ip); + printk("\n"); + } + + if (info) + force_sig_info(signr, info, tsk); + else + force_sig(signr, tsk); + return; + +kernel_trap: + if (!fixup_exception(regs)) { + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + die(str, regs, error_code); + } + return; +} + +#define DO_ERROR(trapnr, signr, str, name) \ +asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ +{ \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ + == NOTIFY_STOP) \ + return; \ + conditional_sti(regs); \ + do_trap(trapnr, signr, str, regs, error_code, NULL); \ +} + +#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ +asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ +{ \ + siginfo_t info; \ + info.si_signo = signr; \ + info.si_errno = 0; \ + info.si_code = sicode; \ + info.si_addr = (void __user *)siaddr; \ + trace_hardirqs_fixup(); \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ + == NOTIFY_STOP) \ + return; \ + conditional_sti(regs); \ + do_trap(trapnr, signr, str, regs, error_code, &info); \ +} + +DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) +DO_ERROR(4, SIGSEGV, "overflow", overflow) +DO_ERROR(5, SIGSEGV, "bounds", bounds) +DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip) +DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) +DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) +DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) + +/* Runs on IST stack */ +asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code) +{ + if (notify_die(DIE_TRAP, "stack segment", regs, error_code, + 12, SIGBUS) == NOTIFY_STOP) + return; + preempt_conditional_sti(regs); + do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); + preempt_conditional_cli(regs); +} + +asmlinkage void do_double_fault(struct pt_regs *regs, long error_code) +{ + static const char str[] = "double fault"; + struct task_struct *tsk = current; + + /* Return not checked because double check cannot be ignored */ + notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV); + + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 8; + + /* This is always a kernel trap and never fixable (and thus must + never return). */ + for (;;) + die(str, regs, error_code); +} + +asmlinkage void __kprobes +do_general_protection(struct pt_regs *regs, long error_code) +{ + struct task_struct *tsk; + + conditional_sti(regs); + + tsk = current; + if (!user_mode(regs)) + goto gp_in_kernel; + + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + + if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && + printk_ratelimit()) { + printk(KERN_INFO + "%s[%d] general protection ip:%lx sp:%lx error:%lx", + tsk->comm, tsk->pid, + regs->ip, regs->sp, error_code); + print_vma_addr(" in ", regs->ip); + printk("\n"); + } + + force_sig(SIGSEGV, tsk); + return; + +gp_in_kernel: + if (fixup_exception(regs)) + return; + + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + if (notify_die(DIE_GPF, "general protection fault", regs, + error_code, 13, SIGSEGV) == NOTIFY_STOP) + return; + die("general protection fault", regs, error_code); +} + +static notrace __kprobes void +mem_parity_error(unsigned char reason, struct pt_regs *regs) +{ + printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", + reason); + printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); + +#if defined(CONFIG_EDAC) + if (edac_handler_set()) { + edac_atomic_assert_error(); + return; + } +#endif + + if (panic_on_unrecovered_nmi) + panic("NMI: Not continuing"); + + printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); + + /* Clear and disable the memory parity error line. */ + reason = (reason & 0xf) | 4; + outb(reason, 0x61); +} + +static notrace __kprobes void +io_check_error(unsigned char reason, struct pt_regs *regs) +{ + printk("NMI: IOCK error (debug interrupt?)\n"); + show_registers(regs); + + /* Re-enable the IOCK line, wait for a few seconds */ + reason = (reason & 0xf) | 8; + outb(reason, 0x61); + mdelay(2000); + reason &= ~8; + outb(reason, 0x61); +} + +static notrace __kprobes void +unknown_nmi_error(unsigned char reason, struct pt_regs *regs) +{ + if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == + NOTIFY_STOP) + return; + printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", + reason); + printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); + + if (panic_on_unrecovered_nmi) + panic("NMI: Not continuing"); + + printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); +} + +/* Runs on IST stack. This code must keep interrupts off all the time. + Nested NMIs are prevented by the CPU. */ +asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) +{ + unsigned char reason = 0; + int cpu; + + cpu = smp_processor_id(); + + /* Only the BSP gets external NMIs from the system. */ + if (!cpu) + reason = get_nmi_reason(); + + if (!(reason & 0xc0)) { + if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) + return; + /* + * Ok, so this is none of the documented NMI sources, + * so it must be the NMI watchdog. + */ + if (nmi_watchdog_tick(regs, reason)) + return; + if (!do_nmi_callback(regs, cpu)) + unknown_nmi_error(reason, regs); + + return; + } + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) + return; + + /* AK: following checks seem to be broken on modern chipsets. FIXME */ + if (reason & 0x80) + mem_parity_error(reason, regs); + if (reason & 0x40) + io_check_error(reason, regs); +} + +asmlinkage notrace __kprobes void +do_nmi(struct pt_regs *regs, long error_code) +{ + nmi_enter(); + + add_pda(__nmi_count, 1); + + if (!ignore_nmis) + default_do_nmi(regs); + + nmi_exit(); +} + +void stop_nmi(void) +{ + acpi_nmi_disable(); + ignore_nmis++; +} + +void restart_nmi(void) +{ + ignore_nmis--; + acpi_nmi_enable(); +} + +/* runs on IST stack. */ +asmlinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) +{ + trace_hardirqs_fixup(); + + if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) + == NOTIFY_STOP) + return; + + preempt_conditional_sti(regs); + do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); + preempt_conditional_cli(regs); +} + +/* Help handler running on IST stack to switch back to user stack + for scheduling or signal handling. The actual stack switch is done in + entry.S */ +asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) +{ + struct pt_regs *regs = eregs; + /* Did already sync */ + if (eregs == (struct pt_regs *)eregs->sp) + ; + /* Exception from user space */ + else if (user_mode(eregs)) + regs = task_pt_regs(current); + /* Exception from kernel and interrupts are enabled. Move to + kernel process stack. */ + else if (eregs->flags & X86_EFLAGS_IF) + regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); + if (eregs != regs) + *regs = *eregs; + return regs; +} + +/* runs on IST stack. */ +asmlinkage void __kprobes do_debug(struct pt_regs *regs, + unsigned long error_code) +{ + struct task_struct *tsk = current; + unsigned long condition; + siginfo_t info; + + trace_hardirqs_fixup(); + + get_debugreg(condition, 6); + + /* + * The processor cleared BTF, so don't mark that we need it set. + */ + clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR); + tsk->thread.debugctlmsr = 0; + + if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, + SIGTRAP) == NOTIFY_STOP) + return; + + preempt_conditional_sti(regs); + + /* Mask out spurious debug traps due to lazy DR7 setting */ + if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { + if (!tsk->thread.debugreg7) + goto clear_dr7; + } + + tsk->thread.debugreg6 = condition; + + /* + * Single-stepping through TF: make sure we ignore any events in + * kernel space (but re-enable TF when returning to user mode). + */ + if (condition & DR_STEP) { + if (!user_mode(regs)) + goto clear_TF_reenable; + } + + /* Ok, finally something we can handle */ + tsk->thread.trap_no = 1; + tsk->thread.error_code = error_code; + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = get_si_code(condition); + info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL; + force_sig_info(SIGTRAP, &info, tsk); + +clear_dr7: + set_debugreg(0, 7); + preempt_conditional_cli(regs); + return; + +clear_TF_reenable: + set_tsk_thread_flag(tsk, TIF_SINGLESTEP); + regs->flags &= ~X86_EFLAGS_TF; + preempt_conditional_cli(regs); + return; +} + +static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) +{ + if (fixup_exception(regs)) + return 1; + + notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE); + /* Illegal floating point operation in the kernel */ + current->thread.trap_no = trapnr; + die(str, regs, 0); + return 0; +} + +/* + * Note that we play around with the 'TS' bit in an attempt to get + * the correct behaviour even in the presence of the asynchronous + * IRQ13 behaviour + */ +asmlinkage void do_coprocessor_error(struct pt_regs *regs) +{ + void __user *ip = (void __user *)(regs->ip); + struct task_struct *task; + siginfo_t info; + unsigned short cwd, swd; + + conditional_sti(regs); + if (!user_mode(regs) && + kernel_math_error(regs, "kernel x87 math error", 16)) + return; + + /* + * Save the info for the exception handler and clear the error. + */ + task = current; + save_init_fpu(task); + task->thread.trap_no = 16; + task->thread.error_code = 0; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = __SI_FAULT; + info.si_addr = ip; + /* + * (~cwd & swd) will mask out exceptions that are not set to unmasked + * status. 0x3f is the exception bits in these regs, 0x200 is the + * C1 reg you need in case of a stack fault, 0x040 is the stack + * fault bit. We should only be taking one exception at a time, + * so if this combination doesn't produce any single exception, + * then we have a bad program that isn't synchronizing its FPU usage + * and it will suffer the consequences since we won't be able to + * fully reproduce the context of the exception + */ + cwd = get_fpu_cwd(task); + swd = get_fpu_swd(task); + switch (swd & ~cwd & 0x3f) { + case 0x000: /* No unmasked exception */ + default: /* Multiple exceptions */ + break; + case 0x001: /* Invalid Op */ + /* + * swd & 0x240 == 0x040: Stack Underflow + * swd & 0x240 == 0x240: Stack Overflow + * User must clear the SF bit (0x40) if set + */ + info.si_code = FPE_FLTINV; + break; + case 0x002: /* Denormalize */ + case 0x010: /* Underflow */ + info.si_code = FPE_FLTUND; + break; + case 0x004: /* Zero Divide */ + info.si_code = FPE_FLTDIV; + break; + case 0x008: /* Overflow */ + info.si_code = FPE_FLTOVF; + break; + case 0x020: /* Precision */ + info.si_code = FPE_FLTRES; + break; + } + force_sig_info(SIGFPE, &info, task); +} + +asmlinkage void bad_intr(void) +{ + printk("bad interrupt"); +} + +asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) +{ + void __user *ip = (void __user *)(regs->ip); + struct task_struct *task; + siginfo_t info; + unsigned short mxcsr; + + conditional_sti(regs); + if (!user_mode(regs) && + kernel_math_error(regs, "kernel simd math error", 19)) + return; + + /* + * Save the info for the exception handler and clear the error. + */ + task = current; + save_init_fpu(task); + task->thread.trap_no = 19; + task->thread.error_code = 0; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = __SI_FAULT; + info.si_addr = ip; + /* + * The SIMD FPU exceptions are handled a little differently, as there + * is only a single status/control register. Thus, to determine which + * unmasked exception was caught we must mask the exception mask bits + * at 0x1f80, and then use these to mask the exception bits at 0x3f. + */ + mxcsr = get_fpu_mxcsr(task); + switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) { + case 0x000: + default: + break; + case 0x001: /* Invalid Op */ + info.si_code = FPE_FLTINV; + break; + case 0x002: /* Denormalize */ + case 0x010: /* Underflow */ + info.si_code = FPE_FLTUND; + break; + case 0x004: /* Zero Divide */ + info.si_code = FPE_FLTDIV; + break; + case 0x008: /* Overflow */ + info.si_code = FPE_FLTOVF; + break; + case 0x020: /* Precision */ + info.si_code = FPE_FLTRES; + break; + } + force_sig_info(SIGFPE, &info, task); +} + +asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs) +{ +} + +asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) +{ +} + +asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void) +{ +} + +/* + * 'math_state_restore()' saves the current math information in the + * old math state array, and gets the new ones from the current task + * + * Careful.. There are problems with IBM-designed IRQ13 behaviour. + * Don't touch unless you *really* know how it works. + */ +asmlinkage void math_state_restore(void) +{ + struct task_struct *me = current; + + if (!used_math()) { + local_irq_enable(); + /* + * does a slab alloc which can sleep + */ + if (init_fpu(me)) { + /* + * ran out of memory! + */ + do_group_exit(SIGKILL); + return; + } + local_irq_disable(); + } + + clts(); /* Allow maths ops (or we recurse) */ + /* + * Paranoid restore. send a SIGSEGV if we fail to restore the state. + */ + if (unlikely(restore_fpu_checking(me))) { + stts(); + force_sig(SIGSEGV, me); + return; + } + task_thread_info(me)->status |= TS_USEDFPU; + me->fpu_counter++; +} +EXPORT_SYMBOL_GPL(math_state_restore); + +void __init trap_init(void) +{ + set_intr_gate(0, ÷_error); + set_intr_gate_ist(1, &debug, DEBUG_STACK); + set_intr_gate_ist(2, &nmi, NMI_STACK); + /* int3 can be called from all */ + set_system_gate_ist(3, &int3, DEBUG_STACK); + /* int4 can be called from all */ + set_system_gate(4, &overflow); + set_intr_gate(5, &bounds); + set_intr_gate(6, &invalid_op); + set_intr_gate(7, &device_not_available); + set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK); + set_intr_gate(9, &coprocessor_segment_overrun); + set_intr_gate(10, &invalid_TSS); + set_intr_gate(11, &segment_not_present); + set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); + set_intr_gate(13, &general_protection); + set_intr_gate(14, &page_fault); + set_intr_gate(15, &spurious_interrupt_bug); + set_intr_gate(16, &coprocessor_error); + set_intr_gate(17, &alignment_check); +#ifdef CONFIG_X86_MCE + set_intr_gate_ist(18, &machine_check, MCE_STACK); +#endif + set_intr_gate(19, &simd_coprocessor_error); + +#ifdef CONFIG_IA32_EMULATION + set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall); +#endif + /* + * Should be a barrier for any external CPU state: + */ + cpu_init(); +} + +static int __init oops_setup(char *s) +{ + if (!s) + return -EINVAL; + if (!strcmp(s, "panic")) + panic_on_oops = 1; + return 0; +} +early_param("oops", oops_setup); + +static int __init kstack_setup(char *s) +{ + if (!s) + return -EINVAL; + kstack_depth_to_print = simple_strtoul(s, NULL, 0); + return 0; +} +early_param("kstack", kstack_setup); + +static int __init code_bytes_setup(char *s) +{ + code_bytes = simple_strtoul(s, NULL, 0); + if (code_bytes > 8192) + code_bytes = 8192; + + return 1; +} +__setup("code_bytes=", code_bytes_setup); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 19afbb644c7f..0d682fc6aeb3 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -564,7 +564,7 @@ static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info * hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32); pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n", - __func__, tsc_khz, hv_clock->tsc_shift, + __FUNCTION__, tsc_khz, hv_clock->tsc_shift, hv_clock->tsc_to_system_mul); } diff --git a/trunk/arch/x86/mach-generic/es7000.c b/trunk/arch/x86/mach-generic/es7000.c index 6513d41ea21e..520cca0ee04e 100644 --- a/trunk/arch/x86/mach-generic/es7000.c +++ b/trunk/arch/x86/mach-generic/es7000.c @@ -47,26 +47,16 @@ static __init int mps_oem_check(struct mp_config_table *mpc, char *oem, /* Hook from generic ACPI tables.c */ static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - unsigned long oem_addr = 0; - int check_dsdt; - int ret = 0; - - /* check dsdt at first to avoid clear fix_map for oem_addr */ - check_dsdt = es7000_check_dsdt(); - + unsigned long oem_addr; if (!find_unisys_acpi_oem_table(&oem_addr)) { - if (check_dsdt) - ret = parse_unisys_oem((char *)oem_addr); + if (es7000_check_dsdt()) + return parse_unisys_oem((char *)oem_addr); else { setup_unisys(); - ret = 1; + return 1; } - /* - * we need to unmap it - */ - unmap_unisys_acpi_oem_table(oem_addr); } - return ret; + return 0; } #else static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) diff --git a/trunk/arch/x86/mm/Makefile b/trunk/arch/x86/mm/Makefile index 59f89b434b45..dfb932dcf136 100644 --- a/trunk/arch/x86/mm/Makefile +++ b/trunk/arch/x86/mm/Makefile @@ -13,8 +13,12 @@ obj-$(CONFIG_MMIOTRACE) += mmiotrace.o mmiotrace-y := pf_in.o mmio-mod.o obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o -obj-$(CONFIG_NUMA) += numa_$(BITS).o +ifeq ($(CONFIG_X86_32),y) +obj-$(CONFIG_NUMA) += discontig_32.o +else +obj-$(CONFIG_NUMA) += numa_64.o obj-$(CONFIG_K8_NUMA) += k8topology_64.o +endif obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o obj-$(CONFIG_MEMTEST) += memtest.o diff --git a/trunk/arch/x86/mm/numa_32.c b/trunk/arch/x86/mm/discontig_32.c similarity index 100% rename from trunk/arch/x86/mm/numa_32.c rename to trunk/arch/x86/mm/discontig_32.c diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index 3f2b8962cbd0..ac2ad781da00 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -592,6 +592,11 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) unsigned long flags; #endif + /* + * We can fault from pretty much anywhere, with unknown IRQ state. + */ + trace_hardirqs_fixup(); + tsk = current; mm = tsk->mm; prefetchw(&mm->mmap_sem); @@ -640,24 +645,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) } -#ifdef CONFIG_X86_32 - /* It's safe to allow irq's after cr2 has been saved and the vmalloc - fault has been handled. */ - if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK)) - local_irq_enable(); - /* - * If we're in an interrupt, have no user context or are running in an - * atomic region then we must not take the fault. + * It's safe to allow irq's after cr2 has been saved and the + * vmalloc fault has been handled. + * + * User-mode registers count as a user access even for any + * potential system fault or CPU buglet. */ - if (in_atomic() || !mm) - goto bad_area_nosemaphore; -#else /* CONFIG_X86_64 */ - if (likely(regs->flags & X86_EFLAGS_IF)) + if (user_mode_vm(regs)) { + local_irq_enable(); + error_code |= PF_USER; + } else if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); +#ifdef CONFIG_X86_64 if (unlikely(error_code & PF_RSVD)) pgtable_bad(address, regs, error_code); +#endif /* * If we're in an interrupt, have no user context or are running in an @@ -666,14 +670,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) if (unlikely(in_atomic() || !mm)) goto bad_area_nosemaphore; - /* - * User-mode registers count as a user access even for any - * potential system fault or CPU buglet. - */ - if (user_mode_vm(regs)) - error_code |= PF_USER; again: -#endif /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the * kernel and should generate an OOPS. Unfortunately, in the case of an diff --git a/trunk/arch/x86/mm/gup.c b/trunk/arch/x86/mm/gup.c index 4ba373c5b8c8..007bb06c7504 100644 --- a/trunk/arch/x86/mm/gup.c +++ b/trunk/arch/x86/mm/gup.c @@ -82,7 +82,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, pte_t pte = gup_get_pte(ptep); struct page *page; - if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) { + if ((pte_val(pte) & (mask | _PAGE_SPECIAL)) != mask) { pte_unmap(ptep); return 0; } @@ -116,10 +116,10 @@ static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, mask = _PAGE_PRESENT|_PAGE_USER; if (write) mask |= _PAGE_RW; - if ((pte_flags(pte) & mask) != mask) + if ((pte_val(pte) & mask) != mask) return 0; /* hugepages are never "special" */ - VM_BUG_ON(pte_flags(pte) & _PAGE_SPECIAL); + VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); VM_BUG_ON(!pfn_valid(pte_pfn(pte))); refs = 0; @@ -173,10 +173,10 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr, mask = _PAGE_PRESENT|_PAGE_USER; if (write) mask |= _PAGE_RW; - if ((pte_flags(pte) & mask) != mask) + if ((pte_val(pte) & mask) != mask) return 0; /* hugepages are never "special" */ - VM_BUG_ON(pte_flags(pte) & _PAGE_SPECIAL); + VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); VM_BUG_ON(!pfn_valid(pte_pfn(pte))); refs = 0; diff --git a/trunk/arch/x86/mm/init_32.c b/trunk/arch/x86/mm/init_32.c index 8396868e82c5..bbe044dbe014 100644 --- a/trunk/arch/x86/mm/init_32.c +++ b/trunk/arch/x86/mm/init_32.c @@ -558,7 +558,7 @@ void zap_low_mappings(void) int nx_enabled; -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP); +pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL); EXPORT_SYMBOL_GPL(__supported_pte_mask); #ifdef CONFIG_X86_PAE diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index b8e461d49412..3e10054c5731 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -89,7 +89,7 @@ early_param("gbpages", parse_direct_gbpages_on); int after_bootmem; -pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP; +unsigned long __supported_pte_mask __read_mostly = ~0UL; EXPORT_SYMBOL_GPL(__supported_pte_mask); static int do_not_nx __cpuinitdata; @@ -196,6 +196,9 @@ set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) } pte = pte_offset_kernel(pmd, vaddr); + if (!pte_none(*pte) && pte_val(new_pte) && + pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask)) + pte_ERROR(*pte); set_pte(pte, new_pte); /* @@ -310,7 +313,7 @@ static __ref void *alloc_low_page(unsigned long *phys) if (pfn >= table_top) panic("alloc_low_page: ran out of memory"); - adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE); + adr = early_ioremap(pfn * PAGE_SIZE, PAGE_SIZE); memset(adr, 0, PAGE_SIZE); *phys = pfn * PAGE_SIZE; return adr; @@ -746,7 +749,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, old_start = mr[i].start; memmove(&mr[i], &mr[i+1], (nr_range - 1 - i) * sizeof (struct map_range)); - mr[i--].start = old_start; + mr[i].start = old_start; nr_range--; } diff --git a/trunk/arch/x86/mm/ioremap.c b/trunk/arch/x86/mm/ioremap.c index e4c43ec71b29..8cbeda15cd29 100644 --- a/trunk/arch/x86/mm/ioremap.c +++ b/trunk/arch/x86/mm/ioremap.c @@ -45,27 +45,6 @@ unsigned long __phys_addr(unsigned long x) } EXPORT_SYMBOL(__phys_addr); -bool __virt_addr_valid(unsigned long x) -{ - if (x >= __START_KERNEL_map) { - x -= __START_KERNEL_map; - if (x >= KERNEL_IMAGE_SIZE) - return false; - x += phys_base; - } else { - if (x < PAGE_OFFSET) - return false; - x -= PAGE_OFFSET; - if (system_state == SYSTEM_BOOTING ? - x > MAXMEM : !phys_addr_valid(x)) { - return false; - } - } - - return pfn_valid(x >> PAGE_SHIFT); -} -EXPORT_SYMBOL(__virt_addr_valid); - #else static inline int phys_addr_valid(unsigned long addr) @@ -77,24 +56,13 @@ static inline int phys_addr_valid(unsigned long addr) unsigned long __phys_addr(unsigned long x) { /* VMALLOC_* aren't constants; not available at the boot time */ - VIRTUAL_BUG_ON(x < PAGE_OFFSET); - VIRTUAL_BUG_ON(system_state != SYSTEM_BOOTING && - is_vmalloc_addr((void *) x)); + VIRTUAL_BUG_ON(x < PAGE_OFFSET || (system_state != SYSTEM_BOOTING && + is_vmalloc_addr((void *)x))); return x - PAGE_OFFSET; } EXPORT_SYMBOL(__phys_addr); #endif -bool __virt_addr_valid(unsigned long x) -{ - if (x < PAGE_OFFSET) - return false; - if (system_state != SYSTEM_BOOTING && is_vmalloc_addr((void *) x)) - return false; - return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT); -} -EXPORT_SYMBOL(__virt_addr_valid); - #endif int page_is_ram(unsigned long pagenr) @@ -274,16 +242,16 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, switch (prot_val) { case _PAGE_CACHE_UC: default: - prot = PAGE_KERNEL_IO_NOCACHE; + prot = PAGE_KERNEL_NOCACHE; break; case _PAGE_CACHE_UC_MINUS: - prot = PAGE_KERNEL_IO_UC_MINUS; + prot = PAGE_KERNEL_UC_MINUS; break; case _PAGE_CACHE_WC: - prot = PAGE_KERNEL_IO_WC; + prot = PAGE_KERNEL_WC; break; case _PAGE_CACHE_WB: - prot = PAGE_KERNEL_IO; + prot = PAGE_KERNEL; break; } @@ -600,12 +568,12 @@ static void __init __early_set_fixmap(enum fixed_addresses idx, } static inline void __init early_set_fixmap(enum fixed_addresses idx, - unsigned long phys, pgprot_t prot) + unsigned long phys) { if (after_paging_init) - __set_fixmap(idx, phys, prot); + set_fixmap(idx, phys); else - __early_set_fixmap(idx, phys, prot); + __early_set_fixmap(idx, phys, PAGE_KERNEL); } static inline void __init early_clear_fixmap(enum fixed_addresses idx) @@ -616,22 +584,16 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx) __early_set_fixmap(idx, 0, __pgprot(0)); } -static void *prev_map[FIX_BTMAPS_SLOTS] __initdata; -static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata; -static int __init check_early_ioremap_leak(void) -{ - int count = 0; - int i; - for (i = 0; i < FIX_BTMAPS_SLOTS; i++) - if (prev_map[i]) - count++; +static int __initdata early_ioremap_nested; - if (!count) +static int __init check_early_ioremap_leak(void) +{ + if (!early_ioremap_nested) return 0; WARN(1, KERN_WARNING "Debug warning: early ioremap leak of %d areas detected.\n", - count); + early_ioremap_nested); printk(KERN_WARNING "please boot with early_ioremap_debug and report the dmesg.\n"); @@ -639,33 +601,18 @@ static int __init check_early_ioremap_leak(void) } late_initcall(check_early_ioremap_leak); -static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) +void __init *early_ioremap(unsigned long phys_addr, unsigned long size) { unsigned long offset, last_addr; - unsigned int nrpages; + unsigned int nrpages, nesting; enum fixed_addresses idx0, idx; - int i, slot; WARN_ON(system_state != SYSTEM_BOOTING); - slot = -1; - for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { - if (!prev_map[i]) { - slot = i; - break; - } - } - - if (slot < 0) { - printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n", - phys_addr, size); - WARN_ON(1); - return NULL; - } - + nesting = early_ioremap_nested; if (early_ioremap_debug) { printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ", - phys_addr, size, slot); + phys_addr, size, nesting); dump_stack(); } @@ -676,7 +623,11 @@ static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, return NULL; } - prev_size[slot] = size; + if (nesting >= FIX_BTMAPS_NESTING) { + WARN_ON(1); + return NULL; + } + early_ioremap_nested++; /* * Mappings have to be page-aligned */ @@ -696,10 +647,10 @@ static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, /* * Ok, go for it.. */ - idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; + idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting; idx = idx0; while (nrpages > 0) { - early_set_fixmap(idx, phys_addr, prot); + early_set_fixmap(idx, phys_addr); phys_addr += PAGE_SIZE; --idx; --nrpages; @@ -707,20 +658,7 @@ static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, if (early_ioremap_debug) printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); - prev_map[slot] = (void *) (offset + fix_to_virt(idx0)); - return prev_map[slot]; -} - -/* Remap an IO device */ -void __init *early_ioremap(unsigned long phys_addr, unsigned long size) -{ - return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO); -} - -/* Remap memory */ -void __init *early_memremap(unsigned long phys_addr, unsigned long size) -{ - return __early_ioremap(phys_addr, size, PAGE_KERNEL); + return (void *) (offset + fix_to_virt(idx0)); } void __init early_iounmap(void *addr, unsigned long size) @@ -729,33 +667,15 @@ void __init early_iounmap(void *addr, unsigned long size) unsigned long offset; unsigned int nrpages; enum fixed_addresses idx; - int i, slot; - - slot = -1; - for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { - if (prev_map[i] == addr) { - slot = i; - break; - } - } + int nesting; - if (slot < 0) { - printk(KERN_INFO "early_iounmap(%p, %08lx) not found slot\n", - addr, size); - WARN_ON(1); - return; - } - - if (prev_size[slot] != size) { - printk(KERN_INFO "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n", - addr, size, slot, prev_size[slot]); - WARN_ON(1); + nesting = --early_ioremap_nested; + if (WARN_ON(nesting < 0)) return; - } if (early_ioremap_debug) { printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, - size, slot); + size, nesting); dump_stack(); } @@ -767,13 +687,12 @@ void __init early_iounmap(void *addr, unsigned long size) offset = virt_addr & ~PAGE_MASK; nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT; - idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; + idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting; while (nrpages > 0) { early_clear_fixmap(idx); --idx; --nrpages; } - prev_map[slot] = 0; } void __this_fixmap_does_not_exist(void) diff --git a/trunk/arch/x86/mm/srat_64.c b/trunk/arch/x86/mm/srat_64.c index 51c0a2fc14fe..1b4763e26ea9 100644 --- a/trunk/arch/x86/mm/srat_64.c +++ b/trunk/arch/x86/mm/srat_64.c @@ -138,7 +138,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) return; } - if (get_uv_system_type() >= UV_X2APIC) + if (is_uv_system()) apic_id = (pa->apic_id << 8) | pa->local_sapic_eid; else apic_id = pa->apic_id; diff --git a/trunk/arch/x86/oprofile/Makefile b/trunk/arch/x86/oprofile/Makefile index 446902b2a6b6..30f3eb366667 100644 --- a/trunk/arch/x86/oprofile/Makefile +++ b/trunk/arch/x86/oprofile/Makefile @@ -7,6 +7,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) oprofile-y := $(DRIVER_OBJS) init.o backtrace.o -oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_amd.o \ +oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \ op_model_ppro.o op_model_p4.o oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o diff --git a/trunk/arch/x86/oprofile/nmi_int.c b/trunk/arch/x86/oprofile/nmi_int.c index 57f6c9088081..8a5f1614a3d5 100644 --- a/trunk/arch/x86/oprofile/nmi_int.c +++ b/trunk/arch/x86/oprofile/nmi_int.c @@ -1,11 +1,10 @@ /** * @file nmi_int.c * - * @remark Copyright 2002-2008 OProfile authors + * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author John Levon - * @author Robert Richter */ #include @@ -440,7 +439,6 @@ int __init op_nmi_init(struct oprofile_operations *ops) __u8 vendor = boot_cpu_data.x86_vendor; __u8 family = boot_cpu_data.x86; char *cpu_type; - int ret = 0; if (!cpu_has_apic) return -ENODEV; @@ -453,23 +451,19 @@ int __init op_nmi_init(struct oprofile_operations *ops) default: return -ENODEV; case 6: - model = &op_amd_spec; + model = &op_athlon_spec; cpu_type = "i386/athlon"; break; case 0xf: - model = &op_amd_spec; + model = &op_athlon_spec; /* Actually it could be i386/hammer too, but give user space an consistent name. */ cpu_type = "x86-64/hammer"; break; case 0x10: - model = &op_amd_spec; + model = &op_athlon_spec; cpu_type = "x86-64/family10"; break; - case 0x11: - model = &op_amd_spec; - cpu_type = "x86-64/family11h"; - break; } break; @@ -496,24 +490,17 @@ int __init op_nmi_init(struct oprofile_operations *ops) return -ENODEV; } + init_sysfs(); #ifdef CONFIG_SMP register_cpu_notifier(&oprofile_cpu_nb); #endif - /* default values, can be overwritten by model */ + using_nmi = 1; ops->create_files = nmi_create_files; ops->setup = nmi_setup; ops->shutdown = nmi_shutdown; ops->start = nmi_start; ops->stop = nmi_stop; ops->cpu_type = cpu_type; - - if (model->init) - ret = model->init(ops); - if (ret) - return ret; - - init_sysfs(); - using_nmi = 1; printk(KERN_INFO "oprofile: using NMI interrupt.\n"); return 0; } @@ -526,6 +513,4 @@ void op_nmi_exit(void) unregister_cpu_notifier(&oprofile_cpu_nb); #endif } - if (model->exit) - model->exit(); } diff --git a/trunk/arch/x86/oprofile/op_model_amd.c b/trunk/arch/x86/oprofile/op_model_amd.c deleted file mode 100644 index d9faf607b3a6..000000000000 --- a/trunk/arch/x86/oprofile/op_model_amd.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * @file op_model_amd.c - * athlon / K7 / K8 / Family 10h model-specific MSR operations - * - * @remark Copyright 2002-2008 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * @author Graydon Hoare - * @author Robert Richter - * @author Barry Kasindorf -*/ - -#include -#include -#include - -#include -#include -#include - -#include "op_x86_model.h" -#include "op_counter.h" - -#define NUM_COUNTERS 4 -#define NUM_CONTROLS 4 - -#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) -#define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0) -#define CTR_WRITE(l, msrs, c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1); } while (0) -#define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) - -#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) -#define CTRL_READ(l, h, msrs, c) do {rdmsr(msrs->controls[(c)].addr, (l), (h)); } while (0) -#define CTRL_WRITE(l, h, msrs, c) do {wrmsr(msrs->controls[(c)].addr, (l), (h)); } while (0) -#define CTRL_SET_ACTIVE(n) (n |= (1<<22)) -#define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) -#define CTRL_CLEAR_LO(x) (x &= (1<<21)) -#define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0) -#define CTRL_SET_ENABLE(val) (val |= 1<<20) -#define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16)) -#define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17)) -#define CTRL_SET_UM(val, m) (val |= (m << 8)) -#define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff)) -#define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf)) -#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9)) -#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8)) - -static unsigned long reset_value[NUM_COUNTERS]; - -#ifdef CONFIG_OPROFILE_IBS - -/* IbsFetchCtl bits/masks */ -#define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */ -#define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */ -#define IBS_FETCH_LOW_MAX_CNT_MASK 0x0000FFFFUL /* MaxCnt mask */ - -/*IbsOpCtl bits */ -#define IBS_OP_LOW_VALID_BIT (1ULL<<18) /* bit 18 */ -#define IBS_OP_LOW_ENABLE (1ULL<<17) /* bit 17 */ - -/* Codes used in cpu_buffer.c */ -/* This produces duplicate code, need to be fixed */ -#define IBS_FETCH_BEGIN 3 -#define IBS_OP_BEGIN 4 - -/* The function interface needs to be fixed, something like add - data. Should then be added to linux/oprofile.h. */ -extern void oprofile_add_ibs_sample(struct pt_regs *const regs, - unsigned int * const ibs_sample, u8 code); - -struct ibs_fetch_sample { - /* MSRC001_1031 IBS Fetch Linear Address Register */ - unsigned int ibs_fetch_lin_addr_low; - unsigned int ibs_fetch_lin_addr_high; - /* MSRC001_1030 IBS Fetch Control Register */ - unsigned int ibs_fetch_ctl_low; - unsigned int ibs_fetch_ctl_high; - /* MSRC001_1032 IBS Fetch Physical Address Register */ - unsigned int ibs_fetch_phys_addr_low; - unsigned int ibs_fetch_phys_addr_high; -}; - -struct ibs_op_sample { - /* MSRC001_1034 IBS Op Logical Address Register (IbsRIP) */ - unsigned int ibs_op_rip_low; - unsigned int ibs_op_rip_high; - /* MSRC001_1035 IBS Op Data Register */ - unsigned int ibs_op_data1_low; - unsigned int ibs_op_data1_high; - /* MSRC001_1036 IBS Op Data 2 Register */ - unsigned int ibs_op_data2_low; - unsigned int ibs_op_data2_high; - /* MSRC001_1037 IBS Op Data 3 Register */ - unsigned int ibs_op_data3_low; - unsigned int ibs_op_data3_high; - /* MSRC001_1038 IBS DC Linear Address Register (IbsDcLinAd) */ - unsigned int ibs_dc_linear_low; - unsigned int ibs_dc_linear_high; - /* MSRC001_1039 IBS DC Physical Address Register (IbsDcPhysAd) */ - unsigned int ibs_dc_phys_low; - unsigned int ibs_dc_phys_high; -}; - -/* - * unitialize the APIC for the IBS interrupts if needed on AMD Family10h+ -*/ -static void clear_ibs_nmi(void); - -static int ibs_allowed; /* AMD Family10h and later */ - -struct op_ibs_config { - unsigned long op_enabled; - unsigned long fetch_enabled; - unsigned long max_cnt_fetch; - unsigned long max_cnt_op; - unsigned long rand_en; - unsigned long dispatched_ops; -}; - -static struct op_ibs_config ibs_config; - -#endif - -/* functions for op_amd_spec */ - -static void op_amd_fill_in_addresses(struct op_msrs * const msrs) -{ - int i; - - for (i = 0; i < NUM_COUNTERS; i++) { - if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; - } - - for (i = 0; i < NUM_CONTROLS; i++) { - if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; - } -} - - -static void op_amd_setup_ctrs(struct op_msrs const * const msrs) -{ - unsigned int low, high; - int i; - - /* clear all counters */ - for (i = 0 ; i < NUM_CONTROLS; ++i) { - if (unlikely(!CTRL_IS_RESERVED(msrs, i))) - continue; - CTRL_READ(low, high, msrs, i); - CTRL_CLEAR_LO(low); - CTRL_CLEAR_HI(high); - CTRL_WRITE(low, high, msrs, i); - } - - /* avoid a false detection of ctr overflows in NMI handler */ - for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!CTR_IS_RESERVED(msrs, i))) - continue; - CTR_WRITE(1, msrs, i); - } - - /* enable active counters */ - for (i = 0; i < NUM_COUNTERS; ++i) { - if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { - reset_value[i] = counter_config[i].count; - - CTR_WRITE(counter_config[i].count, msrs, i); - - CTRL_READ(low, high, msrs, i); - CTRL_CLEAR_LO(low); - CTRL_CLEAR_HI(high); - CTRL_SET_ENABLE(low); - CTRL_SET_USR(low, counter_config[i].user); - CTRL_SET_KERN(low, counter_config[i].kernel); - CTRL_SET_UM(low, counter_config[i].unit_mask); - CTRL_SET_EVENT_LOW(low, counter_config[i].event); - CTRL_SET_EVENT_HIGH(high, counter_config[i].event); - CTRL_SET_HOST_ONLY(high, 0); - CTRL_SET_GUEST_ONLY(high, 0); - - CTRL_WRITE(low, high, msrs, i); - } else { - reset_value[i] = 0; - } - } -} - -#ifdef CONFIG_OPROFILE_IBS - -static inline int -op_amd_handle_ibs(struct pt_regs * const regs, - struct op_msrs const * const msrs) -{ - unsigned int low, high; - struct ibs_fetch_sample ibs_fetch; - struct ibs_op_sample ibs_op; - - if (!ibs_allowed) - return 1; - - if (ibs_config.fetch_enabled) { - rdmsr(MSR_AMD64_IBSFETCHCTL, low, high); - if (high & IBS_FETCH_HIGH_VALID_BIT) { - ibs_fetch.ibs_fetch_ctl_high = high; - ibs_fetch.ibs_fetch_ctl_low = low; - rdmsr(MSR_AMD64_IBSFETCHLINAD, low, high); - ibs_fetch.ibs_fetch_lin_addr_high = high; - ibs_fetch.ibs_fetch_lin_addr_low = low; - rdmsr(MSR_AMD64_IBSFETCHPHYSAD, low, high); - ibs_fetch.ibs_fetch_phys_addr_high = high; - ibs_fetch.ibs_fetch_phys_addr_low = low; - - oprofile_add_ibs_sample(regs, - (unsigned int *)&ibs_fetch, - IBS_FETCH_BEGIN); - - /*reenable the IRQ */ - rdmsr(MSR_AMD64_IBSFETCHCTL, low, high); - high &= ~IBS_FETCH_HIGH_VALID_BIT; - high |= IBS_FETCH_HIGH_ENABLE; - low &= IBS_FETCH_LOW_MAX_CNT_MASK; - wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); - } - } - - if (ibs_config.op_enabled) { - rdmsr(MSR_AMD64_IBSOPCTL, low, high); - if (low & IBS_OP_LOW_VALID_BIT) { - rdmsr(MSR_AMD64_IBSOPRIP, low, high); - ibs_op.ibs_op_rip_low = low; - ibs_op.ibs_op_rip_high = high; - rdmsr(MSR_AMD64_IBSOPDATA, low, high); - ibs_op.ibs_op_data1_low = low; - ibs_op.ibs_op_data1_high = high; - rdmsr(MSR_AMD64_IBSOPDATA2, low, high); - ibs_op.ibs_op_data2_low = low; - ibs_op.ibs_op_data2_high = high; - rdmsr(MSR_AMD64_IBSOPDATA3, low, high); - ibs_op.ibs_op_data3_low = low; - ibs_op.ibs_op_data3_high = high; - rdmsr(MSR_AMD64_IBSDCLINAD, low, high); - ibs_op.ibs_dc_linear_low = low; - ibs_op.ibs_dc_linear_high = high; - rdmsr(MSR_AMD64_IBSDCPHYSAD, low, high); - ibs_op.ibs_dc_phys_low = low; - ibs_op.ibs_dc_phys_high = high; - - /* reenable the IRQ */ - oprofile_add_ibs_sample(regs, - (unsigned int *)&ibs_op, - IBS_OP_BEGIN); - rdmsr(MSR_AMD64_IBSOPCTL, low, high); - high = 0; - low &= ~IBS_OP_LOW_VALID_BIT; - low |= IBS_OP_LOW_ENABLE; - wrmsr(MSR_AMD64_IBSOPCTL, low, high); - } - } - - return 1; -} - -#endif - -static int op_amd_check_ctrs(struct pt_regs * const regs, - struct op_msrs const * const msrs) -{ - unsigned int low, high; - int i; - - for (i = 0 ; i < NUM_COUNTERS; ++i) { - if (!reset_value[i]) - continue; - CTR_READ(low, high, msrs, i); - if (CTR_OVERFLOWED(low)) { - oprofile_add_sample(regs, i); - CTR_WRITE(reset_value[i], msrs, i); - } - } - -#ifdef CONFIG_OPROFILE_IBS - op_amd_handle_ibs(regs, msrs); -#endif - - /* See op_model_ppro.c */ - return 1; -} - -static void op_amd_start(struct op_msrs const * const msrs) -{ - unsigned int low, high; - int i; - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (reset_value[i]) { - CTRL_READ(low, high, msrs, i); - CTRL_SET_ACTIVE(low); - CTRL_WRITE(low, high, msrs, i); - } - } - -#ifdef CONFIG_OPROFILE_IBS - if (ibs_allowed && ibs_config.fetch_enabled) { - low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; - high = IBS_FETCH_HIGH_ENABLE; - wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); - } - - if (ibs_allowed && ibs_config.op_enabled) { - low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) + IBS_OP_LOW_ENABLE; - high = 0; - wrmsr(MSR_AMD64_IBSOPCTL, low, high); - } -#endif -} - - -static void op_amd_stop(struct op_msrs const * const msrs) -{ - unsigned int low, high; - int i; - - /* Subtle: stop on all counters to avoid race with - * setting our pm callback */ - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (!reset_value[i]) - continue; - CTRL_READ(low, high, msrs, i); - CTRL_SET_INACTIVE(low); - CTRL_WRITE(low, high, msrs, i); - } - -#ifdef CONFIG_OPROFILE_IBS - if (ibs_allowed && ibs_config.fetch_enabled) { - low = 0; /* clear max count and enable */ - high = 0; - wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); - } - - if (ibs_allowed && ibs_config.op_enabled) { - low = 0; /* clear max count and enable */ - high = 0; - wrmsr(MSR_AMD64_IBSOPCTL, low, high); - } -#endif -} - -static void op_amd_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (CTR_IS_RESERVED(msrs, i)) - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - } - for (i = 0 ; i < NUM_CONTROLS ; ++i) { - if (CTRL_IS_RESERVED(msrs, i)) - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } -} - -#ifndef CONFIG_OPROFILE_IBS - -/* no IBS support */ - -static int op_amd_init(struct oprofile_operations *ops) -{ - return 0; -} - -static void op_amd_exit(void) {} - -#else - -static u8 ibs_eilvt_off; - -static inline void apic_init_ibs_nmi_per_cpu(void *arg) -{ - ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0); -} - -static inline void apic_clear_ibs_nmi_per_cpu(void *arg) -{ - setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1); -} - -static int pfm_amd64_setup_eilvt(void) -{ -#define IBSCTL_LVTOFFSETVAL (1 << 8) -#define IBSCTL 0x1cc - struct pci_dev *cpu_cfg; - int nodes; - u32 value = 0; - - /* per CPU setup */ - on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 1); - - nodes = 0; - cpu_cfg = NULL; - do { - cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD, - PCI_DEVICE_ID_AMD_10H_NB_MISC, - cpu_cfg); - if (!cpu_cfg) - break; - ++nodes; - pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off - | IBSCTL_LVTOFFSETVAL); - pci_read_config_dword(cpu_cfg, IBSCTL, &value); - if (value != (ibs_eilvt_off | IBSCTL_LVTOFFSETVAL)) { - printk(KERN_DEBUG "Failed to setup IBS LVT offset, " - "IBSCTL = 0x%08x", value); - return 1; - } - } while (1); - - if (!nodes) { - printk(KERN_DEBUG "No CPU node configured for IBS"); - return 1; - } - -#ifdef CONFIG_NUMA - /* Sanity check */ - /* Works only for 64bit with proper numa implementation. */ - if (nodes != num_possible_nodes()) { - printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, " - "found: %d, expected %d", - nodes, num_possible_nodes()); - return 1; - } -#endif - return 0; -} - -/* - * initialize the APIC for the IBS interrupts - * if available (AMD Family10h rev B0 and later) - */ -static void setup_ibs(void) -{ - ibs_allowed = boot_cpu_has(X86_FEATURE_IBS); - - if (!ibs_allowed) - return; - - if (pfm_amd64_setup_eilvt()) { - ibs_allowed = 0; - return; - } - - printk(KERN_INFO "oprofile: AMD IBS detected\n"); -} - - -/* - * unitialize the APIC for the IBS interrupts if needed on AMD Family10h - * rev B0 and later */ -static void clear_ibs_nmi(void) -{ - if (ibs_allowed) - on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1); -} - -static int (*create_arch_files)(struct super_block * sb, struct dentry * root); - -static int setup_ibs_files(struct super_block * sb, struct dentry * root) -{ - char buf[12]; - struct dentry *dir; - int ret = 0; - - /* architecture specific files */ - if (create_arch_files) - ret = create_arch_files(sb, root); - - if (ret) - return ret; - - if (!ibs_allowed) - return ret; - - /* model specific files */ - - /* setup some reasonable defaults */ - ibs_config.max_cnt_fetch = 250000; - ibs_config.fetch_enabled = 0; - ibs_config.max_cnt_op = 250000; - ibs_config.op_enabled = 0; - ibs_config.dispatched_ops = 1; - snprintf(buf, sizeof(buf), "ibs_fetch"); - dir = oprofilefs_mkdir(sb, root, buf); - oprofilefs_create_ulong(sb, dir, "rand_enable", - &ibs_config.rand_en); - oprofilefs_create_ulong(sb, dir, "enable", - &ibs_config.fetch_enabled); - oprofilefs_create_ulong(sb, dir, "max_count", - &ibs_config.max_cnt_fetch); - snprintf(buf, sizeof(buf), "ibs_uops"); - dir = oprofilefs_mkdir(sb, root, buf); - oprofilefs_create_ulong(sb, dir, "enable", - &ibs_config.op_enabled); - oprofilefs_create_ulong(sb, dir, "max_count", - &ibs_config.max_cnt_op); - oprofilefs_create_ulong(sb, dir, "dispatched_ops", - &ibs_config.dispatched_ops); - - return 0; -} - -static int op_amd_init(struct oprofile_operations *ops) -{ - setup_ibs(); - create_arch_files = ops->create_files; - ops->create_files = setup_ibs_files; - return 0; -} - -static void op_amd_exit(void) -{ - clear_ibs_nmi(); -} - -#endif - -struct op_x86_model_spec const op_amd_spec = { - .init = op_amd_init, - .exit = op_amd_exit, - .num_counters = NUM_COUNTERS, - .num_controls = NUM_CONTROLS, - .fill_in_addresses = &op_amd_fill_in_addresses, - .setup_ctrs = &op_amd_setup_ctrs, - .check_ctrs = &op_amd_check_ctrs, - .start = &op_amd_start, - .stop = &op_amd_stop, - .shutdown = &op_amd_shutdown -}; diff --git a/trunk/arch/x86/oprofile/op_model_athlon.c b/trunk/arch/x86/oprofile/op_model_athlon.c new file mode 100644 index 000000000000..3d534879a9dc --- /dev/null +++ b/trunk/arch/x86/oprofile/op_model_athlon.c @@ -0,0 +1,190 @@ +/* + * @file op_model_athlon.h + * athlon / K7 / K8 / Family 10h model-specific MSR operations + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author John Levon + * @author Philippe Elie + * @author Graydon Hoare + */ + +#include +#include +#include +#include + +#include "op_x86_model.h" +#include "op_counter.h" + +#define NUM_COUNTERS 4 +#define NUM_CONTROLS 4 + +#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) +#define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0) +#define CTR_WRITE(l, msrs, c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1); } while (0) +#define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) + +#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) +#define CTRL_READ(l, h, msrs, c) do {rdmsr(msrs->controls[(c)].addr, (l), (h)); } while (0) +#define CTRL_WRITE(l, h, msrs, c) do {wrmsr(msrs->controls[(c)].addr, (l), (h)); } while (0) +#define CTRL_SET_ACTIVE(n) (n |= (1<<22)) +#define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) +#define CTRL_CLEAR_LO(x) (x &= (1<<21)) +#define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0) +#define CTRL_SET_ENABLE(val) (val |= 1<<20) +#define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16)) +#define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17)) +#define CTRL_SET_UM(val, m) (val |= (m << 8)) +#define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff)) +#define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf)) +#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9)) +#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8)) + +static unsigned long reset_value[NUM_COUNTERS]; + +static void athlon_fill_in_addresses(struct op_msrs * const msrs) +{ + int i; + + for (i = 0; i < NUM_COUNTERS; i++) { + if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) + msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; + else + msrs->counters[i].addr = 0; + } + + for (i = 0; i < NUM_CONTROLS; i++) { + if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) + msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; + else + msrs->controls[i].addr = 0; + } +} + + +static void athlon_setup_ctrs(struct op_msrs const * const msrs) +{ + unsigned int low, high; + int i; + + /* clear all counters */ + for (i = 0 ; i < NUM_CONTROLS; ++i) { + if (unlikely(!CTRL_IS_RESERVED(msrs, i))) + continue; + CTRL_READ(low, high, msrs, i); + CTRL_CLEAR_LO(low); + CTRL_CLEAR_HI(high); + CTRL_WRITE(low, high, msrs, i); + } + + /* avoid a false detection of ctr overflows in NMI handler */ + for (i = 0; i < NUM_COUNTERS; ++i) { + if (unlikely(!CTR_IS_RESERVED(msrs, i))) + continue; + CTR_WRITE(1, msrs, i); + } + + /* enable active counters */ + for (i = 0; i < NUM_COUNTERS; ++i) { + if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { + reset_value[i] = counter_config[i].count; + + CTR_WRITE(counter_config[i].count, msrs, i); + + CTRL_READ(low, high, msrs, i); + CTRL_CLEAR_LO(low); + CTRL_CLEAR_HI(high); + CTRL_SET_ENABLE(low); + CTRL_SET_USR(low, counter_config[i].user); + CTRL_SET_KERN(low, counter_config[i].kernel); + CTRL_SET_UM(low, counter_config[i].unit_mask); + CTRL_SET_EVENT_LOW(low, counter_config[i].event); + CTRL_SET_EVENT_HIGH(high, counter_config[i].event); + CTRL_SET_HOST_ONLY(high, 0); + CTRL_SET_GUEST_ONLY(high, 0); + + CTRL_WRITE(low, high, msrs, i); + } else { + reset_value[i] = 0; + } + } +} + + +static int athlon_check_ctrs(struct pt_regs * const regs, + struct op_msrs const * const msrs) +{ + unsigned int low, high; + int i; + + for (i = 0 ; i < NUM_COUNTERS; ++i) { + if (!reset_value[i]) + continue; + CTR_READ(low, high, msrs, i); + if (CTR_OVERFLOWED(low)) { + oprofile_add_sample(regs, i); + CTR_WRITE(reset_value[i], msrs, i); + } + } + + /* See op_model_ppro.c */ + return 1; +} + + +static void athlon_start(struct op_msrs const * const msrs) +{ + unsigned int low, high; + int i; + for (i = 0 ; i < NUM_COUNTERS ; ++i) { + if (reset_value[i]) { + CTRL_READ(low, high, msrs, i); + CTRL_SET_ACTIVE(low); + CTRL_WRITE(low, high, msrs, i); + } + } +} + + +static void athlon_stop(struct op_msrs const * const msrs) +{ + unsigned int low, high; + int i; + + /* Subtle: stop on all counters to avoid race with + * setting our pm callback */ + for (i = 0 ; i < NUM_COUNTERS ; ++i) { + if (!reset_value[i]) + continue; + CTRL_READ(low, high, msrs, i); + CTRL_SET_INACTIVE(low); + CTRL_WRITE(low, high, msrs, i); + } +} + +static void athlon_shutdown(struct op_msrs const * const msrs) +{ + int i; + + for (i = 0 ; i < NUM_COUNTERS ; ++i) { + if (CTR_IS_RESERVED(msrs, i)) + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + } + for (i = 0 ; i < NUM_CONTROLS ; ++i) { + if (CTRL_IS_RESERVED(msrs, i)) + release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + } +} + +struct op_x86_model_spec const op_athlon_spec = { + .num_counters = NUM_COUNTERS, + .num_controls = NUM_CONTROLS, + .fill_in_addresses = &athlon_fill_in_addresses, + .setup_ctrs = &athlon_setup_ctrs, + .check_ctrs = &athlon_check_ctrs, + .start = &athlon_start, + .stop = &athlon_stop, + .shutdown = &athlon_shutdown +}; diff --git a/trunk/arch/x86/oprofile/op_x86_model.h b/trunk/arch/x86/oprofile/op_x86_model.h index 05a0261ba0c3..45b605fa71d0 100644 --- a/trunk/arch/x86/oprofile/op_x86_model.h +++ b/trunk/arch/x86/oprofile/op_x86_model.h @@ -32,8 +32,6 @@ struct pt_regs; * various x86 CPU models' perfctr support. */ struct op_x86_model_spec { - int (*init)(struct oprofile_operations *ops); - void (*exit)(void); unsigned int const num_counters; unsigned int const num_controls; void (*fill_in_addresses)(struct op_msrs * const msrs); @@ -48,6 +46,6 @@ struct op_x86_model_spec { extern struct op_x86_model_spec const op_ppro_spec; extern struct op_x86_model_spec const op_p4_spec; extern struct op_x86_model_spec const op_p4_ht2_spec; -extern struct op_x86_model_spec const op_amd_spec; +extern struct op_x86_model_spec const op_athlon_spec; #endif /* OP_X86_MODEL_H */ diff --git a/trunk/arch/x86/pci/fixup.c b/trunk/arch/x86/pci/fixup.c index 3c27a809393b..4bdaa590375d 100644 --- a/trunk/arch/x86/pci/fixup.c +++ b/trunk/arch/x86/pci/fixup.c @@ -511,31 +511,3 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, fam10h_pci_cfg_space_size); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size); - -/* - * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from - * confusing the PCI engine: - */ -static void sb600_disable_hpet_bar(struct pci_dev *dev) -{ - u8 val; - - /* - * The SB600 and SB700 both share the same device - * ID, but the PM register 0x55 does something different - * for the SB700, so make sure we are dealing with the - * SB600 before touching the bit: - */ - - pci_read_config_byte(dev, 0x08, &val); - - if (val < 0x2F) { - outb(0x55, 0xCD6); - val = inb(0xCD7); - - /* Set bit 7 in PM register 0x55 */ - outb(0x55, 0xCD6); - outb(val | 0x80, 0xCD7); - } -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar); diff --git a/trunk/arch/xtensa/kernel/setup.c b/trunk/arch/xtensa/kernel/setup.c index 9606d2bd1dd9..a00359e8f7a8 100644 --- a/trunk/arch/xtensa/kernel/setup.c +++ b/trunk/arch/xtensa/kernel/setup.c @@ -53,6 +53,11 @@ extern struct fd_ops no_fd_ops; struct fd_ops *fd_ops; #endif +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +extern struct ide_ops no_ide_ops; +struct ide_ops *ide_ops; +#endif + extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 034112bfe1f3..56cb343c76d8 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -1024,7 +1024,8 @@ int bsg_register_queue(struct request_queue *q, struct device *parent, bcd->release = release; kref_init(&bcd->ref); dev = MKDEV(bsg_major, bcd->minor); - class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname); + class_dev = device_create_drvdata(bsg_class, parent, dev, NULL, + "%s", devname); if (IS_ERR(class_dev)) { ret = PTR_ERR(class_dev); goto put_dev; diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index da49b006bcc5..12cf5d491f0d 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -259,7 +259,7 @@ config ACPI_ASUS config ACPI_TOSHIBA tristate "Toshiba Laptop Extras" - depends on X86 && INPUT + depends on X86 select INPUT_POLLDEV select NET select RFKILL diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 24649ada08df..3c578ef78c48 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -260,3 +260,115 @@ static int __init init_acpi_device_notify(void) } arch_initcall(init_acpi_device_notify); + + +#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) + +#ifdef CONFIG_PM +static u32 rtc_handler(void *context) +{ + acpi_clear_event(ACPI_EVENT_RTC); + acpi_disable_event(ACPI_EVENT_RTC, 0); + return ACPI_INTERRUPT_HANDLED; +} + +static inline void rtc_wake_setup(void) +{ + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); + /* + * After the RTC handler is installed, the Fixed_RTC event should + * be disabled. Only when the RTC alarm is set will it be enabled. + */ + acpi_clear_event(ACPI_EVENT_RTC); + acpi_disable_event(ACPI_EVENT_RTC, 0); +} + +static void rtc_wake_on(struct device *dev) +{ + acpi_clear_event(ACPI_EVENT_RTC); + acpi_enable_event(ACPI_EVENT_RTC, 0); +} + +static void rtc_wake_off(struct device *dev) +{ + acpi_disable_event(ACPI_EVENT_RTC, 0); +} +#else +#define rtc_wake_setup() do{}while(0) +#define rtc_wake_on NULL +#define rtc_wake_off NULL +#endif + +/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find + * its device node and pass extra config data. This helps its driver use + * capabilities that the now-obsolete mc146818 didn't have, and informs it + * that this board's RTC is wakeup-capable (per ACPI spec). + */ +#include + +static struct cmos_rtc_board_info rtc_info; + + +/* PNP devices are registered in a subsys_initcall(); + * ACPI specifies the PNP IDs to use. + */ +#include + +static int __init pnp_match(struct device *dev, void *data) +{ + static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", }; + struct pnp_dev *pnp = to_pnp_dev(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(ids); i++) { + if (compare_pnp_id(pnp->id, ids[i]) != 0) + return 1; + } + return 0; +} + +static struct device *__init get_rtc_dev(void) +{ + return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); +} + +static int __init acpi_rtc_init(void) +{ + struct device *dev = get_rtc_dev(); + + if (acpi_disabled) + return 0; + + if (dev) { + rtc_wake_setup(); + rtc_info.wake_on = rtc_wake_on; + rtc_info.wake_off = rtc_wake_off; + + /* workaround bug in some ACPI tables */ + if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { + DBG("bogus FADT month_alarm\n"); + acpi_gbl_FADT.month_alarm = 0; + } + + rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; + rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; + rtc_info.rtc_century = acpi_gbl_FADT.century; + + /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ + if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) + printk(PREFIX "RTC can wake from S4\n"); + + + dev->platform_data = &rtc_info; + + /* RTC always wakes from S1/S2/S3, and often S4/STD */ + device_init_wakeup(dev, 1); + + put_device(dev); + } else + DBG("RTC unavailable?\n"); + return 0; +} +module_init(acpi_rtc_init); + +#endif diff --git a/trunk/drivers/ata/pata_of_platform.c b/trunk/drivers/ata/pata_of_platform.c index 1f18ad9e4fe1..408da30594c4 100644 --- a/trunk/drivers/ata/pata_of_platform.c +++ b/trunk/drivers/ata/pata_of_platform.c @@ -52,7 +52,7 @@ static int __devinit pata_of_platform_probe(struct of_device *ofdev, ret = of_irq_to_resource(dn, 0, &irq_res); if (ret == NO_IRQ) - irq_res.start = irq_res.end = 0; + irq_res.start = irq_res.end = -1; else irq_res.flags = 0; diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index 02b596b9cf6a..41b4361bbf6e 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -148,64 +148,6 @@ static struct ata_port_operations pcmcia_8bit_port_ops = { #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - -struct pcmcia_config_check { - unsigned long ctl_base; - int skip_vcc; - int is_kme; -}; - -static int pcmcia_check_one_config(struct pcmcia_device *pdev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - struct pcmcia_config_check *stk = priv_data; - - /* Check for matching Vcc, unless we're desperate */ - if (!stk->skip_vcc) { - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) - return -ENODEV; - } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) - return -ENODEV; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) - pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; - - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - pdev->io.BasePort1 = io->win[0].base; - pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (!(io->flags & CISTPL_IO_16BIT)) - pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - if (io->nwin == 2) { - pdev->io.NumPorts1 = 8; - pdev->io.BasePort2 = io->win[1].base; - pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; - if (pcmcia_request_io(pdev, &pdev->io) != 0) - return -ENODEV; - stk->ctl_base = pdev->io.BasePort2; - } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { - pdev->io.NumPorts1 = io->win[0].len; - pdev->io.NumPorts2 = 0; - if (pcmcia_request_io(pdev, &pdev->io) != 0) - return -ENODEV; - stk->ctl_base = pdev->io.BasePort1 + 0x0e; - } else - return -ENODEV; - /* If we've got this far, we're done */ - return 0; - } - return -ENODEV; -} - /** * pcmcia_init_one - attach a PCMCIA interface * @pdev: pcmcia device @@ -219,11 +161,19 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) struct ata_host *host; struct ata_port *ap; struct ata_pcmcia_info *info; - struct pcmcia_config_check *stk = NULL; - int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p; + tuple_t tuple; + struct { + unsigned short buf[128]; + cisparse_t parse; + config_info_t conf; + cistpl_cftable_entry_t dflt; + } *stk = NULL; + cistpl_cftable_entry_t *cfg; + int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p; unsigned long io_base, ctl_base; void __iomem *io_addr, *ctl_addr; int n_ports = 1; + struct ata_port_operations *ops = &pcmcia_port_ops; info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -243,27 +193,96 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) pdev->conf.Attributes = CONF_ENABLE_IRQ; pdev->conf.IntType = INT_MEMORY_AND_IO; + /* Allocate resoure probing structures */ + + stk = kzalloc(sizeof(*stk), GFP_KERNEL); + if (!stk) + goto out1; + + cfg = &stk->parse.cftable_entry; + + /* Tuples we are walking */ + tuple.TupleData = (cisdata_t *)&stk->buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + /* See if we have a manufacturer identifier. Use it to set is_kme for vendor quirks */ is_kme = ((pdev->manf_id == MANFID_KME) && ((pdev->card_id == PRODID_KME_KXLC005_A) || (pdev->card_id == PRODID_KME_KXLC005_B))); - /* Allocate resoure probing structures */ - - stk = kzalloc(sizeof(*stk), GFP_KERNEL); - if (!stk) - goto out1; - stk->is_kme = is_kme; - stk->skip_vcc = io_base = ctl_base = 0; + /* Not sure if this is right... look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf)); +/* link->conf.Vcc = stk->conf.Vcc; */ + + pass = io_base = ctl_base = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple)); + + /* Now munch the resources looking for a suitable set */ + while (1) { + if (pcmcia_get_tuple_data(pdev, &tuple) != 0) + goto next_entry; + if (pcmcia_parse_tuple(pdev, &tuple, &stk->parse) != 0) + goto next_entry; + /* Check for matching Vcc, unless we're desperate */ + if (!pass) { + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) + goto next_entry; + } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) + goto next_entry; + } + } - if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) { - stk->skip_vcc = 1; - if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) - goto failed; /* No suitable config found */ + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; + pdev->conf.ConfigIndex = cfg->index; + pdev->io.BasePort1 = io->win[0].base; + pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (!(io->flags & CISTPL_IO_16BIT)) + pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + if (io->nwin == 2) { + pdev->io.NumPorts1 = 8; + pdev->io.BasePort2 = io->win[1].base; + pdev->io.NumPorts2 = (is_kme) ? 2 : 1; + if (pcmcia_request_io(pdev, &pdev->io) != 0) + goto next_entry; + io_base = pdev->io.BasePort1; + ctl_base = pdev->io.BasePort2; + } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { + pdev->io.NumPorts1 = io->win[0].len; + pdev->io.NumPorts2 = 0; + if (pcmcia_request_io(pdev, &pdev->io) != 0) + goto next_entry; + io_base = pdev->io.BasePort1; + ctl_base = pdev->io.BasePort1 + 0x0e; + } else + goto next_entry; + /* If we've got this far, we're done */ + break; + } +next_entry: + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); + if (pass) { + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple)); + } else if (pcmcia_get_next_tuple(pdev, &tuple) != 0) { + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple)); + memset(&stk->dflt, 0, sizeof(stk->dflt)); + pass++; + } } - io_base = pdev->io.BasePort1; - ctl_base = stk->ctl_base; + CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf)); @@ -365,7 +384,6 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ - PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), @@ -386,9 +404,9 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), + PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420), PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), - PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420), PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178), PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e), diff --git a/trunk/drivers/base/Kconfig b/trunk/drivers/base/Kconfig index d8e8c49c0cbd..6318f6b57360 100644 --- a/trunk/drivers/base/Kconfig +++ b/trunk/drivers/base/Kconfig @@ -54,7 +54,7 @@ config FIRMWARE_IN_KERNEL such firmware, and do not wish to use an initrd. This single option controls the inclusion of firmware for - every driver which uses request_firmare() and ships its + every driver which usees request_firmare() and ships its firmware in the kernel source tree, to avoid a proliferation of 'Include firmware for xxx device' options. diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 5aee1c0169ea..ef522ae55480 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -333,7 +333,9 @@ static int match_name(struct device *dev, void *data) { const char *name = data; - return sysfs_streq(name, dev->bus_id); + if (strcmp(name, dev->bus_id) == 0) + return 1; + return 0; } /** @@ -980,56 +982,6 @@ struct klist *bus_get_device_klist(struct bus_type *bus) } EXPORT_SYMBOL_GPL(bus_get_device_klist); -/* - * Yes, this forcably breaks the klist abstraction temporarily. It - * just wants to sort the klist, not change reference counts and - * take/drop locks rapidly in the process. It does all this while - * holding the lock for the list, so objects can't otherwise be - * added/removed while we're swizzling. - */ -static void device_insertion_sort_klist(struct device *a, struct list_head *list, - int (*compare)(const struct device *a, - const struct device *b)) -{ - struct list_head *pos; - struct klist_node *n; - struct device *b; - - list_for_each(pos, list) { - n = container_of(pos, struct klist_node, n_node); - b = container_of(n, struct device, knode_bus); - if (compare(a, b) <= 0) { - list_move_tail(&a->knode_bus.n_node, - &b->knode_bus.n_node); - return; - } - } - list_move_tail(&a->knode_bus.n_node, list); -} - -void bus_sort_breadthfirst(struct bus_type *bus, - int (*compare)(const struct device *a, - const struct device *b)) -{ - LIST_HEAD(sorted_devices); - struct list_head *pos, *tmp; - struct klist_node *n; - struct device *dev; - struct klist *device_klist; - - device_klist = bus_get_device_klist(bus); - - spin_lock(&device_klist->k_lock); - list_for_each_safe(pos, tmp, &device_klist->k_list) { - n = container_of(pos, struct klist_node, n_node); - dev = container_of(n, struct device, knode_bus); - device_insertion_sort_klist(dev, &sorted_devices, compare); - } - list_splice(&sorted_devices, &device_klist->k_list); - spin_unlock(&device_klist->k_lock); -} -EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); - int __init buses_init(void) { bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 8c2cc2648f5a..b98cb1416a2d 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -523,16 +523,11 @@ static void klist_children_put(struct klist_node *n) * device_initialize - init device structure. * @dev: device. * - * This prepares the device for use by other layers by initializing - * its fields. + * This prepares the device for use by other layers, + * including adding it to the device hierarchy. * It is the first half of device_register(), if called by - * that function, though it can also be called separately, so one - * may use @dev's fields. In particular, get_device()/put_device() - * may be used for reference counting of @dev after calling this - * function. - * - * NOTE: Use put_device() to give up your reference instead of freeing - * @dev directly once you have called this function. + * that, though it can also be called separately, so one + * may use @dev's fields (e.g. the refcount). */ void device_initialize(struct device *dev) { @@ -840,13 +835,9 @@ static void device_remove_sys_dev_entry(struct device *dev) * This is part 2 of device_register(), though may be called * separately _iff_ device_initialize() has been called separately. * - * This adds @dev to the kobject hierarchy via kobject_add(), adds it + * This adds it to the kobject hierarchy via kobject_add(), adds it * to the global and sibling lists for the device, then * adds it to the other relevant subsystems of the driver model. - * - * NOTE: _Never_ directly free @dev after calling this function, even - * if it returned an error! Always use put_device() to give up your - * reference instead. */ int device_add(struct device *dev) { @@ -974,10 +965,6 @@ int device_add(struct device *dev) * I.e. you should only call the two helpers separately if * have a clearly defined need to use and refcount the device * before it is added to the hierarchy. - * - * NOTE: _Never_ directly free @dev after calling this function, even - * if it returned an error! Always use put_device() to give up the - * reference initialized in this function instead. */ int device_register(struct device *dev) { @@ -1256,7 +1243,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent, return dev; error: - put_device(dev); + kfree(dev); return ERR_PTR(retval); } EXPORT_SYMBOL_GPL(device_create_vargs); @@ -1327,11 +1314,6 @@ EXPORT_SYMBOL_GPL(device_destroy); * device_rename - renames a device * @dev: the pointer to the struct device to be renamed * @new_name: the new name of the device - * - * It is the responsibility of the caller to provide mutual - * exclusion between two different calls of device_rename - * on the same device to ensure that new_name is valid and - * won't conflict with other devices. */ int device_rename(struct device *dev, char *new_name) { diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index 20febc00a525..3ac443b2ac08 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -257,9 +257,6 @@ static int __driver_attach(struct device *dev, void *data) * is an error. */ - if (drv->bus->match && !drv->bus->match(dev, drv)) - return 0; - if (dev->parent) /* Needed for USB */ down(&dev->parent->sem); down(&dev->sem); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index b7e571031ecd..c9c92b00fd55 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -164,7 +164,8 @@ static ssize_t firmware_loading_store(struct device *dev, } /* fallthrough */ default: - dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); + printk(KERN_ERR "%s: unexpected value (%d)\n", __func__, + loading); /* fallthrough */ case -1: fw_load_abort(fw_priv); @@ -308,7 +309,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, *dev_p = NULL; if (!fw_priv || !f_dev) { - dev_err(device, "%s: kmalloc failed\n", __func__); + printk(KERN_ERR "%s: kmalloc failed\n", __func__); retval = -ENOMEM; goto error_kfree; } @@ -328,7 +329,8 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, f_dev->uevent_suppress = 1; retval = device_register(f_dev); if (retval) { - dev_err(device, "%s: device_register failed\n", __func__); + printk(KERN_ERR "%s: device_register failed\n", + __func__); goto error_kfree; } *dev_p = f_dev; @@ -361,13 +363,15 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p, fw_priv->fw = fw; retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); if (retval) { - dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); + printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", + __func__); goto error_unreg; } retval = device_create_file(f_dev, &dev_attr_loading); if (retval) { - dev_err(device, "%s: device_create_file failed\n", __func__); + printk(KERN_ERR "%s: device_create_file failed\n", + __func__); goto error_unreg; } @@ -397,8 +401,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name, *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); if (!firmware) { - dev_err(device, "%s: kmalloc(struct firmware) failed\n", - __func__); + printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n", + __func__); retval = -ENOMEM; goto out; } @@ -407,15 +411,15 @@ _request_firmware(const struct firmware **firmware_p, const char *name, builtin++) { if (strcmp(name, builtin->name)) continue; - dev_info(device, "firmware: using built-in firmware %s\n", - name); + printk(KERN_INFO "firmware: using built-in firmware %s\n", + name); firmware->size = builtin->size; firmware->data = builtin->data; return 0; } if (uevent) - dev_info(device, "firmware: requesting %s\n", name); + printk(KERN_INFO "firmware: requesting %s\n", name); retval = fw_setup_device(firmware, &f_dev, name, device, uevent); if (retval) diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index dfcbfe504867..3f940393d6c7 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -42,8 +42,10 @@ struct resource *platform_get_resource(struct platform_device *dev, for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; - if (type == resource_type(r) && num-- == 0) - return r; + if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| + IORESOURCE_IRQ|IORESOURCE_DMA)) == type) + if (num-- == 0) + return r; } return NULL; } @@ -76,8 +78,10 @@ struct resource *platform_get_resource_byname(struct platform_device *dev, for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; - if (type == resource_type(r) && !strcmp(r->name, name)) - return r; + if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| + IORESOURCE_IRQ|IORESOURCE_DMA)) == type) + if (!strcmp(r->name, name)) + return r; } return NULL; } @@ -255,9 +259,9 @@ int platform_device_add(struct platform_device *pdev) p = r->parent; if (!p) { - if (resource_type(r) == IORESOURCE_MEM) + if (r->flags & IORESOURCE_MEM) p = &iomem_resource; - else if (resource_type(r) == IORESOURCE_IO) + else if (r->flags & IORESOURCE_IO) p = &ioport_resource; } @@ -278,14 +282,9 @@ int platform_device_add(struct platform_device *pdev) return ret; failed: - while (--i >= 0) { - struct resource *r = &pdev->resource[i]; - unsigned long type = resource_type(r); - - if (type == IORESOURCE_MEM || type == IORESOURCE_IO) - release_resource(r); - } - + while (--i >= 0) + if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO)) + release_resource(&pdev->resource[i]); return ret; } EXPORT_SYMBOL_GPL(platform_device_add); @@ -307,9 +306,7 @@ void platform_device_del(struct platform_device *pdev) for (i = 0; i < pdev->num_resources; i++) { struct resource *r = &pdev->resource[i]; - unsigned long type = resource_type(r); - - if (type == IORESOURCE_MEM || type == IORESOURCE_IO) + if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO)) release_resource(r); } } @@ -394,53 +391,6 @@ struct platform_device *platform_device_register_simple(const char *name, } EXPORT_SYMBOL_GPL(platform_device_register_simple); -/** - * platform_device_register_data - * @parent: parent device for the device we're adding - * @name: base name of the device we're adding - * @id: instance id - * @data: platform specific data for this platform device - * @size: size of platform specific data - * - * This function creates a simple platform device that requires minimal - * resource and memory management. Canned release function freeing memory - * allocated for the device allows drivers using such devices to be - * unloaded without waiting for the last reference to the device to be - * dropped. - */ -struct platform_device *platform_device_register_data( - struct device *parent, - const char *name, int id, - const void *data, size_t size) -{ - struct platform_device *pdev; - int retval; - - pdev = platform_device_alloc(name, id); - if (!pdev) { - retval = -ENOMEM; - goto error; - } - - pdev->dev.parent = parent; - - if (size) { - retval = platform_device_add_data(pdev, data, size); - if (retval) - goto error; - } - - retval = platform_device_add(pdev); - if (retval) - goto error; - - return pdev; - -error: - platform_device_put(pdev); - return ERR_PTR(retval); -} - static int platform_drv_probe(struct device *_dev) { struct platform_driver *drv = to_platform_driver(_dev->driver); @@ -912,7 +862,7 @@ static int platform_pm_restore_noirq(struct device *dev) #endif /* !CONFIG_HIBERNATION */ -static struct pm_ext_ops platform_pm_ops = { +struct pm_ext_ops platform_pm_ops = { .base = { .prepare = platform_pm_prepare, .complete = platform_pm_complete, diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 692c20ba5144..273a944d4040 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -83,7 +83,7 @@ void device_pm_add(struct device *dev) * transition is in progress in order to avoid leaving them * unhandled down the road */ - dev_WARN(dev, "Parentless device registered during a PM transaction\n"); + WARN_ON(true); } list_add_tail(&dev->power.entry, &dpm_list); @@ -778,7 +778,10 @@ EXPORT_SYMBOL_GPL(device_suspend); void __suspend_report_result(const char *function, void *fn, int ret) { - if (ret) - printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret); + if (ret) { + printk(KERN_ERR "%s(): ", function); + print_fn_descriptor_symbol("%s returns ", fn); + printk("%d\n", ret); + } } EXPORT_SYMBOL_GPL(__suspend_report_result); diff --git a/trunk/drivers/block/aoe/aoechr.c b/trunk/drivers/block/aoe/aoechr.c index 200efc4d2c1e..1f56d2c5b7fc 100644 --- a/trunk/drivers/block/aoe/aoechr.c +++ b/trunk/drivers/block/aoe/aoechr.c @@ -284,9 +284,9 @@ aoechr_init(void) return PTR_ERR(aoe_class); } for (i = 0; i < ARRAY_SIZE(chardevs); ++i) - device_create(aoe_class, NULL, - MKDEV(AOE_MAJOR, chardevs[i].minor), NULL, - chardevs[i].name); + device_create_drvdata(aoe_class, NULL, + MKDEV(AOE_MAJOR, chardevs[i].minor), + NULL, chardevs[i].name); return 0; } diff --git a/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c index 432cf4018291..49f274197b16 100644 --- a/trunk/drivers/block/ataflop.c +++ b/trunk/drivers/block/ataflop.c @@ -1882,6 +1882,10 @@ static int __init atari_floppy_init (void) /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ return -ENODEV; + if (MACH_IS_HADES) + /* Hades doesn't have Atari-compatible floppy */ + return -ENODEV; + if (register_blkdev(FLOPPY_MAJOR,"fd")) return -EBUSY; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 2cea27aba9a0..cf64ddf5d839 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4172,7 +4172,7 @@ static int __init floppy_init(void) int i, unit, drive; int err, dr; -#if defined(CONFIG_PPC) +#if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(FDC1)) return -ENODEV; #endif diff --git a/trunk/drivers/block/paride/pg.c b/trunk/drivers/block/paride/pg.c index 9dfa27163001..d731ca42f802 100644 --- a/trunk/drivers/block/paride/pg.c +++ b/trunk/drivers/block/paride/pg.c @@ -686,8 +686,9 @@ static int __init pg_init(void) for (unit = 0; unit < PG_UNITS; unit++) { struct pg *dev = &devices[unit]; if (dev->present) - device_create(pg_class, NULL, MKDEV(major, unit), NULL, - "pg%u", unit); + device_create_drvdata(pg_class, NULL, + MKDEV(major, unit), NULL, + "pg%u", unit); } err = 0; goto out; diff --git a/trunk/drivers/block/paride/pt.c b/trunk/drivers/block/paride/pt.c index 5ae229656eaa..673b8b2fd337 100644 --- a/trunk/drivers/block/paride/pt.c +++ b/trunk/drivers/block/paride/pt.c @@ -979,10 +979,12 @@ static int __init pt_init(void) for (unit = 0; unit < PT_UNITS; unit++) if (pt[unit].present) { - device_create(pt_class, NULL, MKDEV(major, unit), NULL, - "pt%d", unit); - device_create(pt_class, NULL, MKDEV(major, unit + 128), - NULL, "pt%dn", unit); + device_create_drvdata(pt_class, NULL, + MKDEV(major, unit), NULL, + "pt%d", unit); + device_create_drvdata(pt_class, NULL, + MKDEV(major, unit + 128), NULL, + "pt%dn", unit); } goto out; diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index 195ca7c720f5..0e077150568b 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -302,8 +302,9 @@ static struct kobj_type kobj_pkt_type_wqueue = { static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) { if (class_pktcdvd) { - pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, NULL, - "%s", pd->name); + pd->dev = device_create_drvdata(class_pktcdvd, NULL, + pd->pkt_dev, NULL, + "%s", pd->name); if (IS_ERR(pd->dev)) pd->dev = NULL; } diff --git a/trunk/drivers/block/viodasd.c b/trunk/drivers/block/viodasd.c index 1730d29e6044..f1c8feb5510b 100644 --- a/trunk/drivers/block/viodasd.c +++ b/trunk/drivers/block/viodasd.c @@ -249,6 +249,7 @@ static int send_request(struct request *req) struct HvLpEvent *hev; struct scatterlist sg[VIOMAXBLOCKDMA]; int sgindex; + int statindex; struct viodasd_device *d; unsigned long flags; @@ -257,9 +258,11 @@ static int send_request(struct request *req) if (rq_data_dir(req) == READ) { direction = DMA_FROM_DEVICE; viocmd = viomajorsubtype_blockio | vioblockread; + statindex = 0; } else { direction = DMA_TO_DEVICE; viocmd = viomajorsubtype_blockio | vioblockwrite; + statindex = 1; } d = req->rq_disk->private_data; diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c index e6ee21d99d92..bcf57927b7a8 100644 --- a/trunk/drivers/bluetooth/bluecard_cs.c +++ b/trunk/drivers/bluetooth/bluecard_cs.c @@ -901,23 +901,23 @@ static int bluecard_config(struct pcmcia_device *link) for (n = 0; n < 0x400; n += 0x40) { link->io.BasePort1 = n ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == 0) + if (i == CS_SUCCESS) break; } - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); goto failed; } i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c index 2cbe70b66470..27058477cc8b 100644 --- a/trunk/drivers/bluetooth/bt3c_cs.c +++ b/trunk/drivers/bluetooth/bt3c_cs.c @@ -678,78 +678,101 @@ static void bt3c_detach(struct pcmcia_device *link) kfree(info); } -static int bt3c_check_config(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { - unsigned long try = (unsigned long) priv_data; - - if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; - if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && - (cf->io.win[0].base != 0)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = (try == 0) ? 16 : - cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; + int i; + + i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) + return i; + + return pcmcia_parse_tuple(handle, tuple, parse); } -static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { - static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; - int j; - - if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { - for (j = 0; j < 5; j++) { - p_dev->io.BasePort1 = base[j]; - p_dev->io.IOAddrLines = base[j] ? 16 : 3; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - } - return -ENODEV; + if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +{ + if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + return get_tuple(handle, tuple, parse); } static int bt3c_config(struct pcmcia_device *link) { + static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; bt3c_info_t *info = link->priv; - int i; - unsigned long try; - - /* First pass: look for a config entry that looks normal. - Two tries: without IO aliases, then with aliases */ - for (try = 0; try < 2; try++) - if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try)) - goto found_port; + tuple_t tuple; + u_short buf[256]; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; + int i, j, try; + + /* First pass: look for a config entry that looks normal. */ + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + /* Two tries: without IO aliases, then with aliases */ + for (try = 0; try < 2; try++) { + i = first_tuple(link, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if (i != CS_SUCCESS) + goto next_entry; + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + goto found_port; + } +next_entry: + i = next_tuple(link, &tuple, &parse); + } + } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL)) - goto found_port; - - BT_ERR("No usable port range found"); - cs_error(link, RequestIO, -ENODEV); - goto failed; + i = first_tuple(link, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { + link->conf.ConfigIndex = cf->index; + for (j = 0; j < 5; j++) { + link->io.BasePort1 = base[j]; + link->io.IOAddrLines = base[j] ? 16 : 3; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + goto found_port; + } + } + i = next_tuple(link, &tuple, &parse); + } found_port: + if (i != CS_SUCCESS) { + BT_ERR("No usable port range found"); + cs_error(link, RequestIO, i); + goto failed; + } + i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c index 8e556b7ff9f6..68d1d258e6a4 100644 --- a/trunk/drivers/bluetooth/btuart_cs.c +++ b/trunk/drivers/bluetooth/btuart_cs.c @@ -607,78 +607,102 @@ static void btuart_detach(struct pcmcia_device *link) kfree(info); } -static int btuart_check_config(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { - int *try = priv_data; - - if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; - if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && - (cf->io.win[0].base != 0)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = (*try == 0) ? 16 : - cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; + int i; + + i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) + return i; + + return pcmcia_parse_tuple(handle, tuple, parse); } -static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { - static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; - int j; - - if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { - for (j = 0; j < 5; j++) { - p_dev->io.BasePort1 = base[j]; - p_dev->io.IOAddrLines = base[j] ? 16 : 3; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - } - return -ENODEV; + if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +{ + if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + return get_tuple(handle, tuple, parse); } static int btuart_config(struct pcmcia_device *link) { + static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; btuart_info_t *info = link->priv; - int i; - int try; - - /* First pass: look for a config entry that looks normal. - Two tries: without IO aliases, then with aliases */ - for (try = 0; try < 2; try++) - if (!pcmcia_loop_config(link, btuart_check_config, &try)) - goto found_port; + tuple_t tuple; + u_short buf[256]; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; + int i, j, try; + + /* First pass: look for a config entry that looks normal. */ + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + /* Two tries: without IO aliases, then with aliases */ + for (try = 0; try < 2; try++) { + i = first_tuple(link, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if (i != CS_SUCCESS) + goto next_entry; + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + goto found_port; + } +next_entry: + i = next_tuple(link, &tuple, &parse); + } + } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL)) - goto found_port; - - BT_ERR("No usable port range found"); - cs_error(link, RequestIO, -ENODEV); - goto failed; + i = first_tuple(link, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin > 0) + && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { + link->conf.ConfigIndex = cf->index; + for (j = 0; j < 5; j++) { + link->io.BasePort1 = base[j]; + link->io.IOAddrLines = base[j] ? 16 : 3; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + goto found_port; + } + } + i = next_tuple(link, &tuple, &parse); + } found_port: + if (i != CS_SUCCESS) { + BT_ERR("No usable port range found"); + cs_error(link, RequestIO, i); + goto failed; + } + i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index e6e6b037695a..dae45cdf02b2 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -590,40 +590,75 @@ static void dtl1_detach(struct pcmcia_device *link) kfree(info); } -static int dtl1_confcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) { - if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */ - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; + int i; + + i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) + return i; + + return pcmcia_parse_tuple(handle, tuple, parse); +} + +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +{ + if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +{ + if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + return get_tuple(handle, tuple, parse); } static int dtl1_config(struct pcmcia_device *link) { dtl1_info_t *info = link->priv; + tuple_t tuple; + u_short buf[256]; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; int i; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + /* Look for a generic full-sized window */ link->io.NumPorts1 = 8; - if (!pcmcia_loop_config(link, dtl1_confcheck, NULL)) + i = first_tuple(link, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.NumPorts1 = cf->io.win[0].len; /*yo */ + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + break; + } + i = next_tuple(link, &tuple, &parse); + } + + if (i != CS_SUCCESS) { + cs_error(link, RequestIO, i); goto failed; + } i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 4426bb552bd9..8dfcf77cb717 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -484,7 +484,7 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, return -EUNATCH; default: - err = n_tty_ioctl_helper(tty, file, cmd, arg); + err = n_tty_ioctl(tty, file, cmd, arg); break; }; diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 122254155ae1..caff85149b9d 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -350,7 +350,7 @@ config STALDRV config STALLION tristate "Stallion EasyIO or EC8/32 support" - depends on STALDRV && (ISA || EISA || PCI) + depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) help If you have an EasyIO or EasyConnection 8/32 multiport Stallion card, then this is for you; say Y. Make sure to read @@ -361,7 +361,7 @@ config STALLION config ISTALLION tristate "Stallion EC8/64, ONboard, Brumby support" - depends on STALDRV && (ISA || EISA || PCI) + depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) help If you have an EasyConnection 8/64, ONboard, Brumby or Stallion serial multiport card, say Y here. Make sure to read @@ -1043,6 +1043,15 @@ config HPET open selects one of the timers supported by the HPET. The timers are non-periodic and/or periodic. +config HPET_RTC_IRQ + bool + default HPET_EMULATE_RTC + depends on RTC && HPET + help + If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It + is assumed the platform called hpet_alloc with the RTC IRQ values for + the HPET timers. + config HPET_MMAP bool "Allow mmap of HPET" default y diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 1a4247dccac4..6850f6da7576 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -7,7 +7,7 @@ # FONTMAPFILE = cp437.uni -obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o +obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o obj-$(CONFIG_LEGACY_PTYS) += pty.o obj-$(CONFIG_UNIX98_PTYS) += pty.o diff --git a/trunk/drivers/char/agp/amd-k7-agp.c b/trunk/drivers/char/agp/amd-k7-agp.c index 3f98254b911f..603a986e96af 100644 --- a/trunk/drivers/char/agp/amd-k7-agp.c +++ b/trunk/drivers/char/agp/amd-k7-agp.c @@ -223,14 +223,12 @@ static int amd_irongate_configure(void) current_size = A_SIZE_LVL2(agp_bridge->current_size); - if (!amd_irongate_private.registers) { - /* Get the memory mapped registers */ - pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); - temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); - amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); - if (!amd_irongate_private.registers) - return -ENOMEM; - } + /* Get the memory mapped registers */ + pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); + temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); + amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!amd_irongate_private.registers) + return -ENOMEM; /* Write out the address of the gatt table */ writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); @@ -494,26 +492,6 @@ static void __devexit agp_amdk7_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } -#ifdef CONFIG_PM - -static int agp_amdk7_suspend(struct pci_dev *pdev, pm_message_t state) -{ - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - return 0; -} - -static int agp_amdk7_resume(struct pci_dev *pdev) -{ - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - return amd_irongate_driver.configure(); -} - -#endif /* CONFIG_PM */ - /* must be the same order as name table above */ static struct pci_device_id agp_amdk7_pci_table[] = { { @@ -550,10 +528,6 @@ static struct pci_driver agp_amdk7_pci_driver = { .id_table = agp_amdk7_pci_table, .probe = agp_amdk7_probe, .remove = agp_amdk7_remove, -#ifdef CONFIG_PM - .suspend = agp_amdk7_suspend, - .resume = agp_amdk7_resume, -#endif }; static int __init agp_amdk7_init(void) diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index 1108665913e2..043e36628d6d 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -54,7 +54,8 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB) #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ @@ -62,8 +63,7 @@ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB) extern int agp_memory_reserved; @@ -214,8 +214,8 @@ static int intel_i810_configure(void) if (agp_bridge->driver->needs_scratch_page) { for (i = 0; i < current_size->num_entries; i++) { writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); + readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */ } - readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI posting. */ } global_cache_flush(); return 0; @@ -525,10 +525,8 @@ static void intel_i830_init_gtt_entries(void) size += 4; } else if (IS_G4X) { /* On 4 series hardware, GTT stolen is separate from graphics - * stolen, ignore it in stolen gtt entries counting. However, - * 4KB of the stolen memory doesn't get mapped to the GTT. - */ - size = 4; + * stolen, ignore it in stolen gtt entries counting */ + size = 0; } else { /* On previous hardware, the GTT size was just what was * required to map the aperture. @@ -775,8 +773,8 @@ static int intel_i830_configure(void) if (agp_bridge->driver->needs_scratch_page) { for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); + readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */ } - readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */ } global_cache_flush(); @@ -991,8 +989,8 @@ static int intel_i915_configure(void) if (agp_bridge->driver->needs_scratch_page) { for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { writel(agp_bridge->scratch_page, intel_private.gtt+i); + readl(intel_private.gtt+i); /* PCI Posting. */ } - readl(intel_private.gtt+i-1); /* PCI Posting. */ } global_cache_flush(); diff --git a/trunk/drivers/char/agp/nvidia-agp.c b/trunk/drivers/char/agp/nvidia-agp.c index 5bbed3d79db9..dc70d3771811 100644 --- a/trunk/drivers/char/agp/nvidia-agp.c +++ b/trunk/drivers/char/agp/nvidia-agp.c @@ -201,15 +201,10 @@ extern int agp_memory_reserved; static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type) { int i, j; - int mask_type; - mask_type = agp_generic_type_to_mask_type(mem->bridge, type); - if (mask_type != 0 || type != mem->type) + if ((type != 0) || (mem->type != 0)) return -EINVAL; - if (mem->page_count == 0) - return 0; - if ((pg_start + mem->page_count) > (nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE)) return -EINVAL; @@ -225,13 +220,10 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { writel(agp_bridge->driver->mask_memory(agp_bridge, - mem->memory[i], mask_type), + mem->memory[i], mem->type), agp_bridge->gatt_table+nvidia_private.pg_offset+j); + readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j); /* PCI Posting. */ } - - /* PCI Posting. */ - readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j - 1); - agp_bridge->driver->tlb_flush(mem); return 0; } @@ -241,15 +233,9 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type { int i; - int mask_type; - - mask_type = agp_generic_type_to_mask_type(mem->bridge, type); - if (mask_type != 0 || type != mem->type) + if ((type != 0) || (mem->type != 0)) return -EINVAL; - if (mem->page_count == 0) - return 0; - for (i = pg_start; i < (mem->page_count + pg_start); i++) writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i); diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index 98821f97583c..6e763e3f5a81 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -837,6 +837,9 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch) struct async_struct *info; unsigned long flags; + if (!tty) + return 0; + info = tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_put_char")) @@ -889,6 +892,9 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count struct async_struct *info; unsigned long flags; + if (!tty) + return 0; + info = tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_write")) diff --git a/trunk/drivers/char/applicom.c b/trunk/drivers/char/applicom.c index 05674febb0c6..31d08b641f5b 100644 --- a/trunk/drivers/char/applicom.c +++ b/trunk/drivers/char/applicom.c @@ -478,7 +478,7 @@ static int do_ac_read(int IndexCard, char __user *buf, struct st_ram_io *st_loc, struct mailbox *mailbox) { void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC; - unsigned char *to = (unsigned char *)mailbox; + unsigned char *to = (unsigned char *)&mailbox; #ifdef DEBUG int c; #endif @@ -712,7 +712,8 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un IndexCard = adgl->num_card-1; - if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { + if(cmd != 0 && cmd != 6 && + ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { static int warncount = 10; if (warncount) { printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); @@ -831,7 +832,8 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un } break; default: - ret = -ENOTTY; + printk(KERN_INFO "APPLICOM driver ioctl, unknown function code %d\n",cmd) ; + ret = -EINVAL; break; } Dummy = readb(apbs[IndexCard].RamIO + VERS); diff --git a/trunk/drivers/char/bsr.c b/trunk/drivers/char/bsr.c index 456f54db73e2..b650b4e48e50 100644 --- a/trunk/drivers/char/bsr.c +++ b/trunk/drivers/char/bsr.c @@ -229,8 +229,9 @@ static int bsr_create_devs(struct device_node *bn) if (result) goto out_err; - cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev, - cur, cur->bsr_name); + cur->bsr_device = device_create_drvdata(bsr_class, NULL, + cur->bsr_dev, + cur, cur->bsr_name); if (!cur->bsr_device) { printk(KERN_ERR "device_create failed for %s\n", cur->bsr_name); diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 5e5b1dc1a0a7..fe6d774fe2e4 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -4993,14 +4993,12 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { card_name = "Cyclom-Y"; - addr0 = ioremap_nocache(pci_resource_start(pdev, 0), - CyPCI_Yctl); + addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); if (addr0 == NULL) { dev_err(&pdev->dev, "can't remap ctl region\n"); goto err_reg; } - addr2 = ioremap_nocache(pci_resource_start(pdev, 2), - CyPCI_Ywin); + addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); if (addr2 == NULL) { dev_err(&pdev->dev, "can't remap base region\n"); goto err_unmap; @@ -5015,8 +5013,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { struct RUNTIME_9060 __iomem *ctl_addr; - ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0), - CyPCI_Zctl); + ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); if (addr0 == NULL) { dev_err(&pdev->dev, "can't remap ctl region\n"); goto err_reg; @@ -5029,8 +5026,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, mailbox = (u32)readl(&ctl_addr->mail_box_0); - addr2 = ioremap_nocache(pci_resource_start(pdev, 2), - mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin); + addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? + CyPCI_Ze_win : CyPCI_Zwin); if (addr2 == NULL) { dev_err(&pdev->dev, "can't remap base region\n"); goto err_unmap; @@ -5162,9 +5159,9 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, cy_card[card_no].base_addr = NULL; free_irq(irq, &cy_card[card_no]); err_unmap: - iounmap(addr0); + pci_iounmap(pdev, addr0); if (addr2) - iounmap(addr2); + pci_iounmap(pdev, addr2); err_reg: pci_release_regions(pdev); err_dis: @@ -5189,9 +5186,9 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev) cy_writew(cinfo->ctl_addr + 0x68, readw(cinfo->ctl_addr + 0x68) & ~0x0900); - iounmap(cinfo->base_addr); + pci_iounmap(pdev, cinfo->base_addr); if (cinfo->ctl_addr) - iounmap(cinfo->ctl_addr); + pci_iounmap(pdev, cinfo->ctl_addr); if (cinfo->irq #ifndef CONFIG_CYZ_INTR && !IS_CYC_Z(*cinfo) diff --git a/trunk/drivers/char/ds1286.c b/trunk/drivers/char/ds1286.c index 5329d482b582..fb584938c9c3 100644 --- a/trunk/drivers/char/ds1286.c +++ b/trunk/drivers/char/ds1286.c @@ -443,6 +443,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) { unsigned char save_control; unsigned long flags; + unsigned long uip_watchdog = jiffies; /* * read RTC once any update in progress is done. The update @@ -455,7 +456,8 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) */ if (ds1286_is_updating() != 0) - msleep(20); + while (time_before(jiffies, uip_watchdog + 2*HZ/100)) + barrier(); /* * Only the values that we read from the RTC are set. We leave diff --git a/trunk/drivers/char/dsp56k.c b/trunk/drivers/char/dsp56k.c index 85832ab924e6..ca7c72a486b2 100644 --- a/trunk/drivers/char/dsp56k.c +++ b/trunk/drivers/char/dsp56k.c @@ -508,8 +508,8 @@ static int __init dsp56k_init_driver(void) err = PTR_ERR(dsp56k_class); goto out_chrdev; } - device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, - "dsp56k"); + device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), + NULL, "dsp56k"); printk(banner); goto out; diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index 4998b2761e8f..456e4ede049f 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -1376,7 +1376,6 @@ static void post_fep_init(unsigned int crd) unsigned long flags; u16 tseg, rseg; - tty_port_init(&ch->port); ch->brdchan = bc; ch->mailbox = gd; INIT_WORK(&ch->tqueue, do_softint); @@ -1511,6 +1510,10 @@ static void post_fep_init(unsigned int crd) ch->fepstopca = 0; ch->close_delay = 50; + ch->port.count = 0; + ch->port.blocked_open = 0; + init_waitqueue_head(&ch->port.open_wait); + init_waitqueue_head(&ch->port.close_wait); spin_unlock_irqrestore(&epca_lock, flags); } diff --git a/trunk/drivers/char/generic_serial.c b/trunk/drivers/char/generic_serial.c index c6090f84a2e4..19d3afb0e50c 100644 --- a/trunk/drivers/char/generic_serial.c +++ b/trunk/drivers/char/generic_serial.c @@ -54,6 +54,8 @@ int gs_put_char(struct tty_struct * tty, unsigned char ch) func_enter (); + if (!tty) return 0; + port = tty->driver_data; if (!port) return 0; @@ -95,6 +97,8 @@ int gs_write(struct tty_struct * tty, func_enter (); + if (!tty) return 0; + port = tty->driver_data; if (!port) return 0; @@ -181,6 +185,7 @@ static int gs_real_chars_in_buffer(struct tty_struct *tty) struct gs_port *port; func_enter (); + if (!tty) return 0; port = tty->driver_data; if (!port->rd) return 0; @@ -269,6 +274,8 @@ void gs_flush_buffer(struct tty_struct *tty) func_enter (); + if (!tty) return; + port = tty->driver_data; if (!port) return; @@ -289,6 +296,8 @@ void gs_flush_chars(struct tty_struct * tty) func_enter (); + if (!tty) return; + port = tty->driver_data; if (!port) return; @@ -312,6 +321,8 @@ void gs_stop(struct tty_struct * tty) func_enter (); + if (!tty) return; + port = tty->driver_data; if (!port) return; @@ -330,6 +341,8 @@ void gs_start(struct tty_struct * tty) { struct gs_port *port; + if (!tty) return; + port = tty->driver_data; if (!port) return; @@ -380,6 +393,8 @@ void gs_hangup(struct tty_struct *tty) func_enter (); + if (!tty) return; + port = tty->driver_data; tty = port->port.tty; if (!tty) @@ -411,6 +426,8 @@ int gs_block_til_ready(void *port_, struct file * filp) tty = port->port.tty; + if (!tty) return 0; + gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); /* * If the device is in the middle of being closed, then block @@ -506,6 +523,8 @@ void gs_close(struct tty_struct * tty, struct file * filp) func_enter (); + if (!tty) return; + port = (struct gs_port *) tty->driver_data; if (!port) return; @@ -602,6 +621,8 @@ void gs_set_termios (struct tty_struct * tty, func_enter(); + if (!tty) return; + port = tty->driver_data; if (!port) return; diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index f3cfb4c76125..b3f5dbc6d880 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -53,11 +53,6 @@ #define HPET_RANGE_SIZE 1024 /* from HPET spec */ - -/* WARNING -- don't get confused. These macros are never used - * to write the (single) counter, and rarely to read it. - * They're badly named; to fix, someday. - */ #if BITS_PER_LONG == 64 #define write_counter(V, MC) writeq(V, MC) #define read_counter(MC) readq(MC) @@ -82,7 +77,7 @@ static struct clocksource clocksource_hpet = { .rating = 250, .read = read_hpet, .mask = CLOCKSOURCE_MASK(64), - .mult = 0, /* to be calculated */ + .mult = 0, /*to be caluclated*/ .shift = 10, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -91,6 +86,8 @@ static struct clocksource *hpet_clocksource; /* A lock for concurrent access by app and isr hpet activity. */ static DEFINE_SPINLOCK(hpet_lock); +/* A lock for concurrent intermodule access to hpet and isr hpet activity. */ +static DEFINE_SPINLOCK(hpet_task_lock); #define HPET_DEV_NAME (7) @@ -102,6 +99,7 @@ struct hpet_dev { unsigned long hd_irqdata; wait_queue_head_t hd_waitqueue; struct fasync_struct *hd_async_queue; + struct hpet_task *hd_task; unsigned int hd_flags; unsigned int hd_irq; unsigned int hd_hdwirq; @@ -175,6 +173,11 @@ static irqreturn_t hpet_interrupt(int irq, void *data) writel(isr, &devp->hd_hpet->hpet_isr); spin_unlock(&hpet_lock); + spin_lock(&hpet_task_lock); + if (devp->hd_task) + devp->hd_task->ht_func(devp->hd_task->ht_data); + spin_unlock(&hpet_task_lock); + wake_up_interruptible(&devp->hd_waitqueue); kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN); @@ -182,67 +185,6 @@ static irqreturn_t hpet_interrupt(int irq, void *data) return IRQ_HANDLED; } -static void hpet_timer_set_irq(struct hpet_dev *devp) -{ - unsigned long v; - int irq, gsi; - struct hpet_timer __iomem *timer; - - spin_lock_irq(&hpet_lock); - if (devp->hd_hdwirq) { - spin_unlock_irq(&hpet_lock); - return; - } - - timer = devp->hd_timer; - - /* we prefer level triggered mode */ - v = readl(&timer->hpet_config); - if (!(v & Tn_INT_TYPE_CNF_MASK)) { - v |= Tn_INT_TYPE_CNF_MASK; - writel(v, &timer->hpet_config); - } - spin_unlock_irq(&hpet_lock); - - v = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >> - Tn_INT_ROUTE_CAP_SHIFT; - - /* - * In PIC mode, skip IRQ0-4, IRQ6-9, IRQ12-15 which is always used by - * legacy device. In IO APIC mode, we skip all the legacy IRQS. - */ - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) - v &= ~0xf3df; - else - v &= ~0xffff; - - for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; - irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { - - if (irq >= NR_IRQS) { - irq = HPET_MAX_IRQ; - break; - } - - gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE, - ACPI_ACTIVE_LOW); - if (gsi > 0) - break; - - /* FIXME: Setup interrupt source table */ - } - - if (irq < HPET_MAX_IRQ) { - spin_lock_irq(&hpet_lock); - v = readl(&timer->hpet_config); - v |= irq << Tn_INT_ROUTE_CNF_SHIFT; - writel(v, &timer->hpet_config); - devp->hd_hdwirq = gsi; - spin_unlock_irq(&hpet_lock); - } - return; -} - static int hpet_open(struct inode *inode, struct file *file) { struct hpet_dev *devp; @@ -257,7 +199,8 @@ static int hpet_open(struct inode *inode, struct file *file) for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) for (i = 0; i < hpetp->hp_ntimer; i++) - if (hpetp->hp_dev[i].hd_flags & HPET_OPEN) + if (hpetp->hp_dev[i].hd_flags & HPET_OPEN + || hpetp->hp_dev[i].hd_task) continue; else { devp = &hpetp->hp_dev[i]; @@ -276,8 +219,6 @@ static int hpet_open(struct inode *inode, struct file *file) spin_unlock_irq(&hpet_lock); unlock_kernel(); - hpet_timer_set_irq(devp); - return 0; } @@ -500,11 +441,7 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) devp->hd_irq = irq; t = devp->hd_ireqfreq; v = readq(&timer->hpet_config); - - /* 64-bit comparators are not yet supported through the ioctls, - * so force this into 32-bit mode if it supports both modes - */ - g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK; + g = v | Tn_INT_ENB_CNF_MASK; if (devp->hd_flags & HPET_PERIODIC) { write_counter(t, &timer->hpet_compare); @@ -514,12 +451,6 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) v |= Tn_VAL_SET_CNF_MASK; writeq(v, &timer->hpet_config); local_irq_save(flags); - - /* NOTE: what we modify here is a hidden accumulator - * register supported by periodic-capable comparators. - * We never want to modify the (single) counter; that - * would affect all the comparators. - */ m = read_counter(&hpet->hpet_mc); write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); } else { @@ -673,6 +604,57 @@ static int hpet_is_known(struct hpet_data *hdp) return 0; } +static inline int hpet_tpcheck(struct hpet_task *tp) +{ + struct hpet_dev *devp; + struct hpets *hpetp; + + devp = tp->ht_opaque; + + if (!devp) + return -ENXIO; + + for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) + if (devp >= hpetp->hp_dev + && devp < (hpetp->hp_dev + hpetp->hp_ntimer) + && devp->hd_hpet == hpetp->hp_hpet) + return 0; + + return -ENXIO; +} + +#if 0 +int hpet_unregister(struct hpet_task *tp) +{ + struct hpet_dev *devp; + struct hpet_timer __iomem *timer; + int err; + + if ((err = hpet_tpcheck(tp))) + return err; + + spin_lock_irq(&hpet_task_lock); + spin_lock(&hpet_lock); + + devp = tp->ht_opaque; + if (devp->hd_task != tp) { + spin_unlock(&hpet_lock); + spin_unlock_irq(&hpet_task_lock); + return -ENXIO; + } + + timer = devp->hd_timer; + writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK), + &timer->hpet_config); + devp->hd_flags &= ~(HPET_IE | HPET_PERIODIC); + devp->hd_task = NULL; + spin_unlock(&hpet_lock); + spin_unlock_irq(&hpet_task_lock); + + return 0; +} +#endif /* 0 */ + static ctl_table hpet_table[] = { { .ctl_name = CTL_UNNUMBERED, @@ -764,7 +746,6 @@ int hpet_alloc(struct hpet_data *hdp) static struct hpets *last = NULL; unsigned long period; unsigned long long temp; - u32 remainder; /* * hpet_alloc can be called by platform dependent code. @@ -828,13 +809,9 @@ int hpet_alloc(struct hpet_data *hdp) printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); printk("\n"); - temp = hpetp->hp_tick_freq; - remainder = do_div(temp, 1000000); - printk(KERN_INFO - "hpet%u: %u comparators, %d-bit %u.%06u MHz counter\n", - hpetp->hp_which, hpetp->hp_ntimer, - cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, - (unsigned) temp, remainder); + printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", + hpetp->hp_which, hpetp->hp_ntimer, + cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq); mcfg = readq(&hpet->hpet_config); if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { @@ -897,6 +874,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) hdp->hd_address = ioremap(addr.minimum, addr.address_length); if (hpet_is_known(hdp)) { + printk(KERN_DEBUG "%s: 0x%lx is busy\n", + __func__, hdp->hd_phys_address); iounmap(hdp->hd_address); return AE_ALREADY_EXISTS; } @@ -912,6 +891,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) HPET_RANGE_SIZE); if (hpet_is_known(hdp)) { + printk(KERN_DEBUG "%s: 0x%lx is busy\n", + __func__, hdp->hd_phys_address); iounmap(hdp->hd_address); return AE_ALREADY_EXISTS; } diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index bf70450a49cc..fd64137b1ab9 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) spin_lock_irqsave(&hp->lock, flags); if (--hp->count == 0) { + if (hp->ops->notifier_del) + hp->ops->notifier_del(hp, hp->data); + /* We are done with the tty pointer now. */ hp->tty = NULL; spin_unlock_irqrestore(&hp->lock, flags); - if (hp->ops->notifier_del) - hp->ops->notifier_del(hp, hp->data); - /* * Chain calls chars_in_buffer() and returns immediately if * there is no buffered data otherwise sleeps on a wait queue @@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct *tty) hp->n_outbuf = 0; hp->tty = NULL; - spin_unlock_irqrestore(&hp->lock, flags); - if (hp->ops->notifier_del) hp->ops->notifier_del(hp, hp->data); + spin_unlock_irqrestore(&hp->lock, flags); + while(temp_open_count) { --temp_open_count; kref_put(&hp->kref, destroy_hvc_struct); @@ -819,11 +819,11 @@ static int hvc_init(void) hvc_driver = drv; return 0; +put_tty: + put_tty_driver(hvc_driver); stop_thread: kthread_stop(hvc_task); hvc_task = NULL; -put_tty: - put_tty_driver(drv); out: return err; } diff --git a/trunk/drivers/char/hw_random/omap-rng.c b/trunk/drivers/char/hw_random/omap-rng.c index d4e7dca06e4f..51738bdd834e 100644 --- a/trunk/drivers/char/hw_random/omap-rng.c +++ b/trunk/drivers/char/hw_random/omap-rng.c @@ -118,21 +118,18 @@ static int __init omap_rng_probe(struct platform_device *pdev) mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name); - if (mem == NULL) { - ret = -EBUSY; - goto err_region; - } + if (mem == NULL) + return -EBUSY; dev_set_drvdata(&pdev->dev, mem); - rng_base = ioremap(res->start, res->end - res->start + 1); - if (!rng_base) { - ret = -ENOMEM; - goto err_ioremap; - } + rng_base = (u32 __force __iomem *)io_p2v(res->start); ret = hwrng_register(&omap_rng_ops); - if (ret) - goto err_register; + if (ret) { + release_resource(mem); + rng_base = NULL; + return ret; + } dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", omap_rng_read_reg(RNG_REV_REG)); @@ -141,18 +138,6 @@ static int __init omap_rng_probe(struct platform_device *pdev) rng_dev = pdev; return 0; - -err_register: - iounmap(rng_base); - rng_base = NULL; -err_ioremap: - release_resource(mem); -err_region: - if (cpu_is_omap24xx()) { - clk_disable(rng_ick); - clk_put(rng_ick); - } - return ret; } static int __exit omap_rng_remove(struct platform_device *pdev) @@ -163,8 +148,6 @@ static int __exit omap_rng_remove(struct platform_device *pdev) omap_rng_write_reg(RNG_MASK_REG, 0x0); - iounmap(rng_base); - if (cpu_is_omap24xx()) { clk_disable(rng_ick); clk_put(rng_ick); diff --git a/trunk/drivers/char/ip2/Makefile b/trunk/drivers/char/ip2/Makefile index bc397d92b499..939618f62fe1 100644 --- a/trunk/drivers/char/ip2/Makefile +++ b/trunk/drivers/char/ip2/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_COMPUTONE) += ip2.o -ip2-objs := ip2main.o +ip2-objs := ip2base.o ip2main.o diff --git a/trunk/drivers/char/ip2/i2ellis.c b/trunk/drivers/char/ip2/i2ellis.c index 29db44de399f..3601017f58cf 100644 --- a/trunk/drivers/char/ip2/i2ellis.c +++ b/trunk/drivers/char/ip2/i2ellis.c @@ -68,6 +68,38 @@ static DEFINE_RWLOCK(Dl_spinlock); // iiInitialize //======================================================= +//****************************************************************************** +// Function: iiEllisInit() +// Parameters: None +// +// Returns: Nothing +// +// Description: +// +// This routine performs any required initialization of the iiEllis subsystem. +// +//****************************************************************************** +static void +iiEllisInit(void) +{ +} + +//****************************************************************************** +// Function: iiEllisCleanup() +// Parameters: None +// +// Returns: Nothing +// +// Description: +// +// This routine performs any required cleanup of the iiEllis subsystem. +// +//****************************************************************************** +static void +iiEllisCleanup(void) +{ +} + //****************************************************************************** // Function: iiSetAddress(pB, address, delay) // Parameters: pB - pointer to the board structure diff --git a/trunk/drivers/char/ip2/i2ellis.h b/trunk/drivers/char/ip2/i2ellis.h index fb6df2456018..c88a64e527aa 100644 --- a/trunk/drivers/char/ip2/i2ellis.h +++ b/trunk/drivers/char/ip2/i2ellis.h @@ -511,6 +511,7 @@ typedef void (*delayFunc_t)(unsigned int); // // Initialization of a board & structure is in four (five!) parts: // +// 0) iiEllisInit() - Initialize iiEllis subsystem. // 1) iiSetAddress() - Define the board address & delay function for a board. // 2) iiReset() - Reset the board (provided it exists) // -- Note you may do this to several boards -- @@ -522,6 +523,7 @@ typedef void (*delayFunc_t)(unsigned int); // loadware. To change loadware, you must begin again with step 2, resetting // the board again (step 1 not needed). +static void iiEllisInit(void); static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); static int iiReset(i2eBordStrPtr); static int iiResetDelay(i2eBordStrPtr); diff --git a/trunk/drivers/char/ip2/ip2base.c b/trunk/drivers/char/ip2/ip2base.c new file mode 100644 index 000000000000..8155e247c04b --- /dev/null +++ b/trunk/drivers/char/ip2/ip2base.c @@ -0,0 +1,108 @@ +// ip2.c +// This is a dummy module to make the firmware available when needed +// and allows it to be unloaded when not. Rumor is the __initdata +// macro doesn't always works on all platforms so we use this kludge. +// If not compiled as a module it just makes fip_firm avaliable then +// __initdata should work as advertized +// + +#include +#include +#include + +#ifndef __init +#define __init +#endif +#ifndef __initfunc +#define __initfunc(a) a +#endif +#ifndef __initdata +#define __initdata +#endif + +#include "ip2types.h" + +int +ip2_loadmain(int *, int *); // ref into ip2main.c + +/* Note: Add compiled in defaults to these arrays, not to the structure + in ip2.h any longer. That structure WILL get overridden + by these values, or command line values, or insmod values!!! =mhw= +*/ +static int io[IP2_MAX_BOARDS]= { 0, 0, 0, 0 }; +static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; + +static int poll_only = 0; + +MODULE_AUTHOR("Doug McNash"); +MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); +module_param_array(irq, int, NULL, 0); +MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards"); +module_param_array(io, int, NULL, 0); +MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards"); +module_param(poll_only, bool, 0); +MODULE_PARM_DESC(poll_only,"Do not use card interrupts"); + + +static int __init ip2_init(void) +{ + if( poll_only ) { + /* Hard lock the interrupts to zero */ + irq[0] = irq[1] = irq[2] = irq[3] = 0; + } + + return ip2_loadmain(io, irq); +} +module_init(ip2_init); + +MODULE_LICENSE("GPL"); + +#ifndef MODULE +/****************************************************************************** + * ip2_setup: + * str: kernel command line string + * + * Can't autoprobe the boards so user must specify configuration on + * kernel command line. Sane people build it modular but the others + * come here. + * + * Alternating pairs of io,irq for up to 4 boards. + * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 + * + * io=0 => No board + * io=1 => PCI + * io=2 => EISA + * else => ISA I/O address + * + * irq=0 or invalid for ISA will revert to polling mode + * + * Any value = -1, do not overwrite compiled in value. + * + ******************************************************************************/ +static int __init ip2_setup(char *str) +{ + int ints[10]; /* 4 boards, 2 parameters + 2 */ + int i, j; + + str = get_options (str, ARRAY_SIZE(ints), ints); + + for( i = 0, j = 1; i < 4; i++ ) { + if( j > ints[0] ) { + break; + } + if( ints[j] >= 0 ) { + io[i] = ints[j]; + } + j++; + if( j > ints[0] ) { + break; + } + if( ints[j] >= 0 ) { + irq[i] = ints[j]; + } + j++; + } + return 1; +} +__setup("ip2=", ip2_setup); +#endif /* !MODULE */ diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index 70e0ebc30bd0..689f9dcd3b86 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -150,12 +150,15 @@ static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); /*************/ /* String constants to identify ourselves */ -static const char pcName[] = "Computone IntelliPort Plus multiport driver"; -static const char pcVersion[] = "1.2.14"; +static char *pcName = "Computone IntelliPort Plus multiport driver"; +static char *pcVersion = "1.2.14"; /* String constants for port names */ -static const char pcDriver_name[] = "ip2"; -static const char pcIpl[] = "ip2ipl"; +static char *pcDriver_name = "ip2"; +static char *pcIpl = "ip2ipl"; + +// cheezy kludge or genius - you decide? +int ip2_loadmain(int *, int *); /***********************/ /* Function Prototypes */ @@ -237,8 +240,8 @@ static const struct file_operations ip2_ipl = { .open = ip2_ipl_open, }; -static unsigned long irq_counter; -static unsigned long bh_counter; +static unsigned long irq_counter = 0; +static unsigned long bh_counter = 0; // Use immediate queue to service interrupts #define USE_IQI @@ -249,6 +252,7 @@ static unsigned long bh_counter; */ #define POLL_TIMEOUT (jiffies + 1) static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); +static char TimerOn; #ifdef IP2DEBUG_TRACE /* Trace (debug) buffer data */ @@ -264,8 +268,8 @@ static int tracewrap; /**********/ #if defined(MODULE) && defined(IP2DEBUG_OPEN) -#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ - tty->name,(pCh->flags), \ +#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \ + tty->name,(pCh->flags),ip2_tty_driver->refcount, \ tty->count,/*GET_USE_COUNT(module)*/0,s) #else #define DBG_CNT(s) @@ -283,9 +287,8 @@ static int tracewrap; MODULE_AUTHOR("Doug McNash"); MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); -MODULE_LICENSE("GPL"); -static int poll_only; +static int poll_only = 0; static int Eisa_irq; static int Eisa_slot; @@ -294,46 +297,34 @@ static int iindx; static char rirqs[IP2_MAX_BOARDS]; static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; -/* Note: Add compiled in defaults to these arrays, not to the structure - in ip2.h any longer. That structure WILL get overridden - by these values, or command line values, or insmod values!!! =mhw= -*/ -static int io[IP2_MAX_BOARDS]; -static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; - -MODULE_AUTHOR("Doug McNash"); -MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); -module_param_array(irq, int, NULL, 0); -MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards"); -module_param_array(io, int, NULL, 0); -MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); -module_param(poll_only, bool, 0); -MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); - /* for sysfs class support */ static struct class *ip2_class; -/* Some functions to keep track of what irqs we have */ +// Some functions to keep track of what irq's we have -static int __init is_valid_irq(int irq) +static int +is_valid_irq(int irq) { int *i = Valid_Irqs; - while (*i != 0 && *i != irq) + while ((*i != 0) && (*i != irq)) { i++; - - return *i; + } + return (*i); } -static void __init mark_requested_irq(char irq) +static void +mark_requested_irq( char irq ) { rirqs[iindx++] = irq; } -static int __exit clear_requested_irq(char irq) +#ifdef MODULE +static int +clear_requested_irq( char irq ) { int i; - for (i = 0; i < IP2_MAX_BOARDS; ++i) { + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if (rirqs[i] == irq) { rirqs[i] = 0; return 1; @@ -341,15 +332,17 @@ static int __exit clear_requested_irq(char irq) } return 0; } +#endif -static int have_requested_irq(char irq) +static int +have_requested_irq( char irq ) { - /* array init to zeros so 0 irq will not be requested as a side - * effect */ + // array init to zeros so 0 irq will not be requested as a side effect int i; - for (i = 0; i < IP2_MAX_BOARDS; ++i) + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if (rirqs[i] == irq) return 1; + } return 0; } @@ -368,45 +361,53 @@ static int have_requested_irq(char irq) /* handle subsequent installations of the driver. All memory allocated by the */ /* driver should be returned since it may be unloaded from memory. */ /******************************************************************************/ -static void __exit ip2_cleanup_module(void) +#ifdef MODULE +void __exit +ip2_cleanup_module(void) { int err; int i; - del_timer_sync(&PollTimer); +#ifdef IP2DEBUG_INIT + printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion ); +#endif + /* Stop poll timer if we had one. */ + if ( TimerOn ) { + del_timer ( &PollTimer ); + TimerOn = 0; + } /* Reset the boards we have. */ - for (i = 0; i < IP2_MAX_BOARDS; i++) - if (i2BoardPtrTable[i]) - iiReset(i2BoardPtrTable[i]); + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if ( i2BoardPtrTable[i] ) { + iiReset( i2BoardPtrTable[i] ); + } + } /* The following is done at most once, if any boards were installed. */ - for (i = 0; i < IP2_MAX_BOARDS; i++) { - if (i2BoardPtrTable[i]) { - iiResetDelay(i2BoardPtrTable[i]); + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if ( i2BoardPtrTable[i] ) { + iiResetDelay( i2BoardPtrTable[i] ); /* free io addresses and Tibet */ - release_region(ip2config.addr[i], 8); + release_region( ip2config.addr[i], 8 ); device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); - device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, - 4 * i + 1)); + device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); } /* Disable and remove interrupt handler. */ - if (ip2config.irq[i] > 0 && - have_requested_irq(ip2config.irq[i])) { - free_irq(ip2config.irq[i], (void *)&pcName); - clear_requested_irq(ip2config.irq[i]); + if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { + free_irq ( ip2config.irq[i], (void *)&pcName); + clear_requested_irq( ip2config.irq[i]); } } class_destroy(ip2_class); - err = tty_unregister_driver(ip2_tty_driver); - if (err) - printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", - err); + if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { + printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); + } put_tty_driver(ip2_tty_driver); unregister_chrdev(IP2_IPL_MAJOR, pcIpl); remove_proc_entry("ip2mem", NULL); - /* free memory */ + // free memory for (i = 0; i < IP2_MAX_BOARDS; i++) { void *pB; #ifdef CONFIG_PCI @@ -416,18 +417,24 @@ static void __exit ip2_cleanup_module(void) ip2config.pci_dev[i] = NULL; } #endif - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - kfree(pB); + if ((pB = i2BoardPtrTable[i]) != 0 ) { + kfree ( pB ); i2BoardPtrTable[i] = NULL; } - if (DevTableMem[i] != NULL) { - kfree(DevTableMem[i]); + if ((DevTableMem[i]) != NULL ) { + kfree ( DevTableMem[i] ); DevTableMem[i] = NULL; } } + + /* Cleanup the iiEllis subsystem. */ + iiEllisCleanup(); +#ifdef IP2DEBUG_INIT + printk (KERN_DEBUG "IP2 Unloaded\n" ); +#endif } module_exit(ip2_cleanup_module); +#endif /* MODULE */ static const struct tty_operations ip2_ops = { .open = ip2_open, @@ -487,168 +494,139 @@ static const struct firmware *ip2_request_firmware(void) return fw; } -#ifndef MODULE -/****************************************************************************** - * ip2_setup: - * str: kernel command line string - * - * Can't autoprobe the boards so user must specify configuration on - * kernel command line. Sane people build it modular but the others - * come here. - * - * Alternating pairs of io,irq for up to 4 boards. - * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 - * - * io=0 => No board - * io=1 => PCI - * io=2 => EISA - * else => ISA I/O address - * - * irq=0 or invalid for ISA will revert to polling mode - * - * Any value = -1, do not overwrite compiled in value. - * - ******************************************************************************/ -static int __init ip2_setup(char *str) -{ - int j, ints[10]; /* 4 boards, 2 parameters + 2 */ - unsigned int i; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - for (i = 0, j = 1; i < 4; i++) { - if (j > ints[0]) - break; - if (ints[j] >= 0) - io[i] = ints[j]; - j++; - if (j > ints[0]) - break; - if (ints[j] >= 0) - irq[i] = ints[j]; - j++; - } - return 1; -} -__setup("ip2=", ip2_setup); -#endif /* !MODULE */ - -static int __init ip2_loadmain(void) +int +ip2_loadmain(int *iop, int *irqp) { int i, j, box; int err = 0; + static int loaded; i2eBordStrPtr pB = NULL; int rc = -1; - struct pci_dev *pdev = NULL; + static struct pci_dev *pci_dev_i = NULL; const struct firmware *fw = NULL; - if (poll_only) { - /* Hard lock the interrupts to zero */ - irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; - } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); + ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); /* process command line arguments to modprobe or insmod i.e. iop & irqp */ /* irqp and iop should ALWAYS be specified now... But we check them individually just to be sure, anyways... */ - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - ip2config.addr[i] = io[i]; - if (irq[i] >= 0) - ip2config.irq[i] = irq[i]; - else - ip2config.irq[i] = 0; - /* This is a little bit of a hack. If poll_only=1 on command - line back in ip2.c OR all IRQs on all specified boards are - explicitly set to 0, then drop to poll only mode and override - PCI or EISA interrupts. This superceeds the old hack of - triggering if all interrupts were zero (like da default). - Still a hack but less prone to random acts of terrorism. - - What we really should do, now that the IRQ default is set - to -1, is to use 0 as a hard coded, do not probe. - - /\/\|=mhw=|\/\/ - */ - poll_only |= irq[i]; + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if (iop) { + ip2config.addr[i] = iop[i]; + if (irqp) { + if( irqp[i] >= 0 ) { + ip2config.irq[i] = irqp[i]; + } else { + ip2config.irq[i] = 0; + } + // This is a little bit of a hack. If poll_only=1 on command + // line back in ip2.c OR all IRQs on all specified boards are + // explicitly set to 0, then drop to poll only mode and override + // PCI or EISA interrupts. This superceeds the old hack of + // triggering if all interrupts were zero (like da default). + // Still a hack but less prone to random acts of terrorism. + // + // What we really should do, now that the IRQ default is set + // to -1, is to use 0 as a hard coded, do not probe. + // + // /\/\|=mhw=|\/\/ + poll_only |= irqp[i]; + } + } } poll_only = !poll_only; /* Announce our presence */ - printk(KERN_INFO "%s version %s\n", pcName, pcVersion); + printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); + + // ip2 can be unloaded and reloaded for no good reason + // we can't let that happen here or bad things happen + // second load hoses board but not system - fixme later + if (loaded) { + printk( KERN_INFO "Still loaded\n" ); + return 0; + } + loaded++; ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); if (!ip2_tty_driver) return -ENOMEM; + /* Initialise the iiEllis subsystem. */ + iiEllisInit(); + + /* Initialize arrays. */ + memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable ); + memset( DevTable, 0, sizeof DevTable ); + /* Initialise all the boards we can find (up to the maximum). */ - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - switch (ip2config.addr[i]) { + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + switch ( ip2config.addr[i] ) { case 0: /* skip this slot even if card is present */ break; default: /* ISA */ /* ISA address must be specified */ - if (ip2config.addr[i] < 0x100 || - ip2config.addr[i] > 0x3f8) { - printk(KERN_ERR "IP2: Bad ISA board %d " - "address %x\n", i, - ip2config.addr[i]); + if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) { + printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n", + i, ip2config.addr[i] ); ip2config.addr[i] = 0; - break; - } - ip2config.type[i] = ISA; - - /* Check for valid irq argument, set for polling if - * invalid */ - if (ip2config.irq[i] && - !is_valid_irq(ip2config.irq[i])) { - printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", - ip2config.irq[i]); - /* 0 is polling and is valid in that sense */ - ip2config.irq[i] = 0; + } else { + ip2config.type[i] = ISA; + + /* Check for valid irq argument, set for polling if invalid */ + if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) { + printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]); + ip2config.irq[i] = 0;// 0 is polling and is valid in that sense + } } break; case PCI: #ifdef CONFIG_PCI - { - u32 addr; - int status; + { + int status; - pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, - PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); - if (pdev == NULL) { - ip2config.addr[i] = 0; - printk(KERN_ERR "IP2: PCI board %d not " - "found\n", i); - break; - } + pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, + PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); + if (pci_dev_i != NULL) { + unsigned int addr; - if (pci_enable_device(pdev)) { - dev_err(&pdev->dev, "can't enable device\n"); - break; + if (pci_enable_device(pci_dev_i)) { + printk( KERN_ERR "IP2: can't enable PCI device at %s\n", + pci_name(pci_dev_i)); + break; + } + ip2config.type[i] = PCI; + ip2config.pci_dev[i] = pci_dev_get(pci_dev_i); + status = + pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); + if ( addr & 1 ) { + ip2config.addr[i]=(USHORT)(addr&0xfffe); + } else { + printk( KERN_ERR "IP2: PCI I/O address error\n"); + } + +// If the PCI BIOS assigned it, lets try and use it. If we +// can't acquire it or it screws up, deal with it then. + +// if (!is_valid_irq(pci_irq)) { +// printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); +// pci_irq = 0; +// } + ip2config.irq[i] = pci_dev_i->irq; + } else { // ann error + ip2config.addr[i] = 0; + printk(KERN_ERR "IP2: PCI board %d not found\n", i); + } } - ip2config.type[i] = PCI; - ip2config.pci_dev[i] = pci_dev_get(pdev); - status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, - &addr); - if (addr & 1) - ip2config.addr[i] = (USHORT)(addr & 0xfffe); - else - dev_err(&pdev->dev, "I/O address error\n"); - - ip2config.irq[i] = pdev->irq; - } #else - printk(KERN_ERR "IP2: PCI card specified but PCI " - "support not enabled.\n"); - printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " - "defined!\n"); + printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); + printk( KERN_ERR "IP2: configured in this kernel.\n"); + printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n"); #endif /* CONFIG_PCI */ break; case EISA: - ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); - if (ip2config.addr[i] != 0) { + if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) { /* Eisa_irq set as side effect, boo */ ip2config.type[i] = EISA; } @@ -656,32 +634,31 @@ static int __init ip2_loadmain(void) break; } /* switch */ } /* for */ - pci_dev_put(pdev); + if (pci_dev_i) + pci_dev_put(pci_dev_i); - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (ip2config.addr[i]) { + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if ( ip2config.addr[i] ) { pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); if (pB) { i2BoardPtrTable[i] = pB; - iiSetAddress(pB, ip2config.addr[i], - ii2DelayTimer); - iiReset(pB); - } else - printk(KERN_ERR "IP2: board memory allocation " - "error\n"); + iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); + iiReset( pB ); + } else { + printk(KERN_ERR "IP2: board memory allocation error\n"); + } } } - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - iiResetDelay(pB); + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if ( ( pB = i2BoardPtrTable[i] ) != NULL ) { + iiResetDelay( pB ); break; } } - for (i = 0; i < IP2_MAX_BOARDS; ++i) { + for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { /* We don't want to request the firmware unless we have at least one board */ - if (i2BoardPtrTable[i] != NULL) { + if ( i2BoardPtrTable[i] != NULL ) { if (!fw) fw = ip2_request_firmware(); if (!fw) @@ -692,7 +669,7 @@ static int __init ip2_loadmain(void) if (fw) release_firmware(fw); - ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); + ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); ip2_tty_driver->owner = THIS_MODULE; ip2_tty_driver->name = "ttyF"; @@ -703,23 +680,20 @@ static int __init ip2_loadmain(void) ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; ip2_tty_driver->init_termios = tty_std_termios; ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; - ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; + ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(ip2_tty_driver, &ip2_ops); - ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); + ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); - err = tty_register_driver(ip2_tty_driver); - if (err) { - printk(KERN_ERR "IP2: failed to register tty driver\n"); + /* Register the tty devices. */ + if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) { + printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err); put_tty_driver(ip2_tty_driver); - return err; /* leaking resources */ - } - - err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); - if (err) { - printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", - err); + return -EINVAL; + } else + /* Register the IPL driver. */ + if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) { + printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); } else { /* create the sysfs class */ ip2_class = class_create(THIS_MODULE, "ip2"); @@ -731,86 +705,84 @@ static int __init ip2_loadmain(void) /* Register the read_procmem thing */ if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { printk(KERN_ERR "IP2: failed to register read_procmem\n"); - return -EIO; /* leaking resources */ - } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); - /* Register the interrupt handler or poll handler, depending upon the - * specified interrupt. - */ + } else { - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (ip2config.addr[i] == 0) - continue; + ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 ); + /* Register the interrupt handler or poll handler, depending upon the + * specified interrupt. + */ - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - device_create(ip2_class, NULL, - MKDEV(IP2_IPL_MAJOR, 4 * i), - NULL, "ipl%d", i); - device_create(ip2_class, NULL, - MKDEV(IP2_IPL_MAJOR, 4 * i + 1), - NULL, "stat%d", i); - - for (box = 0; box < ABS_MAX_BOXES; box++) - for (j = 0; j < ABS_BIGGEST_BOX; j++) - if (pB->i2eChannelMap[box] & (1 << j)) - tty_register_device( - ip2_tty_driver, - j + ABS_BIGGEST_BOX * - (box+i*ABS_MAX_BOXES), - NULL); - } + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if ( 0 == ip2config.addr[i] ) { + continue; + } - if (poll_only) { - /* Poll only forces driver to only use polling and - to ignore the probed PCI or EISA interrupts. */ - ip2config.irq[i] = CIR_POLL; - } - if (ip2config.irq[i] == CIR_POLL) { -retry: - if (!timer_pending(&PollTimer)) { - mod_timer(&PollTimer, POLL_TIMEOUT); - printk(KERN_INFO "IP2: polling\n"); + if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { + device_create_drvdata(ip2_class, NULL, + MKDEV(IP2_IPL_MAJOR, 4 * i), + NULL, "ipl%d", i); + device_create_drvdata(ip2_class, NULL, + MKDEV(IP2_IPL_MAJOR, 4 * i + 1), + NULL, "stat%d", i); + + for ( box = 0; box < ABS_MAX_BOXES; ++box ) + { + for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) + { + if ( pB->i2eChannelMap[box] & (1 << j) ) + { + tty_register_device(ip2_tty_driver, + j + ABS_BIGGEST_BOX * + (box+i*ABS_MAX_BOXES), NULL); + } + } + } } - } else { - if (have_requested_irq(ip2config.irq[i])) - continue; - rc = request_irq(ip2config.irq[i], ip2_interrupt, - IP2_SA_FLAGS | - (ip2config.type[i] == PCI ? IRQF_SHARED : 0), - pcName, i2BoardPtrTable[i]); - if (rc) { - printk(KERN_ERR "IP2: request_irq failed: " - "error %d\n", rc); + + if (poll_only) { +// Poll only forces driver to only use polling and +// to ignore the probed PCI or EISA interrupts. ip2config.irq[i] = CIR_POLL; - printk(KERN_INFO "IP2: Polling %ld/sec.\n", - (POLL_TIMEOUT - jiffies)); - goto retry; } - mark_requested_irq(ip2config.irq[i]); - /* Initialise the interrupt handler bottom half - * (aka slih). */ + if ( ip2config.irq[i] == CIR_POLL ) { +retry: + if (!TimerOn) { + PollTimer.expires = POLL_TIMEOUT; + add_timer ( &PollTimer ); + TimerOn = 1; + printk( KERN_INFO "IP2: polling\n"); + } + } else { + if (have_requested_irq(ip2config.irq[i])) + continue; + rc = request_irq( ip2config.irq[i], ip2_interrupt, + IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), + pcName, i2BoardPtrTable[i]); + if (rc) { + printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); + ip2config.irq[i] = CIR_POLL; + printk( KERN_INFO "IP2: Polling %ld/sec.\n", + (POLL_TIMEOUT - jiffies)); + goto retry; + } + mark_requested_irq(ip2config.irq[i]); + /* Initialise the interrupt handler bottom half (aka slih). */ + } } - } - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (i2BoardPtrTable[i]) { - /* set and enable board interrupt */ - set_irq(i, ip2config.irq[i]); + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { + if ( i2BoardPtrTable[i] ) { + set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */ + } } } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); - - return 0; + ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); + goto out; out_chrdev: unregister_chrdev(IP2_IPL_MAJOR, "ip2"); - /* unregister and put tty here */ +out: return err; } -module_init(ip2_loadmain); /******************************************************************************/ /* Function: ip2_init_board() */ @@ -1227,8 +1199,9 @@ ip2_polled_interrupt(void) { int i; i2eBordStrPtr pB; + const int irq = 0; - ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0); + ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); /* Service just the boards on the list using this irq */ for( i = 0; i < i2nBoards; ++i ) { @@ -1237,8 +1210,9 @@ ip2_polled_interrupt(void) // Only process those boards which match our IRQ. // IRQ = 0 for polled boards, we won't poll "IRQ" boards - if (pB && pB->i2eUsingIrq == 0) + if ( pB && (pB->i2eUsingIrq == irq) ) { ip2_irq_work(pB); + } } ++irq_counter; @@ -1276,12 +1250,16 @@ ip2_poll(unsigned long arg) { ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); + TimerOn = 0; // it's the truth but not checked in service + // Just polled boards, IRQ = 0 will hit all non-interrupt boards. // It will NOT poll boards handled by hard interrupts. // The issue of queued BH interrupts is handled in ip2_interrupt(). ip2_polled_interrupt(); - mod_timer(&PollTimer, POLL_TIMEOUT); + PollTimer.expires = POLL_TIMEOUT; + add_timer( &PollTimer ); + TimerOn = 1; ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); } @@ -2893,7 +2871,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) case 13: switch ( cmd ) { case 64: /* Driver - ip2stat */ - rc = put_user(-1, pIndex++ ); + rc = put_user(ip2_tty_driver->refcount, pIndex++ ); rc = put_user(irq_counter, pIndex++ ); rc = put_user(bh_counter, pIndex++ ); break; diff --git a/trunk/drivers/char/ipmi/ipmi_devintf.c b/trunk/drivers/char/ipmi/ipmi_devintf.c index 835a33c8d5f5..64e1c169e826 100644 --- a/trunk/drivers/char/ipmi/ipmi_devintf.c +++ b/trunk/drivers/char/ipmi/ipmi_devintf.c @@ -871,7 +871,7 @@ static void ipmi_new_smi(int if_num, struct device *device) entry->dev = dev; mutex_lock(®_list_mutex); - device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num); + device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num); list_add(&entry->link, ®_list); mutex_unlock(®_list_mutex); } diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 3123bf57ad91..8e8afb6141f9 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -2695,7 +2695,7 @@ static __devinit void default_find_bmc(void) for (i = 0; ; i++) { if (!ipmi_defaults[i].port) break; -#ifdef CONFIG_PPC +#ifdef CONFIG_PPC_MERGE if (check_legacy_ioport(ipmi_defaults[i].port)) continue; #endif diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 7d30ee1d3fca..8f7cc190b62d 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -421,16 +421,17 @@ static void isicom_tx(unsigned long _data) if (retries >= 100) goto unlock; - tty = tty_port_tty_get(&port->port); - if (tty == NULL) - goto put_unlock; - for (; count > 0; count--, port++) { /* port not active or tx disabled to force flow control */ if (!(port->port.flags & ASYNC_INITIALIZED) || !(port->status & ISI_TXOK)) continue; + tty = port->port.tty; + + if (tty == NULL) + continue; + txcount = min_t(short, TX_SIZE, port->xmit_cnt); if (txcount <= 0 || tty->stopped || tty->hw_stopped) continue; @@ -488,8 +489,6 @@ static void isicom_tx(unsigned long _data) tty_wakeup(tty); } -put_unlock: - tty_kref_put(tty); unlock: spin_unlock_irqrestore(&isi_card[card].card_lock, flags); /* schedule another tx for hopefully in about 10ms */ @@ -548,7 +547,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty == NULL) { word_count = byte_count >> 1; while (byte_count > 1) { @@ -589,7 +588,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) } if (port->port.flags & ASYNC_CTS_FLOW) { - if (tty->hw_stopped) { + if (port->port.tty->hw_stopped) { if (header & ISI_CTS) { port->port.tty->hw_stopped = 0; /* start tx ing */ @@ -598,7 +597,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) tty_wakeup(tty); } } else if (!(header & ISI_CTS)) { - tty->hw_stopped = 1; + port->port.tty->hw_stopped = 1; /* stop tx ing */ port->status &= ~(ISI_TXOK | ISI_CTS); } @@ -661,21 +660,24 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) } outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); - tty_kref_put(tty); return IRQ_HANDLED; } -static void isicom_config_port(struct tty_struct *tty) +static void isicom_config_port(struct isi_port *port) { - struct isi_port *port = tty->driver_data; struct isi_board *card = port->card; + struct tty_struct *tty; unsigned long baud; unsigned long base = card->base; u16 channel_setup, channel = port->channel, shift_count = card->shift_count; unsigned char flow_ctrl; + tty = port->port.tty; + + if (tty == NULL) + return; /* FIXME: Switch to new tty baud API */ baud = C_BAUD(tty); if (baud & CBAUDEX) { @@ -688,7 +690,7 @@ static void isicom_config_port(struct tty_struct *tty) /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ if (baud < 1 || baud > 4) - tty->termios->c_cflag &= ~CBAUDEX; + port->port.tty->termios->c_cflag &= ~CBAUDEX; else baud += 15; } @@ -795,9 +797,8 @@ static inline void isicom_setup_board(struct isi_board *bp) spin_unlock_irqrestore(&bp->card_lock, flags); } -static int isicom_setup_port(struct tty_struct *tty) +static int isicom_setup_port(struct isi_port *port) { - struct isi_port *port = tty->driver_data; struct isi_board *card = port->card; unsigned long flags; @@ -807,7 +808,8 @@ static int isicom_setup_port(struct tty_struct *tty) return -ENOMEM; spin_lock_irqsave(&card->card_lock, flags); - clear_bit(TTY_IO_ERROR, &tty->flags); + if (port->port.tty) + clear_bit(TTY_IO_ERROR, &port->port.tty->flags); if (port->port.count == 1) card->count++; @@ -821,7 +823,7 @@ static int isicom_setup_port(struct tty_struct *tty) InterruptTheCard(card->base); } - isicom_config_port(tty); + isicom_config_port(port); port->port.flags |= ASYNC_INITIALIZED; spin_unlock_irqrestore(&card->card_lock, flags); @@ -932,8 +934,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) port->port.count++; tty->driver_data = port; - tty_port_tty_set(&port->port, tty); - error = isicom_setup_port(tty); + port->port.tty = tty; + error = isicom_setup_port(port); if (error == 0) error = block_til_ready(tty, filp, port); return error; @@ -953,17 +955,15 @@ static void isicom_shutdown_port(struct isi_port *port) struct isi_board *card = port->card; struct tty_struct *tty; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; - if (!(port->port.flags & ASYNC_INITIALIZED)) { - tty_kref_put(tty); + if (!(port->port.flags & ASYNC_INITIALIZED)) return; - } tty_port_free_xmit_buf(&port->port); port->port.flags &= ~ASYNC_INITIALIZED; /* 3rd October 2000 : Vinayak P Risbud */ - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; /*Fix done by Anil .S on 30-04-2001 remote login through isi port has dtr toggle problem @@ -1243,10 +1243,9 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file, return 0; } -static int isicom_set_serial_info(struct tty_struct *tty, - struct serial_struct __user *info) +static int isicom_set_serial_info(struct isi_port *port, + struct serial_struct __user *info) { - struct isi_port *port = tty->driver_data; struct serial_struct newinfo; int reconfig_port; @@ -1277,7 +1276,7 @@ static int isicom_set_serial_info(struct tty_struct *tty, if (reconfig_port) { unsigned long flags; spin_lock_irqsave(&port->card->card_lock, flags); - isicom_config_port(tty); + isicom_config_port(port); spin_unlock_irqrestore(&port->card->card_lock, flags); } unlock_kernel(); @@ -1319,7 +1318,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, return isicom_get_serial_info(port, argp); case TIOCSSERIAL: - return isicom_set_serial_info(tty, argp); + return isicom_set_serial_info(port, argp); default: return -ENOIOCTLCMD; @@ -1342,7 +1341,7 @@ static void isicom_set_termios(struct tty_struct *tty, return; spin_lock_irqsave(&port->card->card_lock, flags); - isicom_config_port(tty); + isicom_config_port(port); spin_unlock_irqrestore(&port->card->card_lock, flags); if ((old_termios->c_cflag & CRTSCTS) && @@ -1420,7 +1419,7 @@ static void isicom_hangup(struct tty_struct *tty) port->port.count = 0; port->port.flags &= ~ASYNC_NORMAL_ACTIVE; - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; wake_up_interruptible(&port->port.open_wait); } diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index 44e5d60f517e..843a2afaf204 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -623,25 +623,24 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); static void stli_poll(unsigned long arg); static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); -static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp); +static int stli_initopen(struct stlibrd *brdp, struct stliport *portp); static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); -static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, - struct stliport *portp, struct file *filp); -static int stli_setport(struct tty_struct *tty); +static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp); +static int stli_setport(struct stliport *portp); static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); -static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); +static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); static long stli_mktiocm(unsigned long sigvalue); static void stli_read(struct stlibrd *brdp, struct stliport *portp); static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); -static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp); +static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp); static int stli_getbrdstats(combrd_t __user *bp); -static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp); -static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp); +static int stli_getportstats(struct stliport *portp, comstats_t __user *cp); +static int stli_portcmdstats(struct stliport *portp); static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); static int stli_getportstruct(struct stliport __user *arg); static int stli_getbrdstruct(struct stlibrd __user *arg); @@ -732,16 +731,12 @@ static void stli_cleanup_ports(struct stlibrd *brdp) { struct stliport *portp; unsigned int j; - struct tty_struct *tty; for (j = 0; j < STL_MAXPORTS; j++) { portp = brdp->ports[j]; if (portp != NULL) { - tty = tty_port_tty_get(&portp->port); - if (tty != NULL) { - tty_hangup(tty); - tty_kref_put(tty); - } + if (portp->port.tty != NULL) + tty_hangup(portp->port.tty); kfree(portp); } } @@ -829,7 +824,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) * requires several commands to the board we will need to wait for any * other open that is already initializing the port. */ - tty_port_tty_set(&portp->port, tty); + portp->port.tty = tty; tty->driver_data = portp; portp->port.count++; @@ -840,7 +835,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { set_bit(ST_INITIALIZING, &portp->state); - if ((rc = stli_initopen(tty, brdp, portp)) >= 0) { + if ((rc = stli_initopen(brdp, portp)) >= 0) { portp->port.flags |= ASYNC_INITIALIZED; clear_bit(TTY_IO_ERROR, &tty->flags); } @@ -869,7 +864,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) * then also we might have to wait for carrier. */ if (!(filp->f_flags & O_NONBLOCK)) { - if ((rc = stli_waitcarrier(tty, brdp, portp, filp)) != 0) + if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) return rc; } portp->port.flags |= ASYNC_NORMAL_ACTIVE; @@ -935,7 +930,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) stli_flushbuffer(tty); tty->closing = 0; - tty_port_tty_set(&portp->port, NULL); + portp->port.tty = NULL; if (portp->openwaitcnt) { if (portp->close_delay) @@ -957,9 +952,9 @@ static void stli_close(struct tty_struct *tty, struct file *filp) * this still all happens pretty quickly. */ -static int stli_initopen(struct tty_struct *tty, - struct stlibrd *brdp, struct stliport *portp) +static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) { + struct tty_struct *tty; asynotify_t nt; asyport_t aport; int rc; @@ -974,7 +969,10 @@ static int stli_initopen(struct tty_struct *tty, sizeof(asynotify_t), 0)) < 0) return rc; - stli_mkasyport(tty, portp, &aport, tty->termios); + tty = portp->port.tty; + if (tty == NULL) + return -ENODEV; + stli_mkasyport(portp, &aport, tty->termios); if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)) < 0) return rc; @@ -1163,21 +1161,22 @@ static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned l * waiting for the command to complete - so must have user context. */ -static int stli_setport(struct tty_struct *tty) +static int stli_setport(struct stliport *portp) { - struct stliport *portp = tty->driver_data; struct stlibrd *brdp; asyport_t aport; if (portp == NULL) return -ENODEV; + if (portp->port.tty == NULL) + return -ENODEV; if (portp->brdnr >= stli_nrbrds) return -ENODEV; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) return -ENODEV; - stli_mkasyport(tty, portp, &aport, tty->termios); + stli_mkasyport(portp, &aport, portp->port.tty->termios); return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); } @@ -1188,8 +1187,7 @@ static int stli_setport(struct tty_struct *tty) * maybe because if we are clocal then we don't need to wait... */ -static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, - struct stliport *portp, struct file *filp) +static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp) { unsigned long flags; int rc, doclocal; @@ -1197,7 +1195,7 @@ static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, rc = 0; doclocal = 0; - if (tty->termios->c_cflag & CLOCAL) + if (portp->port.tty->termios->c_cflag & CLOCAL) doclocal++; spin_lock_irqsave(&stli_lock, flags); @@ -1375,6 +1373,8 @@ static void stli_flushchars(struct tty_struct *tty) stli_txcookrealsize = 0; stli_txcooktty = NULL; + if (tty == NULL) + return; if (cooktty == NULL) return; if (tty != cooktty) @@ -1572,11 +1572,10 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s * just quietly ignore any requests to change irq, etc. */ -static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp) +static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp) { struct serial_struct sio; int rc; - struct stliport *portp = tty->driver_data; if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) return -EFAULT; @@ -1595,7 +1594,7 @@ static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *s portp->closing_wait = sio.closing_wait; portp->custom_divisor = sio.custom_divisor; - if ((rc = stli_setport(tty)) < 0) + if ((rc = stli_setport(portp)) < 0) return rc; return 0; } @@ -1686,17 +1685,17 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm rc = stli_getserial(portp, argp); break; case TIOCSSERIAL: - rc = stli_setserial(tty, argp); + rc = stli_setserial(portp, argp); break; case STL_GETPFLAG: rc = put_user(portp->pflag, (unsigned __user *)argp); break; case STL_SETPFLAG: if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) - stli_setport(tty); + stli_setport(portp); break; case COM_GETPORTSTATS: - rc = stli_getportstats(tty, portp, argp); + rc = stli_getportstats(portp, argp); break; case COM_CLRPORTSTATS: rc = stli_clrportstats(portp, argp); @@ -1730,6 +1729,8 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) struct ktermios *tiosp; asyport_t aport; + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1741,7 +1742,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) tiosp = tty->termios; - stli_mkasyport(tty, portp, &aport, tiosp); + stli_mkasyport(portp, &aport, tiosp); stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, @@ -1853,7 +1854,7 @@ static void stli_hangup(struct tty_struct *tty) clear_bit(ST_TXBUSY, &portp->state); clear_bit(ST_RXSTOP, &portp->state); set_bit(TTY_IO_ERROR, &tty->flags); - tty_port_tty_set(&portp->port, NULL); + portp->port.tty = NULL; portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; portp->port.count = 0; spin_unlock_irqrestore(&stli_lock, flags); @@ -1934,6 +1935,8 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout) struct stliport *portp; unsigned long tend; + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1995,7 +1998,7 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn char *sp, *uart; int rc, cnt; - rc = stli_portcmdstats(NULL, portp); + rc = stli_portcmdstats(portp); uart = "UNKNOWN"; if (brdp->state & BST_STARTED) { @@ -2185,7 +2188,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) if (test_bit(ST_RXSTOP, &portp->state)) return; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if (tty == NULL) return; @@ -2227,7 +2230,6 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) set_bit(ST_RXING, &portp->state); tty_schedule_flip(tty); - tty_kref_put(tty); } /*****************************************************************************/ @@ -2360,7 +2362,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) if (ap->notify) { nt = ap->changed; ap->notify = 0; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if (nt.signal & SG_DCD) { oldsigs = portp->sigs; @@ -2397,7 +2399,6 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) tty_schedule_flip(tty); } } - tty_kref_put(tty); if (nt.data & DT_RXBUSY) { donerx++; @@ -2534,15 +2535,14 @@ static void stli_poll(unsigned long arg) * the slave. */ -static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, - asyport_t *pp, struct ktermios *tiosp) +static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp) { memset(pp, 0, sizeof(asyport_t)); /* * Start of by setting the baud, char size, parity and stop bit info. */ - pp->baudout = tty_get_baud_rate(tty); + pp->baudout = tty_get_baud_rate(portp->port.tty); if ((tiosp->c_cflag & CBAUD) == B38400) { if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) pp->baudout = 57600; @@ -2695,7 +2695,7 @@ static int stli_initports(struct stlibrd *brdp) printk("STALLION: failed to allocate port structure\n"); continue; } - tty_port_init(&portp->port); + portp->magic = STLI_PORTMAGIC; portp->portnr = i; portp->brdnr = brdp->brdnr; @@ -4220,7 +4220,7 @@ static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, * what port to get stats for (used through board control device). */ -static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) +static int stli_portcmdstats(struct stliport *portp) { unsigned long flags; struct stlibrd *brdp; @@ -4249,15 +4249,15 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) stli_comstats.flags = portp->port.flags; spin_lock_irqsave(&brd_lock, flags); - if (tty != NULL) { - if (portp->port.tty == tty) { - stli_comstats.ttystate = tty->flags; + if (portp->port.tty != NULL) { + if (portp->port.tty->driver_data == portp) { + stli_comstats.ttystate = portp->port.tty->flags; stli_comstats.rxbuffered = -1; - if (tty->termios != NULL) { - stli_comstats.cflags = tty->termios->c_cflag; - stli_comstats.iflags = tty->termios->c_iflag; - stli_comstats.oflags = tty->termios->c_oflag; - stli_comstats.lflags = tty->termios->c_lflag; + if (portp->port.tty->termios != NULL) { + stli_comstats.cflags = portp->port.tty->termios->c_cflag; + stli_comstats.iflags = portp->port.tty->termios->c_iflag; + stli_comstats.oflags = portp->port.tty->termios->c_oflag; + stli_comstats.lflags = portp->port.tty->termios->c_lflag; } } } @@ -4294,8 +4294,7 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) * what port to get stats for (used through board control device). */ -static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, - comstats_t __user *cp) +static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) { struct stlibrd *brdp; int rc; @@ -4313,7 +4312,7 @@ static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, if (!brdp) return -ENODEV; - if ((rc = stli_portcmdstats(tty, portp)) < 0) + if ((rc = stli_portcmdstats(portp)) < 0) return rc; return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? @@ -4428,7 +4427,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un switch (cmd) { case COM_GETPORTSTATS: - rc = stli_getportstats(NULL, NULL, argp); + rc = stli_getportstats(NULL, argp); done++; break; case COM_CLRPORTSTATS: @@ -4600,8 +4599,9 @@ static int __init istallion_module_init(void) istallion_class = class_create(THIS_MODULE, "staliomem"); for (i = 0; i < 4; i++) - device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), - NULL, "staliomem%d", i); + device_create_drvdata(istallion_class, NULL, + MKDEV(STL_SIOMEMMAJOR, i), + NULL, "staliomem%d", i); return 0; err_deinit: diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index de26a978fbdd..7b3a212c86b1 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) return; } - if (keycode >= NR_KEYS) + if (keycode > NR_KEYS) if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); else diff --git a/trunk/drivers/char/lp.c b/trunk/drivers/char/lp.c index e444c2dba160..3f2719b9f77b 100644 --- a/trunk/drivers/char/lp.c +++ b/trunk/drivers/char/lp.c @@ -813,8 +813,8 @@ static int lp_register(int nr, struct parport *port) if (reset) lp_reset(nr); - device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL, - "lp%d", nr); + device_create_drvdata(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL, + "lp%d", nr); printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index 6431f6921a67..672b08e694d0 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -992,9 +992,9 @@ static int __init chr_dev_init(void) mem_class = class_create(THIS_MODULE, "mem"); for (i = 0; i < ARRAY_SIZE(devlist); i++) - device_create(mem_class, NULL, - MKDEV(MEM_MAJOR, devlist[i].minor), NULL, - devlist[i].name); + device_create_drvdata(mem_class, NULL, + MKDEV(MEM_MAJOR, devlist[i].minor), + NULL, devlist[i].name); return 0; } diff --git a/trunk/drivers/char/misc.c b/trunk/drivers/char/misc.c index a5e0db9d7662..999aa779c08a 100644 --- a/trunk/drivers/char/misc.c +++ b/trunk/drivers/char/misc.c @@ -217,8 +217,8 @@ int misc_register(struct miscdevice * misc) misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); dev = MKDEV(MISC_MAJOR, misc->minor); - misc->this_device = device_create(misc_class, misc->parent, dev, NULL, - "%s", misc->name); + misc->this_device = device_create_drvdata(misc_class, misc->parent, + dev, NULL, "%s", misc->name); if (IS_ERR(misc->this_device)) { err = PTR_ERR(misc->this_device); goto out; diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 12d327a2c9ba..d3d7864e0c1e 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -205,7 +205,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, static void moxa_poll(unsigned long); static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); static void moxa_setup_empty_event(struct tty_struct *); -static void moxa_shut_down(struct tty_struct *); +static void moxa_shut_down(struct moxa_port *); /* * moxa board interface functions: */ @@ -217,7 +217,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int); static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); static int MoxaPortLineStatus(struct moxa_port *); static void MoxaPortFlushData(struct moxa_port *, int); -static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); +static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int); static int MoxaPortReadData(struct moxa_port *); static int MoxaPortTxQueue(struct moxa_port *); static int MoxaPortRxQueue(struct moxa_port *); @@ -332,7 +332,6 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, for (i = 0; i < MAX_BOARDS; i++) { p = moxa_boards[i].ports; for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { - struct tty_struct *ttyp; memset(&tmp, 0, sizeof(tmp)); if (!moxa_boards[i].ready) goto copy; @@ -345,12 +344,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, if (status & 4) tmp.dcd = 1; - ttyp = tty_port_tty_get(&p->port); - if (!ttyp || !ttyp->termios) + if (!p->port.tty || !p->port.tty->termios) tmp.cflag = p->cflag; else - tmp.cflag = ttyp->termios->c_cflag; - tty_kref_put(tty); + tmp.cflag = p->port.tty->termios->c_cflag; copy: if (copy_to_user(argm, &tmp, sizeof(tmp))) { mutex_unlock(&moxa_openlock); @@ -513,7 +510,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr, size_t len) { void __iomem *baseAddr = brd->basemem; - const __le16 *uptr = ptr; + const u16 *uptr = ptr; size_t wlen, len2, j; unsigned long key, loadbuf, loadlen, checksum, checksum_ok; unsigned int i, retry; @@ -883,14 +880,8 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) /* pci hot-un-plug support */ for (a = 0; a < brd->numPorts; a++) - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { - struct tty_struct *tty = tty_port_tty_get( - &brd->ports[a].port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } + if (brd->ports[a].port.flags & ASYNC_INITIALIZED) + tty_hangup(brd->ports[a].port.tty); while (1) { opened = 0; for (a = 0; a < brd->numPorts; a++) @@ -1105,14 +1096,13 @@ static void __exit moxa_exit(void) module_init(moxa_init); module_exit(moxa_exit); -static void moxa_close_port(struct tty_struct *tty) +static void moxa_close_port(struct moxa_port *ch) { - struct moxa_port *ch = tty->driver_data; - moxa_shut_down(tty); + moxa_shut_down(ch); MoxaPortFlushData(ch, 2); ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; - tty->driver_data = NULL; - tty_port_tty_set(&ch->port, NULL); + ch->port.tty->driver_data = NULL; + ch->port.tty = NULL; } static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, @@ -1171,7 +1161,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; ch->port.count++; tty->driver_data = ch; - tty_port_tty_set(&ch->port, tty); + ch->port.tty = tty; if (!(ch->port.flags & ASYNC_INITIALIZED)) { ch->statusflags = 0; moxa_set_tty_param(tty, tty->termios); @@ -1189,7 +1179,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) if (retval) { if (ch->port.count) /* 0 means already hung up... */ if (--ch->port.count == 0) - moxa_close_port(tty); + moxa_close_port(ch); } else ch->port.flags |= ASYNC_NORMAL_ACTIVE; mutex_unlock(&moxa_openlock); @@ -1229,7 +1219,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ } - moxa_close_port(tty); + moxa_close_port(ch); unlock: mutex_unlock(&moxa_openlock); } @@ -1244,7 +1234,7 @@ static int moxa_write(struct tty_struct *tty, return 0; spin_lock_bh(&moxa_lock); - len = MoxaPortWriteData(tty, buf, count); + len = MoxaPortWriteData(ch, buf, count); spin_unlock_bh(&moxa_lock); ch->statusflags |= LOWWAIT; @@ -1419,7 +1409,7 @@ static void moxa_hangup(struct tty_struct *tty) return; } ch->port.count = 0; - moxa_close_port(tty); + moxa_close_port(ch); mutex_unlock(&moxa_openlock); wake_up_interruptible(&ch->port.open_wait); @@ -1427,14 +1417,11 @@ static void moxa_hangup(struct tty_struct *tty) static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) { - struct tty_struct *tty; dcd = !!dcd; - if (dcd != p->DCDState) { - tty = tty_port_tty_get(&p->port); - if (tty && C_CLOCAL(tty) && !dcd) - tty_hangup(tty); - tty_kref_put(tty); + if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) { + if (!dcd) + tty_hangup(p->port.tty); } p->DCDState = dcd; } @@ -1442,7 +1429,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) static int moxa_poll_port(struct moxa_port *p, unsigned int handle, u16 __iomem *ip) { - struct tty_struct *tty = tty_port_tty_get(&p->port); + struct tty_struct *tty = p->port.tty; void __iomem *ofsAddr; unsigned int inited = p->port.flags & ASYNC_INITIALIZED; u16 intr; @@ -1489,7 +1476,6 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, tty_insert_flip_char(tty, 0, TTY_BREAK); tty_schedule_flip(tty); } - tty_kref_put(tty); if (intr & IntrLine) moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); @@ -1574,9 +1560,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty) spin_unlock_bh(&moxa_lock); } -static void moxa_shut_down(struct tty_struct *tty) +static void moxa_shut_down(struct moxa_port *ch) { - struct moxa_port *ch = tty->driver_data; + struct tty_struct *tp = ch->port.tty; if (!(ch->port.flags & ASYNC_INITIALIZED)) return; @@ -1586,7 +1572,7 @@ static void moxa_shut_down(struct tty_struct *tty) /* * If we're a modem control device and HUPCL is on, drop RTS & DTR. */ - if (C_HUPCL(tty)) + if (C_HUPCL(tp)) MoxaPortLineCtrl(ch, 0, 0); spin_lock_bh(&moxa_lock); @@ -1967,10 +1953,9 @@ static int MoxaPortLineStatus(struct moxa_port *port) return val; } -static int MoxaPortWriteData(struct tty_struct *tty, +static int MoxaPortWriteData(struct moxa_port *port, const unsigned char *buffer, int len) { - struct moxa_port *port = tty->driver_data; void __iomem *baseAddr, *ofsAddr, *ofs; unsigned int c, total; u16 head, tail, tx_mask, spage, epage; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 8beef50f95a0..b638403e8e9c 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -610,13 +610,15 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, return 0; } -static int mxser_set_baud(struct tty_struct *tty, long newspd) +static int mxser_set_baud(struct mxser_port *info, long newspd) { - struct mxser_port *info = tty->driver_data; int quot = 0, baud; unsigned char cval; - if (!info->ioaddr) + if (!info->port.tty || !info->port.tty->termios) + return -1; + + if (!(info->ioaddr)) return -1; if (newspd > info->max_baud) @@ -624,13 +626,13 @@ static int mxser_set_baud(struct tty_struct *tty, long newspd) if (newspd == 134) { quot = 2 * info->baud_base / 269; - tty_encode_baud_rate(tty, 134, 134); + tty_encode_baud_rate(info->port.tty, 134, 134); } else if (newspd) { quot = info->baud_base / newspd; if (quot == 0) quot = 1; baud = info->baud_base/quot; - tty_encode_baud_rate(tty, baud, baud); + tty_encode_baud_rate(info->port.tty, baud, baud); } else { quot = 0; } @@ -656,7 +658,7 @@ static int mxser_set_baud(struct tty_struct *tty, long newspd) outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ #ifdef BOTHER - if (C_BAUD(tty) == BOTHER) { + if (C_BAUD(info->port.tty) == BOTHER) { quot = info->baud_base % newspd; quot *= 8; if (quot % newspd > newspd / 2) { @@ -677,20 +679,21 @@ static int mxser_set_baud(struct tty_struct *tty, long newspd) * This routine is called to set the UART divisor registers to match * the specified baud rate for a serial port. */ -static int mxser_change_speed(struct tty_struct *tty, - struct ktermios *old_termios) +static int mxser_change_speed(struct mxser_port *info, + struct ktermios *old_termios) { - struct mxser_port *info = tty->driver_data; unsigned cflag, cval, fcr; int ret = 0; unsigned char status; - cflag = tty->termios->c_cflag; - if (!info->ioaddr) + if (!info->port.tty || !info->port.tty->termios) + return ret; + cflag = info->port.tty->termios->c_cflag; + if (!(info->ioaddr)) return ret; - if (mxser_set_baud_method[tty->index] == 0) - mxser_set_baud(tty, tty_get_baud_rate(tty)); + if (mxser_set_baud_method[info->port.tty->index] == 0) + mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); /* byte size and parity */ switch (cflag & CSIZE) { @@ -759,9 +762,9 @@ static int mxser_change_speed(struct tty_struct *tty, info->MCR |= UART_MCR_AFE; } else { status = inb(info->ioaddr + UART_MSR); - if (tty->hw_stopped) { + if (info->port.tty->hw_stopped) { if (status & UART_MSR_CTS) { - tty->hw_stopped = 0; + info->port.tty->hw_stopped = 0; if (info->type != PORT_16550A && !info->board->chip_flag) { outb(info->IER & ~UART_IER_THRI, @@ -771,11 +774,11 @@ static int mxser_change_speed(struct tty_struct *tty, outb(info->IER, info->ioaddr + UART_IER); } - tty_wakeup(tty); + tty_wakeup(info->port.tty); } } else { if (!(status & UART_MSR_CTS)) { - tty->hw_stopped = 1; + info->port.tty->hw_stopped = 1; if ((info->type != PORT_16550A) && (!info->board->chip_flag)) { info->IER &= ~UART_IER_THRI; @@ -801,21 +804,21 @@ static int mxser_change_speed(struct tty_struct *tty, * Set up parity check flag */ info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (I_INPCK(tty)) + if (I_INPCK(info->port.tty)) info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(tty) || I_PARMRK(tty)) + if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) info->read_status_mask |= UART_LSR_BI; info->ignore_status_mask = 0; - if (I_IGNBRK(tty)) { + if (I_IGNBRK(info->port.tty)) { info->ignore_status_mask |= UART_LSR_BI; info->read_status_mask |= UART_LSR_BI; /* * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ - if (I_IGNPAR(tty)) { + if (I_IGNPAR(info->port.tty)) { info->ignore_status_mask |= UART_LSR_OE | UART_LSR_PE | @@ -827,16 +830,16 @@ static int mxser_change_speed(struct tty_struct *tty, } } if (info->board->chip_flag) { - mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); - mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); - if (I_IXON(tty)) { + mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); + mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); + if (I_IXON(info->port.tty)) { mxser_enable_must_rx_software_flow_control( info->ioaddr); } else { mxser_disable_must_rx_software_flow_control( info->ioaddr); } - if (I_IXOFF(tty)) { + if (I_IXOFF(info->port.tty)) { mxser_enable_must_tx_software_flow_control( info->ioaddr); } else { @@ -852,8 +855,7 @@ static int mxser_change_speed(struct tty_struct *tty, return ret; } -static void mxser_check_modem_status(struct tty_struct *tty, - struct mxser_port *port, int status) +static void mxser_check_modem_status(struct mxser_port *port, int status) { /* update input line counters */ if (status & UART_MSR_TERI) @@ -872,11 +874,10 @@ static void mxser_check_modem_status(struct tty_struct *tty, wake_up_interruptible(&port->port.open_wait); } - tty = tty_port_tty_get(&port->port); if (port->port.flags & ASYNC_CTS_FLOW) { - if (tty->hw_stopped) { + if (port->port.tty->hw_stopped) { if (status & UART_MSR_CTS) { - tty->hw_stopped = 0; + port->port.tty->hw_stopped = 0; if ((port->type != PORT_16550A) && (!port->board->chip_flag)) { @@ -886,11 +887,11 @@ static void mxser_check_modem_status(struct tty_struct *tty, outb(port->IER, port->ioaddr + UART_IER); } - tty_wakeup(tty); + tty_wakeup(port->port.tty); } } else { if (!(status & UART_MSR_CTS)) { - tty->hw_stopped = 1; + port->port.tty->hw_stopped = 1; if (port->type != PORT_16550A && !port->board->chip_flag) { port->IER &= ~UART_IER_THRI; @@ -902,9 +903,8 @@ static void mxser_check_modem_status(struct tty_struct *tty, } } -static int mxser_startup(struct tty_struct *tty) +static int mxser_startup(struct mxser_port *info) { - struct mxser_port *info = tty->driver_data; unsigned long page; unsigned long flags; @@ -921,7 +921,8 @@ static int mxser_startup(struct tty_struct *tty) } if (!info->ioaddr || !info->type) { - set_bit(TTY_IO_ERROR, &tty->flags); + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); free_page(page); spin_unlock_irqrestore(&info->slock, flags); return 0; @@ -951,8 +952,8 @@ static int mxser_startup(struct tty_struct *tty) if (inb(info->ioaddr + UART_LSR) == 0xff) { spin_unlock_irqrestore(&info->slock, flags); if (capable(CAP_SYS_ADMIN)) { - if (tty) - set_bit(TTY_IO_ERROR, &tty->flags); + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); return 0; } else return -ENODEV; @@ -990,13 +991,14 @@ static int mxser_startup(struct tty_struct *tty) (void) inb(info->ioaddr + UART_IIR); (void) inb(info->ioaddr + UART_MSR); - clear_bit(TTY_IO_ERROR, &tty->flags); + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; /* * and set the speed of the serial port */ - mxser_change_speed(tty, NULL); + mxser_change_speed(info, NULL); info->port.flags |= ASYNC_INITIALIZED; spin_unlock_irqrestore(&info->slock, flags); @@ -1007,9 +1009,8 @@ static int mxser_startup(struct tty_struct *tty) * This routine will shutdown a serial port; interrupts maybe disabled, and * DTR is dropped if the hangup on close termio flag is on. */ -static void mxser_shutdown(struct tty_struct *tty) +static void mxser_shutdown(struct mxser_port *info) { - struct mxser_port *info = tty->driver_data; unsigned long flags; if (!(info->port.flags & ASYNC_INITIALIZED)) @@ -1034,7 +1035,7 @@ static void mxser_shutdown(struct tty_struct *tty) info->IER = 0; outb(0x00, info->ioaddr + UART_IER); - if (tty->termios->c_cflag & HUPCL) + if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); outb(info->MCR, info->ioaddr + UART_MCR); @@ -1050,7 +1051,8 @@ static void mxser_shutdown(struct tty_struct *tty) /* read data port to reset things */ (void) inb(info->ioaddr + UART_RX); - set_bit(TTY_IO_ERROR, &tty->flags); + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); info->port.flags &= ~ASYNC_INITIALIZED; @@ -1082,14 +1084,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) return -ENODEV; tty->driver_data = info; - tty_port_tty_set(&info->port, tty); + info->port.tty = tty; /* * Start up serial port */ spin_lock_irqsave(&info->slock, flags); info->port.count++; spin_unlock_irqrestore(&info->slock, flags); - retval = mxser_startup(tty); + retval = mxser_startup(info); if (retval) return retval; @@ -1207,13 +1209,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) break; } } - mxser_shutdown(tty); + mxser_shutdown(info); mxser_flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; - tty_port_tty_set(&info->port, NULL); + info->port.tty = NULL; if (info->port.blocked_open) { if (info->port.close_delay) schedule_timeout_interruptible(info->port.close_delay); @@ -1335,13 +1337,12 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) * friends of mxser_ioctl() * ------------------------------------------------------------ */ -static int mxser_get_serial_info(struct tty_struct *tty, +static int mxser_get_serial_info(struct mxser_port *info, struct serial_struct __user *retinfo) { - struct mxser_port *info = tty->driver_data; struct serial_struct tmp = { .type = info->type, - .line = tty->index, + .line = info->port.tty->index, .port = info->ioaddr, .irq = info->board->irq, .flags = info->port.flags, @@ -1356,10 +1357,9 @@ static int mxser_get_serial_info(struct tty_struct *tty, return 0; } -static int mxser_set_serial_info(struct tty_struct *tty, +static int mxser_set_serial_info(struct mxser_port *info, struct serial_struct __user *new_info) { - struct mxser_port *info = tty->driver_data; struct serial_struct new_serial; speed_t baud; unsigned long sl_flags; @@ -1393,14 +1393,14 @@ static int mxser_set_serial_info(struct tty_struct *tty, (new_serial.flags & ASYNC_FLAGS)); info->port.close_delay = new_serial.close_delay * HZ / 100; info->port.closing_wait = new_serial.closing_wait * HZ / 100; - tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) - ? 1 : 0; + info->port.tty->low_latency = + (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && (new_serial.baud_base != info->baud_base || new_serial.custom_divisor != info->custom_divisor)) { baud = new_serial.baud_base / new_serial.custom_divisor; - tty_encode_baud_rate(tty, baud, baud); + tty_encode_baud_rate(info->port.tty, baud, baud); } } @@ -1411,11 +1411,11 @@ static int mxser_set_serial_info(struct tty_struct *tty, if (info->port.flags & ASYNC_INITIALIZED) { if (flags != (info->port.flags & ASYNC_SPD_MASK)) { spin_lock_irqsave(&info->slock, sl_flags); - mxser_change_speed(tty, NULL); + mxser_change_speed(info, NULL); spin_unlock_irqrestore(&info->slock, sl_flags); } } else - retval = mxser_startup(tty); + retval = mxser_startup(info); return retval; } @@ -1461,7 +1461,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file) spin_lock_irqsave(&info->slock, flags); status = inb(info->ioaddr + UART_MSR); if (status & UART_MSR_ANY_DELTA) - mxser_check_modem_status(tty, info, status); + mxser_check_modem_status(info, status); spin_unlock_irqrestore(&info->slock, flags); return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | @@ -1606,7 +1606,6 @@ static int __init mxser_read_register(int port, unsigned short *regs) static int mxser_ioctl_special(unsigned int cmd, void __user *argp) { struct mxser_port *port; - struct tty_struct *tty; int result, status; unsigned int i, j; int ret = 0; @@ -1644,14 +1643,12 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) if (!port->ioaddr) goto copy; - - tty = tty_port_tty_get(&port->port); - if (!tty || !tty->termios) + if (!port->port.tty || !port->port.tty->termios) ms.cflag = port->normal_termios.c_cflag; else - ms.cflag = tty->termios->c_cflag; - tty_kref_put(tty); + ms.cflag = port->port.tty->termios->c_cflag; + status = inb(port->ioaddr + UART_MSR); if (status & UART_MSR_DCD) ms.dcd = 1; @@ -1707,18 +1704,15 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) me->up_txcnt[p] = port->mon_data.up_txcnt; me->modem_status[p] = port->mon_data.modem_status; - tty = tty_port_tty_get(&port->port); + me->baudrate[p] = tty_get_baud_rate(port->port.tty); - if (!tty || !tty->termios) { + if (!port->port.tty || !port->port.tty->termios) { cflag = port->normal_termios.c_cflag; iflag = port->normal_termios.c_iflag; - me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios); } else { - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - me->baudrate[p] = tty_get_baud_rate(tty); + cflag = port->port.tty->termios->c_cflag; + iflag = port->port.tty->termios->c_iflag; } - tty_kref_put(tty); me->databits[p] = cflag & CSIZE; me->stopbits[p] = cflag & CSTOPB; @@ -1828,12 +1822,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, switch (cmd) { case TIOCGSERIAL: lock_kernel(); - retval = mxser_get_serial_info(tty, argp); + retval = mxser_get_serial_info(info, argp); unlock_kernel(); return retval; case TIOCSSERIAL: lock_kernel(); - retval = mxser_set_serial_info(tty, argp); + retval = mxser_set_serial_info(info, argp); unlock_kernel(); return retval; case TIOCSERGETLSR: /* Get line status register */ @@ -1902,7 +1896,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, lock_kernel(); status = mxser_get_msr(info->ioaddr, 1, tty->index); - mxser_check_modem_status(tty, info, status); + mxser_check_modem_status(info, status); mcr = inb(info->ioaddr + UART_MCR); if (mcr & MOXA_MUST_MCR_XON_FLAG) @@ -1915,7 +1909,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, else info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; - if (tty->hw_stopped) + if (info->port.tty->hw_stopped) info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; else info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; @@ -1964,7 +1958,7 @@ static void mxser_stoprx(struct tty_struct *tty) } } - if (tty->termios->c_cflag & CRTSCTS) { + if (info->port.tty->termios->c_cflag & CRTSCTS) { info->MCR &= ~UART_MCR_RTS; outb(info->MCR, info->ioaddr + UART_MCR); } @@ -2001,7 +1995,7 @@ static void mxser_unthrottle(struct tty_struct *tty) } } - if (tty->termios->c_cflag & CRTSCTS) { + if (info->port.tty->termios->c_cflag & CRTSCTS) { info->MCR |= UART_MCR_RTS; outb(info->MCR, info->ioaddr + UART_MCR); } @@ -2046,7 +2040,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi unsigned long flags; spin_lock_irqsave(&info->slock, flags); - mxser_change_speed(tty, old_termios); + mxser_change_speed(info, old_termios); spin_unlock_irqrestore(&info->slock, flags); if ((old_termios->c_cflag & CRTSCTS) && @@ -2144,10 +2138,10 @@ static void mxser_hangup(struct tty_struct *tty) struct mxser_port *info = tty->driver_data; mxser_flush_buffer(tty); - mxser_shutdown(tty); + mxser_shutdown(info); info->port.count = 0; info->port.flags &= ~ASYNC_NORMAL_ACTIVE; - tty_port_tty_set(&info->port, NULL); + info->port.tty = NULL; wake_up_interruptible(&info->port.open_wait); } @@ -2170,9 +2164,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) return 0; } -static void mxser_receive_chars(struct tty_struct *tty, - struct mxser_port *port, int *status) +static void mxser_receive_chars(struct mxser_port *port, int *status) { + struct tty_struct *tty = port->port.tty; unsigned char ch, gdl; int ignored = 0; int cnt = 0; @@ -2180,8 +2174,9 @@ static void mxser_receive_chars(struct tty_struct *tty, int max = 256; recv_room = tty->receive_room; - if (recv_room == 0 && !port->ldisc_stop_rx) + if ((recv_room == 0) && (!port->ldisc_stop_rx)) mxser_stoprx(tty); + if (port->board->chip_flag != MOXA_OTHER_UART) { if (*status & UART_LSR_SPECIAL) @@ -2258,7 +2253,7 @@ static void mxser_receive_chars(struct tty_struct *tty, } while (*status & UART_LSR_DR); end_intr: - mxvar_log.rxcnt[tty->index] += cnt; + mxvar_log.rxcnt[port->port.tty->index] += cnt; port->mon_data.rxcnt += cnt; port->mon_data.up_rxcnt += cnt; @@ -2272,14 +2267,14 @@ static void mxser_receive_chars(struct tty_struct *tty, spin_lock(&port->slock); } -static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) +static void mxser_transmit_chars(struct mxser_port *port) { int count, cnt; if (port->x_char) { outb(port->x_char, port->ioaddr + UART_TX); port->x_char = 0; - mxvar_log.txcnt[tty->index]++; + mxvar_log.txcnt[port->port.tty->index]++; port->mon_data.txcnt++; port->mon_data.up_txcnt++; port->icount.tx++; @@ -2289,8 +2284,8 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->port.xmit_buf == NULL) return; - if (port->xmit_cnt <= 0 || tty->stopped || - (tty->hw_stopped && + if ((port->xmit_cnt <= 0) || port->port.tty->stopped || + (port->port.tty->hw_stopped && (port->type != PORT_16550A) && (!port->board->chip_flag))) { port->IER &= ~UART_IER_THRI; @@ -2307,14 +2302,14 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (--port->xmit_cnt <= 0) break; } while (--count > 0); - mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); + mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); port->mon_data.txcnt += (cnt - port->xmit_cnt); port->mon_data.up_txcnt += (cnt - port->xmit_cnt); port->icount.tx += (cnt - port->xmit_cnt); - if (port->xmit_cnt < WAKEUP_CHARS && tty) - tty_wakeup(tty); + if (port->xmit_cnt < WAKEUP_CHARS) + tty_wakeup(port->port.tty); if (port->xmit_cnt <= 0) { port->IER &= ~UART_IER_THRI; @@ -2333,7 +2328,6 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) int max, irqbits, bits, msr; unsigned int int_cnt, pass_counter = 0; int handled = IRQ_NONE; - struct tty_struct *tty; for (i = 0; i < MXSER_BOARDS; i++) if (dev_id == &mxser_boards[i]) { @@ -2366,15 +2360,13 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) if (iir & UART_IIR_NO_INT) break; iir &= MOXA_MUST_IIR_MASK; - tty = tty_port_tty_get(&port->port); - if (!tty || + if (!port->port.tty || (port->port.flags & ASYNC_CLOSING) || !(port->port.flags & ASYNC_INITIALIZED)) { status = inb(port->ioaddr + UART_LSR); outb(0x27, port->ioaddr + UART_FCR); inb(port->ioaddr + UART_MSR); - tty_kref_put(tty); break; } @@ -2395,28 +2387,27 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) iir == MOXA_MUST_IIR_RDA || iir == MOXA_MUST_IIR_RTO || iir == MOXA_MUST_IIR_LSR) - mxser_receive_chars(tty, port, + mxser_receive_chars(port, &status); } else { status &= port->read_status_mask; if (status & UART_LSR_DR) - mxser_receive_chars(tty, port, + mxser_receive_chars(port, &status); } msr = inb(port->ioaddr + UART_MSR); if (msr & UART_MSR_ANY_DELTA) - mxser_check_modem_status(tty, port, msr); + mxser_check_modem_status(port, msr); if (port->board->chip_flag) { if (iir == 0x02 && (status & UART_LSR_THRE)) - mxser_transmit_chars(tty, port); + mxser_transmit_chars(port); } else { if (status & UART_LSR_THRE) - mxser_transmit_chars(tty, port); + mxser_transmit_chars(port); } - tty_kref_put(tty); } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); spin_unlock(&port->slock); } diff --git a/trunk/drivers/char/n_hdlc.c b/trunk/drivers/char/n_hdlc.c index bacb3e2872ae..69ec6399c714 100644 --- a/trunk/drivers/char/n_hdlc.c +++ b/trunk/drivers/char/n_hdlc.c @@ -764,7 +764,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, break; default: - error = n_tty_ioctl_helper(tty, file, cmd, arg); + error = n_tty_ioctl (tty, file, cmd, arg); break; } return error; diff --git a/trunk/drivers/char/n_r3964.c b/trunk/drivers/char/n_r3964.c index 4a8215a89ad3..ae377aa473ba 100644 --- a/trunk/drivers/char/n_r3964.c +++ b/trunk/drivers/char/n_r3964.c @@ -372,8 +372,14 @@ static void remove_from_rx_queue(struct r3964_info *pInfo, static void put_char(struct r3964_info *pInfo, unsigned char ch) { struct tty_struct *tty = pInfo->tty; + + if (tty == NULL) + return; + /* FIXME: put_char should not be called from an IRQ */ - tty_put_char(tty, ch); + if (tty->ops->put_char) { + tty->ops->put_char(tty, ch); + } pInfo->bcc ^= ch; } diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c index efbfe9612658..708c2b1dbe51 100644 --- a/trunk/drivers/char/n_tty.c +++ b/trunk/drivers/char/n_tty.c @@ -26,7 +26,7 @@ * * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to * waiting writing processes-Sapan Bhatia . - * Also fixed a bug in BLOCKING mode where n_tty_write returns + * Also fixed a bug in BLOCKING mode where write_chan returns * EAGAIN */ @@ -99,7 +99,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, 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; /* @@ -122,16 +121,6 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) } } -/** - * put_tty_queue - add character to tty - * @c: character - * @tty: tty device - * - * Add a character to the tty read_buf queue. This is done under the - * read_lock to serialize character addition and also to protect us - * against parallel reads or flushes - */ - static void put_tty_queue(unsigned char c, struct tty_struct *tty) { unsigned long flags; @@ -148,11 +137,14 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty) * check_unthrottle - allow new receive data * @tty; tty device * - * Check whether to call the driver unthrottle functions - * + * Check whether to call the driver.unthrottle function. + * We test the TTY_THROTTLED bit first so that it always + * indicates the current state. The decision about whether + * it is worth allowing more input has been taken by the caller. * Can sleep, may be called under the atomic_read_lock mutex but * this is not guaranteed. */ + static void check_unthrottle(struct tty_struct *tty) { if (tty->count) @@ -166,8 +158,6 @@ static void check_unthrottle(struct tty_struct *tty) * Reset the read buffer counters, clear the flags, * and make sure the driver is unthrottled. Called * from n_tty_open() and n_tty_flush_buffer(). - * - * Locking: tty_read_lock for read fields. */ static void reset_buffer_flags(struct tty_struct *tty) { @@ -191,7 +181,7 @@ static void reset_buffer_flags(struct tty_struct *tty) * at hangup) or when the N_TTY line discipline internally has to * clean the pending queue (for example some signals). * - * Locking: ctrl_lock, read_lock. + * Locking: ctrl_lock */ static void n_tty_flush_buffer(struct tty_struct *tty) @@ -217,8 +207,6 @@ static void n_tty_flush_buffer(struct tty_struct *tty) * * Report the number of characters buffered to be delivered to user * at this instant in time. - * - * Locking: read_lock */ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) @@ -358,7 +346,7 @@ static int opost(unsigned char c, struct tty_struct *tty) * the simple cases normally found and helps to generate blocks of * symbols for the console driver and thus improve performance. * - * Called from n_tty_write under the tty layer write lock. Relies + * Called from write_chan under the tty layer write lock. Relies * on lock_kernel for the tty->column state. */ @@ -422,8 +410,6 @@ static ssize_t opost_block(struct tty_struct *tty, * * Echo user input back onto the screen. This must be called only when * L_ECHO(tty) is true. Called from the driver receive_buf path. - * - * Relies on BKL for tty column locking */ static void echo_char(unsigned char c, struct tty_struct *tty) @@ -436,12 +422,6 @@ static void echo_char(unsigned char c, struct tty_struct *tty) opost(c, tty); } -/** - * finsh_erasing - complete erase - * @tty: tty doing the erase - * - * Relies on BKL for tty column locking - */ static inline void finish_erasing(struct tty_struct *tty) { if (tty->erasing) { @@ -459,8 +439,6 @@ static inline void finish_erasing(struct tty_struct *tty) * Perform erase and necessary output when an erase character is * present in the stream from the driver layer. Handles the complexities * of UTF-8 multibyte symbols. - * - * Locking: read_lock for tty buffers, BKL for column/erasing state */ static void eraser(unsigned char c, struct tty_struct *tty) @@ -469,7 +447,6 @@ static void eraser(unsigned char c, struct tty_struct *tty) int head, seen_alnums, cnt; unsigned long flags; - /* FIXME: locking needed ? */ if (tty->read_head == tty->canon_head) { /* opost('\a', tty); */ /* what do you think? */ return; @@ -504,7 +481,6 @@ static void eraser(unsigned char c, struct tty_struct *tty) } seen_alnums = 0; - /* FIXME: Locking ?? */ while (tty->read_head != tty->canon_head) { head = tty->read_head; @@ -607,8 +583,6 @@ static void eraser(unsigned char c, struct tty_struct *tty) * may caus terminal flushing to take place according to the termios * settings and character used. Called from the driver receive_buf * path so serialized. - * - * Locking: ctrl_lock, read_lock (both via flush buffer) */ static inline void isig(int sig, struct tty_struct *tty, int flush) @@ -1033,26 +1007,12 @@ int is_ignored(int sig) * and is protected from re-entry by the tty layer. The user is * guaranteed that this function will not be re-entered or in progress * when the ldisc is closed. - * - * Locking: Caller holds tty->termios_mutex */ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) { - int canon_change = 1; - BUG_ON(!tty); - - if (old) - canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON; - if (canon_change) { - memset(&tty->read_flags, 0, sizeof tty->read_flags); - tty->canon_head = tty->read_tail; - tty->canon_data = 0; - tty->erasing = 0; - } - - if (canon_change && !L_ICANON(tty) && tty->read_cnt) - wake_up_interruptible(&tty->read_wait); + if (!tty) + return; tty->icanon = (L_ICANON(tty) != 0); if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { @@ -1183,7 +1143,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) * @b: user data * @nr: size of data * - * Helper function to speed up n_tty_read. It is only called when + * Helper function to speed up read_chan. It is only called when * ICANON is off; it copies characters straight from the tty queue to * user space directly. It can be profitably called twice; once to * drain the space from the tail pointer to the (physical) end of the @@ -1250,7 +1210,7 @@ static int job_control(struct tty_struct *tty, struct file *file) if (file->f_op->write != redirected_tty_write && current->signal->tty == tty) { if (!tty->pgrp) - printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); + printk(KERN_ERR "read_chan: no tty->pgrp!\n"); else if (task_pgrp(current) != tty->pgrp) { if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) @@ -1265,7 +1225,7 @@ static int job_control(struct tty_struct *tty, struct file *file) /** - * n_tty_read - read function for tty + * read_chan - read function for tty * @tty: tty device * @file: file object * @buf: userspace buffer pointer @@ -1279,7 +1239,7 @@ static int job_control(struct tty_struct *tty, struct file *file) * This code must be sure never to sleep through a hangup. */ -static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, +static ssize_t read_chan(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr) { unsigned char __user *b = buf; @@ -1294,7 +1254,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, do_it_again: - BUG_ON(!tty->read_buf); + if (!tty->read_buf) { + printk(KERN_ERR "n_tty_read_chan: read_buf == NULL?!?\n"); + return -EIO; + } c = job_control(tty, file); if (c < 0) @@ -1481,7 +1444,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, } /** - * n_tty_write - write function for tty + * write_chan - write function for tty * @tty: tty device * @file: file object * @buf: userspace buffer pointer @@ -1495,7 +1458,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, * This code must be sure never to sleep through a hangup. */ -static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, +static ssize_t write_chan(struct tty_struct *tty, struct file *file, const unsigned char *buf, size_t nr) { const unsigned char *b = buf; @@ -1569,7 +1532,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, } /** - * n_tty_poll - poll method for N_TTY + * normal_poll - poll method for N_TTY * @tty: terminal device * @file: file accessing it * @wait: poll table @@ -1582,7 +1545,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, * Called without the kernel lock held - fine */ -static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, +static unsigned int normal_poll(struct tty_struct *tty, struct file *file, poll_table *wait) { unsigned int mask = 0; @@ -1610,44 +1573,6 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, return mask; } -static unsigned long inq_canon(struct tty_struct *tty) -{ - int nr, head, tail; - - if (!tty->canon_data) - return 0; - head = tty->canon_head; - tail = tty->read_tail; - nr = (head - tail) & (N_TTY_BUF_SIZE-1); - /* Skip EOF-chars.. */ - while (head != tail) { - if (test_bit(tail, tty->read_flags) && - tty->read_buf[tail] == __DISABLED_CHAR) - nr--; - tail = (tail+1) & (N_TTY_BUF_SIZE-1); - } - return nr; -} - -static int n_tty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int retval; - - switch (cmd) { - case TIOCOUTQ: - return put_user(tty_chars_in_buffer(tty), (int __user *) arg); - case TIOCINQ: - /* FIXME: Locking */ - retval = tty->read_cnt; - if (L_ICANON(tty)) - retval = inq_canon(tty); - return put_user(retval, (unsigned int __user *) arg); - default: - return n_tty_ioctl_helper(tty, file, cmd, arg); - } -} - struct tty_ldisc_ops tty_ldisc_N_TTY = { .magic = TTY_LDISC_MAGIC, .name = "n_tty", @@ -1655,11 +1580,11 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { .close = n_tty_close, .flush_buffer = n_tty_flush_buffer, .chars_in_buffer = n_tty_chars_in_buffer, - .read = n_tty_read, - .write = n_tty_write, + .read = read_chan, + .write = write_chan, .ioctl = n_tty_ioctl, .set_termios = n_tty_set_termios, - .poll = n_tty_poll, + .poll = normal_poll, .receive_buf = n_tty_receive_buf, .write_wakeup = n_tty_write_wakeup }; diff --git a/trunk/drivers/char/nozomi.c b/trunk/drivers/char/nozomi.c index 9a34a1935283..66a0f931c66c 100644 --- a/trunk/drivers/char/nozomi.c +++ b/trunk/drivers/char/nozomi.c @@ -1599,10 +1599,7 @@ static int ntty_open(struct tty_struct *tty, struct file *file) return 0; } -/* Called when the userspace process close the tty, /dev/noz*. Also - called immediately if ntty_open fails in which case tty->driver_data - will be NULL an we exit by the first return */ - +/* Called when the userspace process close the tty, /dev/noz*. */ static void ntty_close(struct tty_struct *tty, struct file *file) { struct nozomi *dc = get_dc_by_tty(tty); diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c index dbb912574569..f070ae7bd91a 100644 --- a/trunk/drivers/char/pcmcia/cm4000_cs.c +++ b/trunk/drivers/char/pcmcia/cm4000_cs.c @@ -1759,40 +1759,65 @@ static void cmm_cm4000_release(struct pcmcia_device * link) /*==== Interface to PCMCIA Layer =======================================*/ -static int cm4000_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if (!cfg->io.nwin) - return -ENODEV; - - /* Get the IOaddr */ - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(cfg->io.flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(cfg->io.flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; - - return pcmcia_request_io(p_dev, &p_dev->io); -} - static int cm4000_config(struct pcmcia_device * link, int devno) { struct cm4000_dev *dev; + tuple_t tuple; + cisparse_t parse; + u_char buf[64]; + int fail_fn, fail_rc; + int rc; /* read the config-tuples */ - if (pcmcia_loop_config(link, cm4000_config_check, NULL)) + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + + link->io.BasePort2 = 0; + link->io.NumPorts2 = 0; + link->io.Attributes2 = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + for (rc = pcmcia_get_first_tuple(link, &tuple); + rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) { + + rc = pcmcia_get_tuple_data(link, &tuple); + if (rc != CS_SUCCESS) + continue; + rc = pcmcia_parse_tuple(link, &tuple, &parse); + if (rc != CS_SUCCESS) + continue; + + link->conf.ConfigIndex = parse.cftable_entry.index; + + if (!parse.cftable_entry.io.nwin) + continue; + + /* Get the IOaddr */ + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = parse.cftable_entry.io.flags + & CISTPL_IO_LINES_MASK; + + rc = pcmcia_request_io(link, &link->io); + if (rc == CS_SUCCESS) + break; /* we are done */ + } + if (rc != CS_SUCCESS) goto cs_release; link->conf.IntType = 00000002; - if (pcmcia_request_configuration(link, &link->conf)) + if ((fail_rc = + pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) { + fail_fn = RequestConfiguration; goto cs_release; + } dev = link->priv; sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); @@ -1871,7 +1896,7 @@ static int cm4000_probe(struct pcmcia_device *link) return ret; } - device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i); + device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i); return 0; } diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c index 4f0723b07974..0b5934bef7a4 100644 --- a/trunk/drivers/char/pcmcia/cm4040_cs.c +++ b/trunk/drivers/char/pcmcia/cm4040_cs.c @@ -526,49 +526,65 @@ static void cm4040_reader_release(struct pcmcia_device *link) return; } -static int cm4040_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - int rc; - if (!cfg->io.nwin) - return -ENODEV; - - /* Get the IOaddr */ - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(cfg->io.flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(cfg->io.flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; - - rc = pcmcia_request_io(p_dev, &p_dev->io); - dev_printk(KERN_INFO, &handle_to_dev(p_dev), - "pcmcia_request_io returned 0x%x\n", rc); - return rc; -} - - static int reader_config(struct pcmcia_device *link, int devno) { struct reader_dev *dev; - int fail_rc; + tuple_t tuple; + cisparse_t parse; + u_char buf[64]; + int fail_fn, fail_rc; + int rc; + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; link->io.BasePort2 = 0; link->io.NumPorts2 = 0; link->io.Attributes2 = 0; - - if (pcmcia_loop_config(link, cm4040_config_check, NULL)) + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + for (rc = pcmcia_get_first_tuple(link, &tuple); + rc == CS_SUCCESS; + rc = pcmcia_get_next_tuple(link, &tuple)) { + rc = pcmcia_get_tuple_data(link, &tuple); + if (rc != CS_SUCCESS) + continue; + rc = pcmcia_parse_tuple(link, &tuple, &parse); + if (rc != CS_SUCCESS) + continue; + + link->conf.ConfigIndex = parse.cftable_entry.index; + + if (!parse.cftable_entry.io.nwin) + continue; + + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = parse.cftable_entry.io.flags + & CISTPL_IO_LINES_MASK; + rc = pcmcia_request_io(link, &link->io); + + dev_printk(KERN_INFO, &handle_to_dev(link), "foo"); + if (rc == CS_SUCCESS) + break; + else + dev_printk(KERN_INFO, &handle_to_dev(link), + "pcmcia_request_io failed 0x%x\n", rc); + } + if (rc != CS_SUCCESS) goto cs_release; link->conf.IntType = 00000002; - fail_rc = pcmcia_request_configuration(link, &link->conf); - if (fail_rc != 0) { + if ((fail_rc = pcmcia_request_configuration(link,&link->conf)) + !=CS_SUCCESS) { + fail_fn = RequestConfiguration; dev_printk(KERN_INFO, &handle_to_dev(link), "pcmcia_request_configuration failed 0x%x\n", fail_rc); @@ -637,7 +653,8 @@ static int reader_probe(struct pcmcia_device *link) return ret; } - device_create(cmx_class, NULL, MKDEV(major, i), NULL, "cmx%d", i); + device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL, + "cmx%d", i); return 0; } diff --git a/trunk/drivers/char/pcmcia/ipwireless/main.c b/trunk/drivers/char/pcmcia/ipwireless/main.c index 5216fce0c62d..5eca7a99afe6 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/main.c +++ b/trunk/drivers/char/pcmcia/ipwireless/main.c @@ -65,9 +65,9 @@ static void signalled_reboot_work(struct work_struct *work_reboot) struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, work_reboot); struct pcmcia_device *link = ipw->link; - int ret = pcmcia_reset_card(link->socket); + int ret = pccard_reset_card(link->socket); - if (ret != 0) + if (ret != CS_SUCCESS) cs_error(link, ResetCard, ret); } @@ -83,6 +83,7 @@ static int config_ipwireless(struct ipw_dev *ipw) { struct pcmcia_device *link = ipw->link; int ret; + config_info_t conf; tuple_t tuple; unsigned short buf[64]; cisparse_t parse; @@ -104,7 +105,7 @@ static int config_ipwireless(struct ipw_dev *ipw) while (ret == 0) { ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); goto exit0; } @@ -115,21 +116,21 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_get_first_tuple(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetFirstTuple, ret); goto exit0; } ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); goto exit0; } - ret = pcmcia_parse_tuple(&tuple, &parse); + ret = pcmcia_parse_tuple(link, &tuple, &parse); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, ParseTuple, ret); goto exit0; } @@ -151,21 +152,21 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_get_first_tuple(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetFirstTuple, ret); goto exit0; } ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); goto exit0; } - ret = pcmcia_parse_tuple(&tuple, &parse); + ret = pcmcia_parse_tuple(link, &tuple, &parse); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); goto exit0; } @@ -180,7 +181,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_io(link, &link->io); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, RequestIO, ret); goto exit0; } @@ -194,21 +195,21 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_get_first_tuple(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetFirstTuple, ret); goto exit1; } ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, GetTupleData, ret); goto exit1; } - ret = pcmcia_parse_tuple(&tuple, &parse); + ret = pcmcia_parse_tuple(link, &tuple, &parse); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, ParseTuple, ret); goto exit1; } @@ -226,7 +227,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_window(&link, &ipw->request_common_memory, &ipw->handle_common_memory); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, RequestWindow, ret); goto exit1; } @@ -238,7 +239,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_map_mem_page(ipw->handle_common_memory, &memreq_common_memory); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, MapMemPage, ret); goto exit1; } @@ -260,7 +261,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_window(&link, &ipw->request_attr_memory, &ipw->handle_attr_memory); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, RequestWindow, ret); goto exit2; } @@ -271,7 +272,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_map_mem_page(ipw->handle_attr_memory, &memreq_attr_memory); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, MapMemPage, ret); goto exit2; } @@ -291,11 +292,20 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_irq(link, &link->irq); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, RequestIRQ, ret); goto exit3; } + /* Look up current Vcc */ + + ret = pcmcia_get_configuration_info(link, &conf); + + if (ret != CS_SUCCESS) { + cs_error(link, GetConfigurationInfo, ret); + goto exit4; + } + printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", ipw->is_v2_card ? "V2/V3" : "V1"); printk(KERN_INFO IPWIRELESS_PCCARD_NAME @@ -331,7 +341,7 @@ static int config_ipwireless(struct ipw_dev *ipw) */ ret = pcmcia_request_configuration(link, &link->conf); - if (ret != 0) { + if (ret != CS_SUCCESS) { cs_error(link, RequestConfiguration, ret); goto exit4; } diff --git a/trunk/drivers/char/pcmcia/ipwireless/tty.c b/trunk/drivers/char/pcmcia/ipwireless/tty.c index 569f2f7743a7..3a23e7694d55 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/tty.c +++ b/trunk/drivers/char/pcmcia/ipwireless/tty.c @@ -276,7 +276,6 @@ static int ipw_write_room(struct tty_struct *linux_tty) struct ipw_tty *tty = linux_tty->driver_data; int room; - /* FIXME: Exactly how is the tty object locked here .. */ if (!tty) return -ENODEV; @@ -398,7 +397,6 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set, static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) { struct ipw_tty *tty = linux_tty->driver_data; - /* FIXME: Exactly how is the tty object locked here .. */ if (!tty) return -ENODEV; @@ -414,7 +412,6 @@ ipw_tiocmset(struct tty_struct *linux_tty, struct file *file, unsigned int set, unsigned int clear) { struct ipw_tty *tty = linux_tty->driver_data; - /* FIXME: Exactly how is the tty object locked here .. */ if (!tty) return -ENODEV; @@ -436,8 +433,6 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, if (!tty->open_count) return -EINVAL; - /* FIXME: Exactly how is the tty object locked here .. */ - switch (cmd) { case TIOCGSERIAL: return ipwireless_get_serial_info(tty, (void __user *) arg); @@ -472,6 +467,13 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, } return 0; + case TCGETS: + case TCGETA: + return n_tty_ioctl(linux_tty, file, cmd, arg); + + case TCFLSH: + return n_tty_ioctl(linux_tty, file, cmd, arg); + case FIONREAD: { int val = 0; @@ -480,11 +482,10 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, return -EFAULT; } return 0; - case TCFLSH: - return tty_perform_flush(linux_tty, arg); } } - return tty_mode_ioctl(linux_tty, file, cmd , arg); + + return -ENOIOCTLCMD; } static int add_tty(dev_node_t *nodesp, int j, @@ -587,8 +588,6 @@ void ipwireless_tty_free(struct ipw_tty *tty) tty_hangup(ttyj->linux_tty); /* Wait till the tty_hangup has completed */ flush_scheduled_work(); - /* FIXME: Exactly how is the tty object locked here - against a parallel ioctl etc */ mutex_lock(&ttyj->ipw_tty_mutex); } while (ttyj->open_count) diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 9a626e50b793..c240562c218b 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -601,7 +601,7 @@ static int mgslpc_config(struct pcmcia_device *link) cfg = &(parse.cftable_entry); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; if (cfg->index == 0) diff --git a/trunk/drivers/char/ppdev.c b/trunk/drivers/char/ppdev.c index c84c34fb1231..bee39fdfba73 100644 --- a/trunk/drivers/char/ppdev.c +++ b/trunk/drivers/char/ppdev.c @@ -760,8 +760,9 @@ static const struct file_operations pp_fops = { static void pp_attach(struct parport *port) { - device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), - NULL, "parport%d", port->number); + device_create_drvdata(ppdev_class, port->dev, + MKDEV(PP_MAJOR, port->number), + NULL, "parport%d", port->number); } static void pp_detach(struct parport *port) diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index 6d4582712b1f..76b27932d229 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -8,12 +8,10 @@ * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to * waiting writers -- Sapan Bhatia * - * When reading this code see also fs/devpts. In particular note that the - * driver_data field is used by the devpts side as a binding to the devpts - * inode. + * */ -#include +#include /* For EXPORT_SYMBOL */ #include #include @@ -25,12 +23,11 @@ #include #include #include -#include -#include -#include -#include +#include #include +#include +#include /* These are global because they are accessed in tty_io.c */ #ifdef CONFIG_UNIX98_PTYS @@ -38,12 +35,14 @@ struct tty_driver *ptm_driver; static struct tty_driver *pts_driver; #endif -static void pty_close(struct tty_struct *tty, struct file *filp) +static void pty_close(struct tty_struct * tty, struct file * filp) { - BUG_ON(!tty); - if (tty->driver->subtype == PTY_TYPE_MASTER) - WARN_ON(tty->count > 1); - else { + if (!tty) + return; + if (tty->driver->subtype == PTY_TYPE_MASTER) { + if (tty->count > 1) + printk("master pty_close: count = %d!!\n", tty->count); + } else { if (tty->count > 2) return; } @@ -60,7 +59,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) set_bit(TTY_OTHER_CLOSED, &tty->flags); #ifdef CONFIG_UNIX98_PTYS if (tty->driver == ptm_driver) - devpts_pty_kill(tty->link); + devpts_pty_kill(tty->index); #endif tty_vhangup(tty->link); } @@ -70,13 +69,13 @@ static void pty_close(struct tty_struct *tty, struct file *filp) * The unthrottle routine is called by the line discipline to signal * that it can receive more characters. For PTY's, the TTY_THROTTLED * flag is always set, to force the line discipline to always call the - * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE + * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE * characters in the queue. This is necessary since each time this * happens, we need to wake up any sleeping processes that could be * (1) trying to send data to the pty, or (2) waiting in wait_until_sent() * for the pty buffer to be drained. */ -static void pty_unthrottle(struct tty_struct *tty) +static void pty_unthrottle(struct tty_struct * tty) { struct tty_struct *o_tty = tty->link; @@ -88,7 +87,7 @@ static void pty_unthrottle(struct tty_struct *tty) } /* - * WSH 05/24/97: modified to + * WSH 05/24/97: modified to * (1) use space in tty->flip instead of a shared temp buffer * The flip buffers aren't being used for a pty, so there's lots * of space available. The buffer is protected by a per-pty @@ -101,8 +100,7 @@ static void pty_unthrottle(struct tty_struct *tty) * not our partners. We can't just take the other one blindly without * risking deadlocks. */ -static int pty_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) { struct tty_struct *to = tty->link; int c; @@ -114,7 +112,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, if (c > count) c = count; to->ldisc.ops->receive_buf(to, buf, NULL, c); - + return c; } @@ -130,17 +128,17 @@ static int pty_write_room(struct tty_struct *tty) /* * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior - * The chars_in_buffer() value is used by the ldisc select() function + * The chars_in_buffer() value is used by the ldisc select() function * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). * The pty driver chars_in_buffer() Master/Slave must behave differently: * * The Master side needs to allow typed-ahead commands to accumulate * while being canonicalized, so we report "our buffer" as empty until * some threshold is reached, and then report the count. (Any count > - * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock - * the count returned must be 0 if no canonical data is available to be + * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock + * the count returned must be 0 if no canonical data is available to be * read. (The N_TTY ldisc.chars_in_buffer now knows this.) - * + * * The Slave side passes all characters in raw mode to the Master side's * buffer where they can be read immediately, so in this case we can * return the true count in the buffer. @@ -157,22 +155,21 @@ static int pty_chars_in_buffer(struct tty_struct *tty) /* The ldisc must report 0 if no characters available to be read */ count = to->ldisc.ops->chars_in_buffer(to); - if (tty->driver->subtype == PTY_TYPE_SLAVE) - return count; + if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; - /* Master side driver ... if the other side's read buffer is less than + /* Master side driver ... if the other side's read buffer is less than * half full, return 0 to allow writers to proceed; otherwise return - * the count. This leaves a comfortable margin to avoid overflow, + * the count. This leaves a comfortable margin to avoid overflow, * and still allows half a buffer's worth of typed-ahead commands. */ - return (count < N_TTY_BUF_SIZE/2) ? 0 : count; + return ((count < N_TTY_BUF_SIZE/2) ? 0 : count); } /* Set the lock flag on a pty */ -static int pty_set_lock(struct tty_struct *tty, int __user *arg) +static int pty_set_lock(struct tty_struct *tty, int __user * arg) { int val; - if (get_user(val, arg)) + if (get_user(val,arg)) return -EFAULT; if (val) set_bit(TTY_PTY_LOCK, &tty->flags); @@ -185,13 +182,13 @@ static void pty_flush_buffer(struct tty_struct *tty) { struct tty_struct *to = tty->link; unsigned long flags; - + if (!to) return; - + if (to->ldisc.ops->flush_buffer) to->ldisc.ops->flush_buffer(to); - + if (to->packet) { spin_lock_irqsave(&tty->ctrl_lock, flags); tty->ctrl_status |= TIOCPKT_FLUSHWRITE; @@ -200,7 +197,7 @@ static void pty_flush_buffer(struct tty_struct *tty) } } -static int pty_open(struct tty_struct *tty, struct file *filp) +static int pty_open(struct tty_struct *tty, struct file * filp) { int retval = -ENODEV; @@ -223,65 +220,13 @@ static int pty_open(struct tty_struct *tty, struct file *filp) return retval; } -static void pty_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - tty->termios->c_cflag &= ~(CSIZE | PARENB); - tty->termios->c_cflag |= (CS8 | CREAD); -} - -static int pty_install(struct tty_driver *driver, struct tty_struct *tty) +static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { - struct tty_struct *o_tty; - int idx = tty->index; - int retval; - - o_tty = alloc_tty_struct(); - if (!o_tty) - return -ENOMEM; - if (!try_module_get(driver->other->owner)) { - /* This cannot in fact currently happen */ - free_tty_struct(o_tty); - return -ENOMEM; - } - initialize_tty_struct(o_tty, driver->other, idx); - - /* We always use new tty termios data so we can do this - the easy way .. */ - retval = tty_init_termios(tty); - if (retval) - goto free_mem_out; - - retval = tty_init_termios(o_tty); - if (retval) { - tty_free_termios(tty); - goto free_mem_out; - } - - /* - * Everything allocated ... set up the o_tty structure. - */ - driver->other->ttys[idx] = o_tty; - tty_driver_kref_get(driver->other); - if (driver->subtype == PTY_TYPE_MASTER) - o_tty->count++; - /* Establish the links in both directions */ - tty->link = o_tty; - o_tty->link = tty; - - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; - return 0; -free_mem_out: - module_put(o_tty->driver->owner); - free_tty_struct(o_tty); - return -ENOMEM; + tty->termios->c_cflag &= ~(CSIZE | PARENB); + tty->termios->c_cflag |= (CS8 | CREAD); } - static const struct tty_operations pty_ops = { - .install = pty_install, .open = pty_open, .close = pty_close, .write = pty_write, @@ -384,11 +329,8 @@ static inline void legacy_pty_init(void) { } * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. */ int pty_limit = NR_UNIX98_PTY_DEFAULT; -static int pty_limit_min; +static int pty_limit_min = 0; static int pty_limit_max = NR_UNIX98_PTY_MAX; -static int pty_count; - -static struct cdev ptmx_cdev; static struct ctl_table pty_table[] = { { @@ -406,7 +348,6 @@ static struct ctl_table pty_table[] = { .procname = "nr", .maxlen = sizeof(int), .mode = 0444, - .data = &pty_count, .proc_handler = &proc_dointvec, }, { .ctl_name = 0 @@ -447,127 +388,7 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, return -ENOIOCTLCMD; } -/** - * ptm_unix98_lookup - find a pty master - * @driver: ptm driver - * @idx: tty index - * - * Look up a pty master device. Called under the tty_mutex for now. - * This provides our locking. - */ - -static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, - struct inode *ptm_inode, int idx) -{ - struct tty_struct *tty = devpts_get_tty(ptm_inode, idx); - if (tty) - tty = tty->link; - return tty; -} - -/** - * pts_unix98_lookup - find a pty slave - * @driver: pts driver - * @idx: tty index - * - * Look up a pty master device. Called under the tty_mutex for now. - * This provides our locking. - */ - -static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, - struct inode *pts_inode, int idx) -{ - struct tty_struct *tty = devpts_get_tty(pts_inode, idx); - /* Master must be open before slave */ - if (!tty) - return ERR_PTR(-EIO); - return tty; -} - -static void pty_unix98_shutdown(struct tty_struct *tty) -{ - /* We have our own method as we don't use the tty index */ - kfree(tty->termios); -} - -/* We have no need to install and remove our tty objects as devpts does all - the work for us */ - -static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) -{ - struct tty_struct *o_tty; - int idx = tty->index; - - o_tty = alloc_tty_struct(); - if (!o_tty) - return -ENOMEM; - if (!try_module_get(driver->other->owner)) { - /* This cannot in fact currently happen */ - free_tty_struct(o_tty); - return -ENOMEM; - } - initialize_tty_struct(o_tty, driver->other, idx); - - tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); - if (tty->termios == NULL) - goto free_mem_out; - *tty->termios = driver->init_termios; - tty->termios_locked = tty->termios + 1; - - o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); - if (o_tty->termios == NULL) - goto free_mem_out; - *o_tty->termios = driver->other->init_termios; - o_tty->termios_locked = o_tty->termios + 1; - - tty_driver_kref_get(driver->other); - if (driver->subtype == PTY_TYPE_MASTER) - o_tty->count++; - /* Establish the links in both directions */ - tty->link = o_tty; - o_tty->link = tty; - /* - * All structures have been allocated, so now we install them. - * Failures after this point use release_tty to clean up, so - * there's no need to null out the local pointers. - */ - tty_driver_kref_get(driver); - tty->count++; - pty_count++; - return 0; -free_mem_out: - kfree(o_tty->termios); - module_put(o_tty->driver->owner); - free_tty_struct(o_tty); - kfree(tty->termios); - return -ENOMEM; -} - -static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) -{ - pty_count--; -} - -static const struct tty_operations ptm_unix98_ops = { - .lookup = ptm_unix98_lookup, - .install = pty_unix98_install, - .remove = pty_unix98_remove, - .open = pty_open, - .close = pty_close, - .write = pty_write, - .write_room = pty_write_room, - .flush_buffer = pty_flush_buffer, - .chars_in_buffer = pty_chars_in_buffer, - .unthrottle = pty_unthrottle, - .set_termios = pty_set_termios, - .ioctl = pty_unix98_ioctl, - .shutdown = pty_unix98_shutdown -}; - static const struct tty_operations pty_unix98_ops = { - .lookup = pts_unix98_lookup, - .install = pty_unix98_install, - .remove = pty_unix98_remove, .open = pty_open, .close = pty_close, .write = pty_write, @@ -576,73 +397,9 @@ static const struct tty_operations pty_unix98_ops = { .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .set_termios = pty_set_termios, - .shutdown = pty_unix98_shutdown + .ioctl = pty_unix98_ioctl }; -/** - * ptmx_open - open a unix 98 pty master - * @inode: inode of device file - * @filp: file pointer to tty - * - * Allocate a unix98 pty master device from the ptmx driver. - * - * Locking: tty_mutex protects the init_dev work. tty->count should - * protect the rest. - * allocated_ptys_lock handles the list of free pty numbers - */ - -static int __ptmx_open(struct inode *inode, struct file *filp) -{ - struct tty_struct *tty; - int retval; - int index; - - nonseekable_open(inode, filp); - - /* find a device that is not in use. */ - index = devpts_new_index(inode); - if (index < 0) - return index; - - mutex_lock(&tty_mutex); - tty = tty_init_dev(ptm_driver, index, 1); - mutex_unlock(&tty_mutex); - - if (IS_ERR(tty)) { - retval = PTR_ERR(tty); - goto out; - } - - set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ - filp->private_data = tty; - file_move(filp, &tty->tty_files); - - retval = devpts_pty_new(inode, tty->link); - if (retval) - goto out1; - - retval = ptm_driver->ops->open(tty, filp); - if (!retval) - return 0; -out1: - tty_release_dev(filp); - return retval; -out: - devpts_kill_index(inode, index); - return retval; -} - -static int ptmx_open(struct inode *inode, struct file *filp) -{ - int ret; - - lock_kernel(); - ret = __ptmx_open(inode, filp); - unlock_kernel(); - return ret; -} - -static struct file_operations ptmx_fops; static void __init unix98_pty_init(void) { @@ -670,7 +427,7 @@ static void __init unix98_pty_init(void) ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; ptm_driver->other = pts_driver; - tty_set_operations(ptm_driver, &ptm_unix98_ops); + tty_set_operations(ptm_driver, &pty_unix98_ops); pts_driver->owner = THIS_MODULE; pts_driver->driver_name = "pty_slave"; @@ -686,26 +443,16 @@ static void __init unix98_pty_init(void) pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; pts_driver->other = ptm_driver; - tty_set_operations(pts_driver, &pty_unix98_ops); - + tty_set_operations(pts_driver, &pty_ops); + if (tty_register_driver(ptm_driver)) panic("Couldn't register Unix98 ptm driver"); if (tty_register_driver(pts_driver)) panic("Couldn't register Unix98 pts driver"); + pty_table[1].data = &ptm_driver->refcount; register_sysctl_table(pty_root_table); - - /* Now create the /dev/ptmx special device */ - tty_default_fops(&ptmx_fops); - ptmx_fops.open = ptmx_open; - - cdev_init(&ptmx_cdev, &ptmx_fops); - if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || - register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) - panic("Couldn't register /dev/ptmx driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); } - #else static inline void unix98_pty_init(void) { } #endif diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index c8752eaad483..6af435b89867 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1205,7 +1205,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp, return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos); } -static int uuid_strategy(ctl_table *table, +static int uuid_strategy(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { diff --git a/trunk/drivers/char/raw.c b/trunk/drivers/char/raw.c index e139372d0e69..47b8cf281d4a 100644 --- a/trunk/drivers/char/raw.c +++ b/trunk/drivers/char/raw.c @@ -131,8 +131,8 @@ raw_ioctl(struct inode *inode, struct file *filp, static void bind_device(struct raw_config_request *rq) { device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); - device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL, - "raw%d", rq->raw_minor); + device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), + NULL, "raw%d", rq->raw_minor); } /* @@ -283,7 +283,8 @@ static int __init raw_init(void) ret = PTR_ERR(raw_class); goto error_region; } - device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); + device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, + "rawctl"); return 0; diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index 17683de95717..b47710c17885 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -96,7 +96,7 @@ static unsigned long rtc_port; static int rtc_irq; #endif -#ifdef CONFIG_HPET_EMULATE_RTC +#ifdef CONFIG_HPET_RTC_IRQ #undef RTC_IRQ #endif diff --git a/trunk/drivers/char/snsc.c b/trunk/drivers/char/snsc.c index 32b74de18f5f..3ce60df14c0a 100644 --- a/trunk/drivers/char/snsc.c +++ b/trunk/drivers/char/snsc.c @@ -444,8 +444,8 @@ scdrv_init(void) continue; } - device_create(snsc_class, NULL, dev, NULL, - "%s", devname); + device_create_drvdata(snsc_class, NULL, dev, NULL, + "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, 0 /*ignored */ , diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index 963b03fb29e5..19db1eb87c26 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -405,9 +405,9 @@ static unsigned int stl_baudrates[] = { static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); static int stl_brdinit(struct stlbrd *brdp); -static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); +static int stl_getportstats(struct stlport *portp, comstats_t __user *cp); static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); -static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, struct file *filp); +static int stl_waitcarrier(struct stlport *portp, struct file *filp); /* * CD1400 uart specific handling functions. @@ -612,9 +612,8 @@ static struct class *stallion_class; static void stl_cd_change(struct stlport *portp) { unsigned int oldsigs = portp->sigs; - struct tty_struct *tty = tty_port_tty_get(&portp->port); - if (!tty) + if (!portp->port.tty) return; portp->sigs = stl_getsignals(portp); @@ -624,8 +623,7 @@ static void stl_cd_change(struct stlport *portp) if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) if (portp->port.flags & ASYNC_CHECK_CD) - tty_hangup(tty); - tty_kref_put(tty); + tty_hangup(portp->port.tty); } /* @@ -736,7 +734,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) * On the first open of the device setup the port hardware, and * initialize the per port data structure. */ - tty_port_tty_set(&portp->port, tty); + portp->port.tty = tty; tty->driver_data = portp; portp->port.count++; @@ -776,7 +774,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) * then also we might have to wait for carrier. */ if (!(filp->f_flags & O_NONBLOCK)) - if ((rc = stl_waitcarrier(tty, portp, filp)) != 0) + if ((rc = stl_waitcarrier(portp, filp)) != 0) return rc; portp->port.flags |= ASYNC_NORMAL_ACTIVE; @@ -791,8 +789,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) * maybe because if we are clocal then we don't need to wait... */ -static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, - struct file *filp) +static int stl_waitcarrier(struct stlport *portp, struct file *filp) { unsigned long flags; int rc, doclocal; @@ -804,7 +801,7 @@ static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, spin_lock_irqsave(&stallion_lock, flags); - if (tty->termios->c_cflag & CLOCAL) + if (portp->port.tty->termios->c_cflag & CLOCAL) doclocal++; portp->openwaitcnt++; @@ -849,6 +846,8 @@ static void stl_flushbuffer(struct tty_struct *tty) pr_debug("stl_flushbuffer(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -866,6 +865,8 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -948,7 +949,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp) tty_ldisc_flush(tty); tty->closing = 0; - tty_port_tty_set(&portp->port, NULL); + portp->port.tty = NULL; if (portp->openwaitcnt) { if (portp->close_delay) @@ -1032,6 +1033,8 @@ static int stl_putchar(struct tty_struct *tty, unsigned char ch) pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); + if (tty == NULL) + return -EINVAL; portp = tty->driver_data; if (portp == NULL) return -EINVAL; @@ -1067,6 +1070,8 @@ static void stl_flushchars(struct tty_struct *tty) pr_debug("stl_flushchars(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1085,6 +1090,8 @@ static int stl_writeroom(struct tty_struct *tty) pr_debug("stl_writeroom(tty=%p)\n", tty); + if (tty == NULL) + return 0; portp = tty->driver_data; if (portp == NULL) return 0; @@ -1115,6 +1122,8 @@ static int stl_charsinbuffer(struct tty_struct *tty) pr_debug("stl_charsinbuffer(tty=%p)\n", tty); + if (tty == NULL) + return 0; portp = tty->driver_data; if (portp == NULL) return 0; @@ -1174,9 +1183,8 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) * just quietly ignore any requests to change irq, etc. */ -static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp) +static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) { - struct stlport * portp = tty->driver_data; struct serial_struct sio; pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); @@ -1197,7 +1205,7 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp portp->close_delay = sio.close_delay; portp->closing_wait = sio.closing_wait; portp->custom_divisor = sio.custom_divisor; - stl_setport(portp, tty->termios); + stl_setport(portp, portp->port.tty->termios); return 0; } @@ -1207,6 +1215,8 @@ static int stl_tiocmget(struct tty_struct *tty, struct file *file) { struct stlport *portp; + if (tty == NULL) + return -ENODEV; portp = tty->driver_data; if (portp == NULL) return -ENODEV; @@ -1222,6 +1232,8 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file, struct stlport *portp; int rts = -1, dtr = -1; + if (tty == NULL) + return -ENODEV; portp = tty->driver_data; if (portp == NULL) return -ENODEV; @@ -1250,6 +1262,8 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, arg); + if (tty == NULL) + return -ENODEV; portp = tty->driver_data; if (portp == NULL) return -ENODEV; @@ -1268,10 +1282,10 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd rc = stl_getserial(portp, argp); break; case TIOCSSERIAL: - rc = stl_setserial(tty, argp); + rc = stl_setserial(portp, argp); break; case COM_GETPORTSTATS: - rc = stl_getportstats(tty, portp, argp); + rc = stl_getportstats(portp, argp); break; case COM_CLRPORTSTATS: rc = stl_clrportstats(portp, argp); @@ -1303,6 +1317,8 @@ static void stl_start(struct tty_struct *tty) pr_debug("stl_start(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1318,6 +1334,8 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old) pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1351,6 +1369,8 @@ static void stl_throttle(struct tty_struct *tty) pr_debug("stl_throttle(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1369,6 +1389,8 @@ static void stl_unthrottle(struct tty_struct *tty) pr_debug("stl_unthrottle(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1388,6 +1410,8 @@ static void stl_stop(struct tty_struct *tty) pr_debug("stl_stop(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1408,6 +1432,8 @@ static void stl_hangup(struct tty_struct *tty) pr_debug("stl_hangup(tty=%p)\n", tty); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1426,7 +1452,7 @@ static void stl_hangup(struct tty_struct *tty) portp->tx.head = NULL; portp->tx.tail = NULL; } - tty_port_tty_set(&portp->port, NULL); + portp->port.tty = NULL; portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; portp->port.count = 0; wake_up_interruptible(&portp->port.open_wait); @@ -1440,6 +1466,8 @@ static int stl_breakctl(struct tty_struct *tty, int state) pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); + if (tty == NULL) + return -EINVAL; portp = tty->driver_data; if (portp == NULL) return -EINVAL; @@ -1456,6 +1484,8 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); + if (tty == NULL) + return; portp = tty->driver_data; if (portp == NULL) return; @@ -1775,7 +1805,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) "(size=%Zd)\n", sizeof(struct stlport)); break; } - tty_port_init(&portp->port); + portp->magic = STL_PORTMAGIC; portp->portnr = i; portp->brdnr = panelp->brdnr; @@ -1802,7 +1832,6 @@ static void stl_cleanup_panels(struct stlbrd *brdp) struct stlpanel *panelp; struct stlport *portp; unsigned int j, k; - struct tty_struct *tty; for (j = 0; j < STL_MAXPANELS; j++) { panelp = brdp->panels[j]; @@ -1812,11 +1841,8 @@ static void stl_cleanup_panels(struct stlbrd *brdp) portp = panelp->ports[k]; if (portp == NULL) continue; - tty = tty_port_tty_get(&portp->port); - if (tty != NULL) { - stl_hangup(tty); - tty_kref_put(tty); - } + if (portp->port.tty != NULL) + stl_hangup(portp->port.tty); kfree(portp->tx.buf); kfree(portp); } @@ -2472,7 +2498,7 @@ static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) * what port to get stats for (used through board control device). */ -static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp) +static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) { comstats_t stl_comstats; unsigned char *head, *tail; @@ -2499,17 +2525,18 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst portp->stats.rxbuffered = 0; spin_lock_irqsave(&stallion_lock, flags); - if (tty != NULL && portp->port.tty == tty) { - portp->stats.ttystate = tty->flags; - /* No longer available as a statistic */ - portp->stats.rxbuffered = 1; /*tty->flip.count; */ - if (tty->termios != NULL) { - portp->stats.cflags = tty->termios->c_cflag; - portp->stats.iflags = tty->termios->c_iflag; - portp->stats.oflags = tty->termios->c_oflag; - portp->stats.lflags = tty->termios->c_lflag; + if (portp->port.tty != NULL) + if (portp->port.tty->driver_data == portp) { + portp->stats.ttystate = portp->port.tty->flags; + /* No longer available as a statistic */ + portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */ + if (portp->port.tty->termios != NULL) { + portp->stats.cflags = portp->port.tty->termios->c_cflag; + portp->stats.iflags = portp->port.tty->termios->c_iflag; + portp->stats.oflags = portp->port.tty->termios->c_oflag; + portp->stats.lflags = portp->port.tty->termios->c_lflag; + } } - } spin_unlock_irqrestore(&stallion_lock, flags); head = portp->tx.head; @@ -2613,7 +2640,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns switch (cmd) { case COM_GETPORTSTATS: - rc = stl_getportstats(NULL, NULL, argp); + rc = stl_getportstats(NULL, argp); break; case COM_CLRPORTSTATS: rc = stl_clrportstats(NULL, argp); @@ -3216,7 +3243,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) if (portp == NULL) return; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if (tty == NULL) return; @@ -3261,7 +3288,6 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) BRDDISABLE(portp->brdnr); spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); } /*****************************************************************************/ @@ -3279,7 +3305,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) if (portp == NULL) return; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if (tty == NULL) return; @@ -3299,7 +3325,6 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) } BRDDISABLE(portp->brdnr); spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); } /*****************************************************************************/ @@ -3453,7 +3478,6 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) int len, stlen; char *head, *tail; unsigned char ioack, srer; - struct tty_struct *tty; pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); @@ -3480,11 +3504,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) if ((len == 0) || ((len < STL_TXBUFLOW) && (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { set_bit(ASYI_TXLOW, &portp->istate); - tty = tty_port_tty_get(&portp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + if (portp->port.tty) + tty_wakeup(portp->port.tty); } if (len == 0) { @@ -3548,7 +3569,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) return; } portp = panelp->ports[(ioack >> 3)]; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { outb((RDCR + portp->uartaddr), ioaddr); @@ -3612,12 +3633,10 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) } } else { printk("STALLION: bad RX interrupt ack value=%x\n", ioack); - tty_kref_put(tty); return; } stl_rxalldone: - tty_kref_put(tty); outb((EOSRR + portp->uartaddr), ioaddr); outb(0, (ioaddr + EREG_DATA)); } @@ -4156,7 +4175,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) if (portp == NULL) return; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if (tty == NULL) return; @@ -4207,7 +4226,6 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) BRDDISABLE(portp->brdnr); spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); } /*****************************************************************************/ @@ -4226,7 +4244,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) if (portp == NULL) return; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; if (tty == NULL) return; @@ -4251,7 +4269,6 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) } BRDDISABLE(portp->brdnr); spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); } /*****************************************************************************/ @@ -4391,7 +4408,6 @@ static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) static void stl_sc26198txisr(struct stlport *portp) { - struct tty_struct *tty; unsigned int ioaddr; unsigned char mr0; int len, stlen; @@ -4406,11 +4422,8 @@ static void stl_sc26198txisr(struct stlport *portp) if ((len == 0) || ((len < STL_TXBUFLOW) && (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { set_bit(ASYI_TXLOW, &portp->istate); - tty = tty_port_tty_get(&portp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + if (portp->port.tty) + tty_wakeup(portp->port.tty); } if (len == 0) { @@ -4463,7 +4476,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; ioaddr = portp->ioaddr; outb(GIBCR, (ioaddr + XP_ADDR)); len = inb(ioaddr + XP_DATA) + 1; @@ -4502,7 +4515,6 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) stl_sc26198txunflow(portp, tty); } } - tty_kref_put(tty); } /*****************************************************************************/ @@ -4516,7 +4528,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char struct tty_struct *tty; unsigned int ioaddr; - tty = tty_port_tty_get(&portp->port); + tty = portp->port.tty; ioaddr = portp->ioaddr; if (status & SR_RXPARITY) @@ -4554,7 +4566,6 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char if (status == 0) portp->stats.rxtotal++; } - tty_kref_put(tty); } /*****************************************************************************/ @@ -4743,8 +4754,8 @@ static int __init stallion_module_init(void) if (IS_ERR(stallion_class)) printk("STALLION: failed to create class\n"); for (i = 0; i < 4; i++) - device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), - NULL, "staliomem%d", i); + device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), + NULL, "staliomem%d", i); return 0; err_unrtty: diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index 5b8d7a1aa3e6..c385206f9db5 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -2504,7 +2504,7 @@ static void __devexit sx_remove_card(struct sx_board *board, del_timer(&board->timer); if (pdev) { #ifdef CONFIG_PCI - pci_iounmap(pdev, board->base2); + pci_iounmap(pdev, board->base); pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); #endif } else { @@ -2703,7 +2703,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev, return 0; err_unmap: - pci_iounmap(pdev, board->base2); + pci_iounmap(pdev, board->base); err_reg: pci_release_region(pdev, reg); err_flag: diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index dce4cc0e6953..8fdfe9c871e3 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -327,7 +326,6 @@ static struct sysrq_key_op sysrq_moom_op = { .handler = sysrq_handle_moom, .help_msg = "Full", .action_msg = "Manual OOM execution", - .enable_mask = SYSRQ_ENABLE_SIGNAL, }; static void sysrq_handle_kill(int key, struct tty_struct *tty) @@ -535,32 +533,3 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) return __sysrq_swap_key_ops(key, NULL, op_p); } EXPORT_SYMBOL(unregister_sysrq_key); - -#ifdef CONFIG_PROC_FS -/* - * writing 'C' to /proc/sysrq-trigger is like sysrq-C - */ -static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - if (count) { - char c; - - if (get_user(c, buf)) - return -EFAULT; - __handle_sysrq(c, NULL, 0); - } - return count; -} - -static const struct file_operations proc_sysrq_trigger_operations = { - .write = write_sysrq_trigger, -}; - -static int __init sysrq_init(void) -{ - proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations); - return 0; -} -module_init(sysrq_init); -#endif diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index e70d13defde4..ae766d868454 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -525,19 +525,19 @@ void tpm_get_timeouts(struct tpm_chip *chip) timeout = be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))); if (timeout) - chip->vendor.timeout_a = usecs_to_jiffies(timeout); + chip->vendor.timeout_a = msecs_to_jiffies(timeout); timeout = be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX))); if (timeout) - chip->vendor.timeout_b = usecs_to_jiffies(timeout); + chip->vendor.timeout_b = msecs_to_jiffies(timeout); timeout = be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX))); if (timeout) - chip->vendor.timeout_c = usecs_to_jiffies(timeout); + chip->vendor.timeout_c = msecs_to_jiffies(timeout); timeout = be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX))); if (timeout) - chip->vendor.timeout_d = usecs_to_jiffies(timeout); + chip->vendor.timeout_d = msecs_to_jiffies(timeout); duration: memcpy(data, tpm_cap, sizeof(tpm_cap)); @@ -554,22 +554,15 @@ void tpm_get_timeouts(struct tpm_chip *chip) return; chip->vendor.duration[TPM_SHORT] = - usecs_to_jiffies(be32_to_cpu + msecs_to_jiffies(be32_to_cpu (*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); - /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above - * value wrong and apparently reports msecs rather than usecs. So we - * fix up the resulting too-small TPM_SHORT value to make things work. - */ - if (chip->vendor.duration[TPM_SHORT] < (HZ/100)) - chip->vendor.duration[TPM_SHORT] = HZ; - chip->vendor.duration[TPM_MEDIUM] = - usecs_to_jiffies(be32_to_cpu + msecs_to_jiffies(be32_to_cpu (*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)))); chip->vendor.duration[TPM_LONG] = - usecs_to_jiffies(be32_to_cpu + msecs_to_jiffies(be32_to_cpu (*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)))); } @@ -961,63 +954,72 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel); /* * Device file system interface to the TPM - * - * It's assured that the chip will be opened just once, - * by the check of is_open variable, which is protected - * by driver_lock. */ int tpm_open(struct inode *inode, struct file *file) { - int minor = iminor(inode); + int rc = 0, minor = iminor(inode); struct tpm_chip *chip = NULL, *pos; - rcu_read_lock(); - list_for_each_entry_rcu(pos, &tpm_chip_list, list) { + lock_kernel(); + spin_lock(&driver_lock); + + list_for_each_entry(pos, &tpm_chip_list, list) { if (pos->vendor.miscdev.minor == minor) { chip = pos; - get_device(chip->dev); break; } } - rcu_read_unlock(); - if (!chip) - return -ENODEV; + if (chip == NULL) { + rc = -ENODEV; + goto err_out; + } - if (test_and_set_bit(0, &chip->is_open)) { + if (chip->num_opens) { dev_dbg(chip->dev, "Another process owns this TPM\n"); - put_device(chip->dev); - return -EBUSY; + rc = -EBUSY; + goto err_out; } + chip->num_opens++; + get_device(chip->dev); + + spin_unlock(&driver_lock); + chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); if (chip->data_buffer == NULL) { - clear_bit(0, &chip->is_open); + chip->num_opens--; put_device(chip->dev); + unlock_kernel(); return -ENOMEM; } atomic_set(&chip->data_pending, 0); file->private_data = chip; + unlock_kernel(); return 0; + +err_out: + spin_unlock(&driver_lock); + unlock_kernel(); + return rc; } EXPORT_SYMBOL_GPL(tpm_open); -/* - * Called on file close - */ int tpm_release(struct inode *inode, struct file *file) { struct tpm_chip *chip = file->private_data; - del_singleshot_timer_sync(&chip->user_read_timer); flush_scheduled_work(); + spin_lock(&driver_lock); file->private_data = NULL; + del_singleshot_timer_sync(&chip->user_read_timer); atomic_set(&chip->data_pending, 0); - kfree(chip->data_buffer); - clear_bit(0, &chip->is_open); + chip->num_opens--; put_device(chip->dev); + kfree(chip->data_buffer); + spin_unlock(&driver_lock); return 0; } EXPORT_SYMBOL_GPL(tpm_release); @@ -1091,11 +1093,13 @@ void tpm_remove_hardware(struct device *dev) } spin_lock(&driver_lock); - list_del_rcu(&chip->list); + + list_del(&chip->list); + spin_unlock(&driver_lock); - synchronize_rcu(); misc_deregister(&chip->vendor.miscdev); + sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); tpm_bios_log_teardown(chip->bios_dir); @@ -1140,33 +1144,25 @@ int tpm_pm_resume(struct device *dev) } EXPORT_SYMBOL_GPL(tpm_pm_resume); -/* In case vendor provided release function, call it too.*/ - -void tpm_dev_vendor_release(struct tpm_chip *chip) -{ - if (chip->vendor.release) - chip->vendor.release(chip->dev); - - clear_bit(chip->dev_num, dev_mask); - kfree(chip->vendor.miscdev.name); -} -EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); - - /* * Once all references to platform device are down to 0, * release all allocated structures. + * In case vendor provided release function, + * call it too. */ static void tpm_dev_release(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); - tpm_dev_vendor_release(chip); + if (chip->vendor.release) + chip->vendor.release(dev); chip->release(dev); + + clear_bit(chip->dev_num, dev_mask); + kfree(chip->vendor.miscdev.name); kfree(chip); } -EXPORT_SYMBOL_GPL(tpm_dev_release); /* * Called from tpm_.c probe function only for devices @@ -1175,8 +1171,8 @@ EXPORT_SYMBOL_GPL(tpm_dev_release); * upon errant exit from this function specific probe function should call * pci_disable_device */ -struct tpm_chip *tpm_register_hardware(struct device *dev, - const struct tpm_vendor_specific *entry) +struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific + *entry) { #define DEVNAME_SIZE 7 @@ -1187,8 +1183,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, chip = kzalloc(sizeof(*chip), GFP_KERNEL); devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); - if (chip == NULL || devname == NULL) - goto out_free; + if (chip == NULL || devname == NULL) { + kfree(chip); + kfree(devname); + return NULL; + } mutex_init(&chip->buffer_mutex); mutex_init(&chip->tpm_mutex); @@ -1205,7 +1204,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, if (chip->dev_num >= TPM_NUM_DEVICES) { dev_err(dev, "No available tpm device numbers\n"); - goto out_free; + kfree(chip); + return NULL; } else if (chip->dev_num == 0) chip->vendor.miscdev.minor = TPM_MINOR; else @@ -1231,26 +1231,22 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, return NULL; } + spin_lock(&driver_lock); + + list_add(&chip->list, &tpm_chip_list); + + spin_unlock(&driver_lock); + if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { + list_del(&chip->list); misc_deregister(&chip->vendor.miscdev); put_device(chip->dev); - return NULL; } chip->bios_dir = tpm_bios_log_setup(devname); - /* Make chip available */ - spin_lock(&driver_lock); - list_add_rcu(&chip->list, &tpm_chip_list); - spin_unlock(&driver_lock); - return chip; - -out_free: - kfree(chip); - kfree(devname); - return NULL; } EXPORT_SYMBOL_GPL(tpm_register_hardware); diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h index 8e30df4a4388..e885148b4cfb 100644 --- a/trunk/drivers/char/tpm/tpm.h +++ b/trunk/drivers/char/tpm/tpm.h @@ -90,7 +90,7 @@ struct tpm_chip { struct device *dev; /* Device stuff */ int dev_num; /* /dev/tpm# */ - unsigned long is_open; /* only one allowed */ + int num_opens; /* only one allowed */ int time_expired; /* Data passed to and from the tpm via the read/write calls */ @@ -132,7 +132,6 @@ extern struct tpm_chip* tpm_register_hardware(struct device *, const struct tpm_vendor_specific *); extern int tpm_open(struct inode *, struct file *); extern int tpm_release(struct inode *, struct file *); -extern void tpm_dev_vendor_release(struct tpm_chip *); extern ssize_t tpm_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index 717af7ad1bdf..ed1879c0dd8d 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -630,23 +630,12 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { {"", 0} /* Terminator */ }; -static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) -{ - struct tpm_chip *chip = pnp_get_drvdata(dev); - - tpm_dev_vendor_release(chip); - - kfree(chip); -} - - static struct pnp_driver tis_pnp_driver = { .name = "tpm_tis", .id_table = tpm_pnp_tbl, .probe = tpm_tis_pnp_init, .suspend = tpm_tis_pnp_suspend, .resume = tpm_tis_pnp_resume, - .remove = tpm_tis_pnp_remove, }; #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 @@ -694,7 +683,6 @@ static void __exit cleanup_tis(void) spin_lock(&tis_lock); list_for_each_entry_safe(i, j, &tis_chips, list) { chip = to_tpm_chip(i); - tpm_remove_hardware(chip->dev); iowrite32(~TPM_GLOBAL_INT_ENABLE & ioread32(chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor. @@ -706,9 +694,9 @@ static void __exit cleanup_tis(void) free_irq(chip->vendor.irq, chip); iounmap(i->iobase); list_del(&i->list); + tpm_remove_hardware(chip->dev); } spin_unlock(&tis_lock); - if (force) { platform_device_unregister(pdev); driver_unregister(&tis_drv); diff --git a/trunk/drivers/char/tty_audit.c b/trunk/drivers/char/tty_audit.c index 5787249934c8..3582f43345a8 100644 --- a/trunk/drivers/char/tty_audit.c +++ b/trunk/drivers/char/tty_audit.c @@ -93,7 +93,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, get_task_comm(name, tsk); audit_log_untrustedstring(ab, name); audit_log_format(ab, " data="); - audit_log_n_hex(ab, buf->data, buf->valid); + audit_log_n_untrustedstring(ab, buf->data, buf->valid); audit_log_end(ab); } buf->valid = 0; diff --git a/trunk/drivers/char/tty_buffer.c b/trunk/drivers/char/tty_buffer.c deleted file mode 100644 index 810ee25d66a4..000000000000 --- a/trunk/drivers/char/tty_buffer.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Tty buffer allocation management - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * tty_buffer_free_all - free buffers used by a tty - * @tty: tty to free from - * - * Remove all the buffers pending on a tty whether queued with data - * or in the free ring. Must be called when the tty is no longer in use - * - * Locking: none - */ - -void tty_buffer_free_all(struct tty_struct *tty) -{ - struct tty_buffer *thead; - while ((thead = tty->buf.head) != NULL) { - tty->buf.head = thead->next; - kfree(thead); - } - while ((thead = tty->buf.free) != NULL) { - tty->buf.free = thead->next; - kfree(thead); - } - tty->buf.tail = NULL; - tty->buf.memory_used = 0; -} - -/** - * tty_buffer_alloc - allocate a tty buffer - * @tty: tty device - * @size: desired size (characters) - * - * Allocate a new tty buffer to hold the desired number of characters. - * Return NULL if out of memory or the allocation would exceed the - * per device queue - * - * Locking: Caller must hold tty->buf.lock - */ - -static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) -{ - struct tty_buffer *p; - - if (tty->buf.memory_used + size > 65536) - return NULL; - p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); - if (p == NULL) - return NULL; - p->used = 0; - p->size = size; - p->next = NULL; - p->commit = 0; - p->read = 0; - p->char_buf_ptr = (char *)(p->data); - p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; - tty->buf.memory_used += size; - return p; -} - -/** - * tty_buffer_free - free a tty buffer - * @tty: tty owning the buffer - * @b: the buffer to free - * - * Free a tty buffer, or add it to the free list according to our - * internal strategy - * - * Locking: Caller must hold tty->buf.lock - */ - -static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) -{ - /* Dumb strategy for now - should keep some stats */ - tty->buf.memory_used -= b->size; - WARN_ON(tty->buf.memory_used < 0); - - if (b->size >= 512) - kfree(b); - else { - b->next = tty->buf.free; - tty->buf.free = b; - } -} - -/** - * __tty_buffer_flush - flush full tty buffers - * @tty: tty to flush - * - * flush all the buffers containing receive data. Caller must - * hold the buffer lock and must have ensured no parallel flush to - * ldisc is running. - * - * Locking: Caller must hold tty->buf.lock - */ - -static void __tty_buffer_flush(struct tty_struct *tty) -{ - struct tty_buffer *thead; - - while ((thead = tty->buf.head) != NULL) { - tty->buf.head = thead->next; - tty_buffer_free(tty, thead); - } - tty->buf.tail = NULL; -} - -/** - * tty_buffer_flush - flush full tty buffers - * @tty: tty to flush - * - * flush all the buffers containing receive data. If the buffer is - * being processed by flush_to_ldisc then we defer the processing - * to that function - * - * Locking: none - */ - -void tty_buffer_flush(struct tty_struct *tty) -{ - unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); - - /* If the data is being pushed to the tty layer then we can't - process it here. Instead set a flag and the flush_to_ldisc - path will process the flush request before it exits */ - if (test_bit(TTY_FLUSHING, &tty->flags)) { - set_bit(TTY_FLUSHPENDING, &tty->flags); - spin_unlock_irqrestore(&tty->buf.lock, flags); - wait_event(tty->read_wait, - test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); - return; - } else - __tty_buffer_flush(tty); - spin_unlock_irqrestore(&tty->buf.lock, flags); -} - -/** - * tty_buffer_find - find a free tty buffer - * @tty: tty owning the buffer - * @size: characters wanted - * - * Locate an existing suitable tty buffer or if we are lacking one then - * allocate a new one. We round our buffers off in 256 character chunks - * to get better allocation behaviour. - * - * Locking: Caller must hold tty->buf.lock - */ - -static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) -{ - struct tty_buffer **tbh = &tty->buf.free; - while ((*tbh) != NULL) { - struct tty_buffer *t = *tbh; - if (t->size >= size) { - *tbh = t->next; - t->next = NULL; - t->used = 0; - t->commit = 0; - t->read = 0; - tty->buf.memory_used += t->size; - return t; - } - tbh = &((*tbh)->next); - } - /* Round the buffer size out */ - size = (size + 0xFF) & ~0xFF; - return tty_buffer_alloc(tty, size); - /* Should possibly check if this fails for the largest buffer we - have queued and recycle that ? */ -} - -/** - * tty_buffer_request_room - grow tty buffer if needed - * @tty: tty structure - * @size: size desired - * - * Make at least size bytes of linear space available for the tty - * buffer. If we fail return the size we managed to find. - * - * Locking: Takes tty->buf.lock - */ -int tty_buffer_request_room(struct tty_struct *tty, size_t size) -{ - struct tty_buffer *b, *n; - int left; - unsigned long flags; - - spin_lock_irqsave(&tty->buf.lock, flags); - - /* OPTIMISATION: We could keep a per tty "zero" sized buffer to - remove this conditional if its worth it. This would be invisible - to the callers */ - if ((b = tty->buf.tail) != NULL) - left = b->size - b->used; - else - left = 0; - - if (left < size) { - /* This is the slow path - looking for new buffers to use */ - if ((n = tty_buffer_find(tty, size)) != NULL) { - if (b != NULL) { - b->next = n; - b->commit = b->used; - } else - tty->buf.head = n; - tty->buf.tail = n; - } else - size = left; - } - - spin_unlock_irqrestore(&tty->buf.lock, flags); - return size; -} -EXPORT_SYMBOL_GPL(tty_buffer_request_room); - -/** - * tty_insert_flip_string - Add characters to the tty buffer - * @tty: tty structure - * @chars: characters - * @size: size - * - * Queue a series of bytes to the tty buffering. All the characters - * passed are marked as without error. Returns the number added. - * - * Locking: Called functions may take tty->buf.lock - */ - -int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, - size_t size) -{ - int copied = 0; - do { - int space = tty_buffer_request_room(tty, size - copied); - struct tty_buffer *tb = tty->buf.tail; - /* If there is no space then tb may be NULL */ - if (unlikely(space == 0)) - break; - memcpy(tb->char_buf_ptr + tb->used, chars, space); - memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); - tb->used += space; - copied += space; - chars += space; - /* There is a small chance that we need to split the data over - several buffers. If this is the case we must loop */ - } while (unlikely(size > copied)); - return copied; -} -EXPORT_SYMBOL(tty_insert_flip_string); - -/** - * tty_insert_flip_string_flags - Add characters to the tty buffer - * @tty: tty structure - * @chars: characters - * @flags: flag bytes - * @size: size - * - * Queue a series of bytes to the tty buffering. For each character - * the flags array indicates the status of the character. Returns the - * number added. - * - * Locking: Called functions may take tty->buf.lock - */ - -int tty_insert_flip_string_flags(struct tty_struct *tty, - const unsigned char *chars, const char *flags, size_t size) -{ - int copied = 0; - do { - int space = tty_buffer_request_room(tty, size - copied); - struct tty_buffer *tb = tty->buf.tail; - /* If there is no space then tb may be NULL */ - if (unlikely(space == 0)) - break; - memcpy(tb->char_buf_ptr + tb->used, chars, space); - memcpy(tb->flag_buf_ptr + tb->used, flags, space); - tb->used += space; - copied += space; - chars += space; - flags += space; - /* There is a small chance that we need to split the data over - several buffers. If this is the case we must loop */ - } while (unlikely(size > copied)); - return copied; -} -EXPORT_SYMBOL(tty_insert_flip_string_flags); - -/** - * tty_schedule_flip - push characters to ldisc - * @tty: tty to push from - * - * Takes any pending buffers and transfers their ownership to the - * ldisc side of the queue. It then schedules those characters for - * processing by the line discipline. - * - * Locking: Takes tty->buf.lock - */ - -void tty_schedule_flip(struct tty_struct *tty) -{ - unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) - tty->buf.tail->commit = tty->buf.tail->used; - spin_unlock_irqrestore(&tty->buf.lock, flags); - schedule_delayed_work(&tty->buf.work, 1); -} -EXPORT_SYMBOL(tty_schedule_flip); - -/** - * tty_prepare_flip_string - make room for characters - * @tty: tty - * @chars: return pointer for character write area - * @size: desired size - * - * Prepare a block of space in the buffer for data. Returns the length - * available and buffer pointer to the space which is now allocated and - * accounted for as ready for normal characters. This is used for drivers - * that need their own block copy routines into the buffer. There is no - * guarantee the buffer is a DMA target! - * - * Locking: May call functions taking tty->buf.lock - */ - -int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, - size_t size) -{ - int space = tty_buffer_request_room(tty, size); - if (likely(space)) { - struct tty_buffer *tb = tty->buf.tail; - *chars = tb->char_buf_ptr + tb->used; - memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); - tb->used += space; - } - return space; -} -EXPORT_SYMBOL_GPL(tty_prepare_flip_string); - -/** - * tty_prepare_flip_string_flags - make room for characters - * @tty: tty - * @chars: return pointer for character write area - * @flags: return pointer for status flag write area - * @size: desired size - * - * Prepare a block of space in the buffer for data. Returns the length - * available and buffer pointer to the space which is now allocated and - * accounted for as ready for characters. This is used for drivers - * that need their own block copy routines into the buffer. There is no - * guarantee the buffer is a DMA target! - * - * Locking: May call functions taking tty->buf.lock - */ - -int tty_prepare_flip_string_flags(struct tty_struct *tty, - unsigned char **chars, char **flags, size_t size) -{ - int space = tty_buffer_request_room(tty, size); - if (likely(space)) { - struct tty_buffer *tb = tty->buf.tail; - *chars = tb->char_buf_ptr + tb->used; - *flags = tb->flag_buf_ptr + tb->used; - tb->used += space; - } - return space; -} -EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); - - - -/** - * flush_to_ldisc - * @work: tty structure passed from work queue. - * - * This routine is called out of the software interrupt to flush data - * from the buffer chain to the line discipline. - * - * Locking: holds tty->buf.lock to guard buffer list. Drops the lock - * while invoking the line discipline receive_buf method. The - * receive_buf method is single threaded for each tty instance. - */ - -static void flush_to_ldisc(struct work_struct *work) -{ - struct tty_struct *tty = - container_of(work, struct tty_struct, buf.work.work); - unsigned long flags; - struct tty_ldisc *disc; - struct tty_buffer *tbuf, *head; - char *char_buf; - unsigned char *flag_buf; - - disc = tty_ldisc_ref(tty); - if (disc == NULL) /* !TTY_LDISC */ - return; - - spin_lock_irqsave(&tty->buf.lock, flags); - /* So we know a flush is running */ - set_bit(TTY_FLUSHING, &tty->flags); - head = tty->buf.head; - if (head != NULL) { - tty->buf.head = NULL; - for (;;) { - int count = head->commit - head->read; - if (!count) { - if (head->next == NULL) - break; - tbuf = head; - head = head->next; - tty_buffer_free(tty, tbuf); - continue; - } - /* Ldisc or user is trying to flush the buffers - we are feeding to the ldisc, stop feeding the - line discipline as we want to empty the queue */ - if (test_bit(TTY_FLUSHPENDING, &tty->flags)) - break; - if (!tty->receive_room) { - schedule_delayed_work(&tty->buf.work, 1); - break; - } - if (count > tty->receive_room) - count = tty->receive_room; - char_buf = head->char_buf_ptr + head->read; - flag_buf = head->flag_buf_ptr + head->read; - head->read += count; - spin_unlock_irqrestore(&tty->buf.lock, flags); - disc->ops->receive_buf(tty, char_buf, - flag_buf, count); - spin_lock_irqsave(&tty->buf.lock, flags); - } - /* Restore the queue head */ - tty->buf.head = head; - } - /* We may have a deferred request to flush the input buffer, - if so pull the chain under the lock and empty the queue */ - if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { - __tty_buffer_flush(tty); - clear_bit(TTY_FLUSHPENDING, &tty->flags); - wake_up(&tty->read_wait); - } - clear_bit(TTY_FLUSHING, &tty->flags); - spin_unlock_irqrestore(&tty->buf.lock, flags); - - tty_ldisc_deref(disc); -} - -/** - * tty_flip_buffer_push - terminal - * @tty: tty to push - * - * Queue a push of the terminal flip buffers to the line discipline. This - * function must not be called from IRQ context if tty->low_latency is set. - * - * In the event of the queue being busy for flipping the work will be - * held off and retried later. - * - * Locking: tty buffer lock. Driver locks in low latency mode. - */ - -void tty_flip_buffer_push(struct tty_struct *tty) -{ - unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) - tty->buf.tail->commit = tty->buf.tail->used; - spin_unlock_irqrestore(&tty->buf.lock, flags); - - if (tty->low_latency) - flush_to_ldisc(&tty->buf.work.work); - else - schedule_delayed_work(&tty->buf.work, 1); -} -EXPORT_SYMBOL(tty_flip_buffer_push); - -/** - * tty_buffer_init - prepare a tty buffer structure - * @tty: tty to initialise - * - * Set up the initial state of the buffer management for a tty device. - * Must be called before the other tty buffer functions are used. - * - * Locking: none - */ - -void tty_buffer_init(struct tty_struct *tty) -{ - spin_lock_init(&tty->buf.lock); - tty->buf.head = NULL; - tty->buf.tail = NULL; - tty->buf.free = NULL; - tty->buf.memory_used = 0; - INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); -} - diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 59f472143f08..e4dce8709541 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -49,7 +49,7 @@ * implement CONFIG_VT and generalize console device interface. * -- Marko Kohtala , March 97 * - * Rewrote tty_init_dev and tty_release_dev to eliminate races. + * Rewrote init_dev and release_dev to eliminate races. * -- Bill Hawes , June 97 * * Added devfs support. @@ -136,6 +136,13 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ DEFINE_MUTEX(tty_mutex); EXPORT_SYMBOL(tty_mutex); +#ifdef CONFIG_UNIX98_PTYS +extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ +static int ptmx_open(struct inode *, struct file *); +#endif + +static void initialize_tty_struct(struct tty_struct *tty); + static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); ssize_t redirected_tty_write(struct file *, const char __user *, @@ -164,11 +171,13 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); * Locking: none */ -struct tty_struct *alloc_tty_struct(void) +static struct tty_struct *alloc_tty_struct(void) { return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); } +static void tty_buffer_free_all(struct tty_struct *); + /** * free_tty_struct - free a disused tty * @tty: tty struct to free @@ -178,7 +187,7 @@ struct tty_struct *alloc_tty_struct(void) * Locking: none. Must be called after tty is definitely unused */ -void free_tty_struct(struct tty_struct *tty) +static inline void free_tty_struct(struct tty_struct *tty) { kfree(tty->write_buf); tty_buffer_free_all(tty); @@ -254,6 +263,398 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) return 0; } +/* + * Tty buffer allocation management + */ + +/** + * tty_buffer_free_all - free buffers used by a tty + * @tty: tty to free from + * + * Remove all the buffers pending on a tty whether queued with data + * or in the free ring. Must be called when the tty is no longer in use + * + * Locking: none + */ + +static void tty_buffer_free_all(struct tty_struct *tty) +{ + struct tty_buffer *thead; + while ((thead = tty->buf.head) != NULL) { + tty->buf.head = thead->next; + kfree(thead); + } + while ((thead = tty->buf.free) != NULL) { + tty->buf.free = thead->next; + kfree(thead); + } + tty->buf.tail = NULL; + tty->buf.memory_used = 0; +} + +/** + * tty_buffer_init - prepare a tty buffer structure + * @tty: tty to initialise + * + * Set up the initial state of the buffer management for a tty device. + * Must be called before the other tty buffer functions are used. + * + * Locking: none + */ + +static void tty_buffer_init(struct tty_struct *tty) +{ + spin_lock_init(&tty->buf.lock); + tty->buf.head = NULL; + tty->buf.tail = NULL; + tty->buf.free = NULL; + tty->buf.memory_used = 0; +} + +/** + * tty_buffer_alloc - allocate a tty buffer + * @tty: tty device + * @size: desired size (characters) + * + * Allocate a new tty buffer to hold the desired number of characters. + * Return NULL if out of memory or the allocation would exceed the + * per device queue + * + * Locking: Caller must hold tty->buf.lock + */ + +static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) +{ + struct tty_buffer *p; + + if (tty->buf.memory_used + size > 65536) + return NULL; + p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); + if (p == NULL) + return NULL; + p->used = 0; + p->size = size; + p->next = NULL; + p->commit = 0; + p->read = 0; + p->char_buf_ptr = (char *)(p->data); + p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; + tty->buf.memory_used += size; + return p; +} + +/** + * tty_buffer_free - free a tty buffer + * @tty: tty owning the buffer + * @b: the buffer to free + * + * Free a tty buffer, or add it to the free list according to our + * internal strategy + * + * Locking: Caller must hold tty->buf.lock + */ + +static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) +{ + /* Dumb strategy for now - should keep some stats */ + tty->buf.memory_used -= b->size; + WARN_ON(tty->buf.memory_used < 0); + + if (b->size >= 512) + kfree(b); + else { + b->next = tty->buf.free; + tty->buf.free = b; + } +} + +/** + * __tty_buffer_flush - flush full tty buffers + * @tty: tty to flush + * + * flush all the buffers containing receive data. Caller must + * hold the buffer lock and must have ensured no parallel flush to + * ldisc is running. + * + * Locking: Caller must hold tty->buf.lock + */ + +static void __tty_buffer_flush(struct tty_struct *tty) +{ + struct tty_buffer *thead; + + while ((thead = tty->buf.head) != NULL) { + tty->buf.head = thead->next; + tty_buffer_free(tty, thead); + } + tty->buf.tail = NULL; +} + +/** + * tty_buffer_flush - flush full tty buffers + * @tty: tty to flush + * + * flush all the buffers containing receive data. If the buffer is + * being processed by flush_to_ldisc then we defer the processing + * to that function + * + * Locking: none + */ + +static void tty_buffer_flush(struct tty_struct *tty) +{ + unsigned long flags; + spin_lock_irqsave(&tty->buf.lock, flags); + + /* If the data is being pushed to the tty layer then we can't + process it here. Instead set a flag and the flush_to_ldisc + path will process the flush request before it exits */ + if (test_bit(TTY_FLUSHING, &tty->flags)) { + set_bit(TTY_FLUSHPENDING, &tty->flags); + spin_unlock_irqrestore(&tty->buf.lock, flags); + wait_event(tty->read_wait, + test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); + return; + } else + __tty_buffer_flush(tty); + spin_unlock_irqrestore(&tty->buf.lock, flags); +} + +/** + * tty_buffer_find - find a free tty buffer + * @tty: tty owning the buffer + * @size: characters wanted + * + * Locate an existing suitable tty buffer or if we are lacking one then + * allocate a new one. We round our buffers off in 256 character chunks + * to get better allocation behaviour. + * + * Locking: Caller must hold tty->buf.lock + */ + +static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) +{ + struct tty_buffer **tbh = &tty->buf.free; + while ((*tbh) != NULL) { + struct tty_buffer *t = *tbh; + if (t->size >= size) { + *tbh = t->next; + t->next = NULL; + t->used = 0; + t->commit = 0; + t->read = 0; + tty->buf.memory_used += t->size; + return t; + } + tbh = &((*tbh)->next); + } + /* Round the buffer size out */ + size = (size + 0xFF) & ~0xFF; + return tty_buffer_alloc(tty, size); + /* Should possibly check if this fails for the largest buffer we + have queued and recycle that ? */ +} + +/** + * tty_buffer_request_room - grow tty buffer if needed + * @tty: tty structure + * @size: size desired + * + * Make at least size bytes of linear space available for the tty + * buffer. If we fail return the size we managed to find. + * + * Locking: Takes tty->buf.lock + */ +int tty_buffer_request_room(struct tty_struct *tty, size_t size) +{ + struct tty_buffer *b, *n; + int left; + unsigned long flags; + + spin_lock_irqsave(&tty->buf.lock, flags); + + /* OPTIMISATION: We could keep a per tty "zero" sized buffer to + remove this conditional if its worth it. This would be invisible + to the callers */ + if ((b = tty->buf.tail) != NULL) + left = b->size - b->used; + else + left = 0; + + if (left < size) { + /* This is the slow path - looking for new buffers to use */ + if ((n = tty_buffer_find(tty, size)) != NULL) { + if (b != NULL) { + b->next = n; + b->commit = b->used; + } else + tty->buf.head = n; + tty->buf.tail = n; + } else + size = left; + } + + spin_unlock_irqrestore(&tty->buf.lock, flags); + return size; +} +EXPORT_SYMBOL_GPL(tty_buffer_request_room); + +/** + * tty_insert_flip_string - Add characters to the tty buffer + * @tty: tty structure + * @chars: characters + * @size: size + * + * Queue a series of bytes to the tty buffering. All the characters + * passed are marked as without error. Returns the number added. + * + * Locking: Called functions may take tty->buf.lock + */ + +int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, + size_t size) +{ + int copied = 0; + do { + int space = tty_buffer_request_room(tty, size - copied); + struct tty_buffer *tb = tty->buf.tail; + /* If there is no space then tb may be NULL */ + if (unlikely(space == 0)) + break; + memcpy(tb->char_buf_ptr + tb->used, chars, space); + memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); + tb->used += space; + copied += space; + chars += space; + /* There is a small chance that we need to split the data over + several buffers. If this is the case we must loop */ + } while (unlikely(size > copied)); + return copied; +} +EXPORT_SYMBOL(tty_insert_flip_string); + +/** + * tty_insert_flip_string_flags - Add characters to the tty buffer + * @tty: tty structure + * @chars: characters + * @flags: flag bytes + * @size: size + * + * Queue a series of bytes to the tty buffering. For each character + * the flags array indicates the status of the character. Returns the + * number added. + * + * Locking: Called functions may take tty->buf.lock + */ + +int tty_insert_flip_string_flags(struct tty_struct *tty, + const unsigned char *chars, const char *flags, size_t size) +{ + int copied = 0; + do { + int space = tty_buffer_request_room(tty, size - copied); + struct tty_buffer *tb = tty->buf.tail; + /* If there is no space then tb may be NULL */ + if (unlikely(space == 0)) + break; + memcpy(tb->char_buf_ptr + tb->used, chars, space); + memcpy(tb->flag_buf_ptr + tb->used, flags, space); + tb->used += space; + copied += space; + chars += space; + flags += space; + /* There is a small chance that we need to split the data over + several buffers. If this is the case we must loop */ + } while (unlikely(size > copied)); + return copied; +} +EXPORT_SYMBOL(tty_insert_flip_string_flags); + +/** + * tty_schedule_flip - push characters to ldisc + * @tty: tty to push from + * + * Takes any pending buffers and transfers their ownership to the + * ldisc side of the queue. It then schedules those characters for + * processing by the line discipline. + * + * Locking: Takes tty->buf.lock + */ + +void tty_schedule_flip(struct tty_struct *tty) +{ + unsigned long flags; + spin_lock_irqsave(&tty->buf.lock, flags); + if (tty->buf.tail != NULL) + tty->buf.tail->commit = tty->buf.tail->used; + spin_unlock_irqrestore(&tty->buf.lock, flags); + schedule_delayed_work(&tty->buf.work, 1); +} +EXPORT_SYMBOL(tty_schedule_flip); + +/** + * tty_prepare_flip_string - make room for characters + * @tty: tty + * @chars: return pointer for character write area + * @size: desired size + * + * Prepare a block of space in the buffer for data. Returns the length + * available and buffer pointer to the space which is now allocated and + * accounted for as ready for normal characters. This is used for drivers + * that need their own block copy routines into the buffer. There is no + * guarantee the buffer is a DMA target! + * + * Locking: May call functions taking tty->buf.lock + */ + +int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, + size_t size) +{ + int space = tty_buffer_request_room(tty, size); + if (likely(space)) { + struct tty_buffer *tb = tty->buf.tail; + *chars = tb->char_buf_ptr + tb->used; + memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); + tb->used += space; + } + return space; +} + +EXPORT_SYMBOL_GPL(tty_prepare_flip_string); + +/** + * tty_prepare_flip_string_flags - make room for characters + * @tty: tty + * @chars: return pointer for character write area + * @flags: return pointer for status flag write area + * @size: desired size + * + * Prepare a block of space in the buffer for data. Returns the length + * available and buffer pointer to the space which is now allocated and + * accounted for as ready for characters. This is used for drivers + * that need their own block copy routines into the buffer. There is no + * guarantee the buffer is a DMA target! + * + * Locking: May call functions taking tty->buf.lock + */ + +int tty_prepare_flip_string_flags(struct tty_struct *tty, + unsigned char **chars, char **flags, size_t size) +{ + int space = tty_buffer_request_room(tty, size); + if (likely(space)) { + struct tty_buffer *tb = tty->buf.tail; + *chars = tb->char_buf_ptr + tb->used; + *flags = tb->flag_buf_ptr + tb->used; + tb->used += space; + } + return space; +} + +EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); + + + /** * get_tty_driver - find device of a tty * @dev_t: device identifier @@ -274,7 +675,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) if (device < base || device >= base + p->num) continue; *index = device - base; - return tty_driver_kref_get(p); + return p; } return NULL; } @@ -318,7 +719,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) if (tty_line >= 0 && tty_line <= p->num && p->ops && p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { - res = tty_driver_kref_get(p); + res = p; *line = tty_line; break; } @@ -418,6 +819,20 @@ static const struct file_operations tty_fops = { .fasync = tty_fasync, }; +#ifdef CONFIG_UNIX98_PTYS +static const struct file_operations ptmx_fops = { + .llseek = no_llseek, + .read = tty_read, + .write = tty_write, + .poll = tty_poll, + .unlocked_ioctl = tty_ioctl, + .compat_ioctl = tty_compat_ioctl, + .open = ptmx_open, + .release = tty_release, + .fasync = tty_fasync, +}; +#endif + static const struct file_operations console_fops = { .llseek = no_llseek, .read = tty_read, @@ -538,7 +953,6 @@ static void do_tty_hangup(struct work_struct *work) struct tty_ldisc *ld; int closecount = 0, n; unsigned long flags; - int refs = 0; if (!tty) return; @@ -605,12 +1019,8 @@ static void do_tty_hangup(struct work_struct *work) if (tty->session) { do_each_pid_task(tty->session, PIDTYPE_SID, p) { spin_lock_irq(&p->sighand->siglock); - if (p->signal->tty == tty) { + if (p->signal->tty == tty) p->signal->tty = NULL; - /* We defer the dereferences outside fo - the tasklist lock */ - refs++; - } if (!p->signal->leader) { spin_unlock_irq(&p->sighand->siglock); continue; @@ -636,10 +1046,6 @@ static void do_tty_hangup(struct work_struct *work) tty->ctrl_status = 0; spin_unlock_irqrestore(&tty->ctrl_lock, flags); - /* Account for the p->signal references we killed */ - while (refs--) - tty_kref_put(tty); - /* * If one of the devices matches a console pointer, we * cannot just call hangup() because that will cause @@ -708,23 +1114,6 @@ void tty_vhangup(struct tty_struct *tty) EXPORT_SYMBOL(tty_vhangup); -/** - * tty_vhangup_self - process vhangup for own ctty - * - * Perform a vhangup on the current controlling tty - */ - -void tty_vhangup_self(void) -{ - struct tty_struct *tty; - - tty = get_current_tty(); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } -} - /** * tty_hung_up_p - was tty hung up * @filp: file pointer of tty @@ -778,14 +1167,16 @@ void disassociate_ctty(int on_exit) struct pid *tty_pgrp = NULL; + mutex_lock(&tty_mutex); tty = get_current_tty(); if (tty) { tty_pgrp = get_pid(tty->pgrp); lock_kernel(); + mutex_unlock(&tty_mutex); + /* XXX: here we race, there is nothing protecting tty */ if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) tty_vhangup(tty); unlock_kernel(); - tty_kref_put(tty); } else if (on_exit) { struct pid *old_pgrp; spin_lock_irq(¤t->sighand->siglock); @@ -797,6 +1188,7 @@ void disassociate_ctty(int on_exit) kill_pgrp(old_pgrp, SIGCONT, on_exit); put_pid(old_pgrp); } + mutex_unlock(&tty_mutex); return; } if (tty_pgrp) { @@ -811,6 +1203,8 @@ void disassociate_ctty(int on_exit) current->signal->tty_old_pgrp = NULL; spin_unlock_irq(¤t->sighand->siglock); + mutex_lock(&tty_mutex); + /* It is possible that do_tty_hangup has free'd this tty */ tty = get_current_tty(); if (tty) { unsigned long flags; @@ -820,13 +1214,13 @@ void disassociate_ctty(int on_exit) tty->session = NULL; tty->pgrp = NULL; spin_unlock_irqrestore(&tty->ctrl_lock, flags); - tty_kref_put(tty); } else { #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "error attempted to write to tty [0x%p]" " = NULL", tty); #endif } + mutex_unlock(&tty_mutex); /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); @@ -1026,19 +1420,19 @@ static inline ssize_t do_tty_write( /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ if (tty->write_cnt < chunk) { - unsigned char *buf_chunk; + unsigned char *buf; if (chunk < 1024) chunk = 1024; - buf_chunk = kmalloc(chunk, GFP_KERNEL); - if (!buf_chunk) { + buf = kmalloc(chunk, GFP_KERNEL); + if (!buf) { ret = -ENOMEM; goto out; } kfree(tty->write_buf); tty->write_cnt = chunk; - tty->write_buf = buf_chunk; + tty->write_buf = buf; } /* Do the write .. */ @@ -1072,31 +1466,6 @@ static inline ssize_t do_tty_write( return ret; } -/** - * tty_write_message - write a message to a certain tty, not just the console. - * @tty: the destination tty_struct - * @msg: the message to write - * - * This is used for messages that need to be redirected to a specific tty. - * We don't put it into the syslog queue right now maybe in the future if - * really needed. - * - * We must still hold the BKL and test the CLOSING flag for the moment. - */ - -void tty_write_message(struct tty_struct *tty, char *msg) -{ - lock_kernel(); - if (tty) { - mutex_lock(&tty->atomic_write_lock); - if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) - tty->ops->write(tty, msg, strlen(msg)); - tty_write_unlock(tty); - } - unlock_kernel(); - return; -} - /** * tty_write - write method for tty device file @@ -1164,6 +1533,42 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, return tty_write(file, buf, count, ppos); } +void tty_port_init(struct tty_port *port) +{ + memset(port, 0, sizeof(*port)); + init_waitqueue_head(&port->open_wait); + init_waitqueue_head(&port->close_wait); + mutex_init(&port->mutex); + port->close_delay = (50 * HZ) / 100; + port->closing_wait = (3000 * HZ) / 100; +} +EXPORT_SYMBOL(tty_port_init); + +int tty_port_alloc_xmit_buf(struct tty_port *port) +{ + /* We may sleep in get_zeroed_page() */ + mutex_lock(&port->mutex); + if (port->xmit_buf == NULL) + port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); + mutex_unlock(&port->mutex); + if (port->xmit_buf == NULL) + return -ENOMEM; + return 0; +} +EXPORT_SYMBOL(tty_port_alloc_xmit_buf); + +void tty_port_free_xmit_buf(struct tty_port *port) +{ + mutex_lock(&port->mutex); + if (port->xmit_buf != NULL) { + free_page((unsigned long)port->xmit_buf); + port->xmit_buf = NULL; + } + mutex_unlock(&port->mutex); +} +EXPORT_SYMBOL(tty_port_free_xmit_buf); + + static char ptychar[] = "pqrstuvwxyzabcde"; /** @@ -1187,7 +1592,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) } /** - * tty_line_name - generate name for a tty + * pty_line_name - generate name for a tty * @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 7 bytes @@ -1203,148 +1608,10 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) } /** - * tty_driver_lookup_tty() - find an existing tty, if any - * @driver: the driver for the tty - * @idx: the minor number - * - * Return the tty, if found or ERR_PTR() otherwise. - * - * Locking: tty_mutex must be held. If tty is found, the mutex must - * be held until the 'fast-open' is also done. Will change once we - * have refcounting in the driver and per driver locking - */ -struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, - struct inode *inode, int idx) -{ - struct tty_struct *tty; - - if (driver->ops->lookup) - return driver->ops->lookup(driver, inode, idx); - - tty = driver->ttys[idx]; - return tty; -} - -/** - * tty_init_termios - helper for termios setup - * @tty: the tty to set up - * - * Initialise the termios structures for this tty. Thus runs under - * the tty_mutex currently so we can be relaxed about ordering. - */ - -int tty_init_termios(struct tty_struct *tty) -{ - struct ktermios *tp; - int idx = tty->index; - - tp = tty->driver->termios[idx]; - if (tp == NULL) { - tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); - if (tp == NULL) - return -ENOMEM; - memcpy(tp, &tty->driver->init_termios, - sizeof(struct ktermios)); - tty->driver->termios[idx] = tp; - } - tty->termios = tp; - tty->termios_locked = tp + 1; - - /* Compatibility until drivers always set this */ - tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); - tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); - return 0; -} - -/** - * tty_driver_install_tty() - install a tty entry in the driver - * @driver: the driver for the tty - * @tty: the tty - * - * Install a tty object into the driver tables. The tty->index field - * will be set by the time this is called. This method is responsible - * for ensuring any need additional structures are allocated and - * configured. - * - * Locking: tty_mutex for now - */ -static int tty_driver_install_tty(struct tty_driver *driver, - struct tty_struct *tty) -{ - int idx = tty->index; - - if (driver->ops->install) - return driver->ops->install(driver, tty); - - if (tty_init_termios(tty) == 0) { - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; - return 0; - } - return -ENOMEM; -} - -/** - * tty_driver_remove_tty() - remove a tty from the driver tables - * @driver: the driver for the tty - * @idx: the minor number - * - * Remvoe a tty object from the driver tables. The tty->index field - * will be set by the time this is called. - * - * Locking: tty_mutex for now - */ -static void tty_driver_remove_tty(struct tty_driver *driver, - struct tty_struct *tty) -{ - if (driver->ops->remove) - driver->ops->remove(driver, tty); - else - driver->ttys[tty->index] = NULL; -} - -/* - * tty_reopen() - fast re-open of an open tty - * @tty - the tty to open - * - * Return 0 on success, -errno on error. - * - * Locking: tty_mutex must be held from the time the tty was found - * till this open completes. - */ -static int tty_reopen(struct tty_struct *tty) -{ - struct tty_driver *driver = tty->driver; - - if (test_bit(TTY_CLOSING, &tty->flags)) - return -EIO; - - if (driver->type == TTY_DRIVER_TYPE_PTY && - driver->subtype == PTY_TYPE_MASTER) { - /* - * special case for PTY masters: only one open permitted, - * and the slave side open count is incremented as well. - */ - if (tty->count) - return -EIO; - - tty->link->count++; - } - tty->count++; - tty->driver = driver; /* N.B. why do this every time?? */ - - WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); - - return 0; -} - -/** - * tty_init_dev - initialise a tty device + * init_dev - initialise a tty device * @driver: tty driver we are opening a device on * @idx: device index - * @ret_tty: returned tty structure - * @first_ok: ok to open a new device (used by ptmx) + * @tty: returned tty structure * * Prepare a tty device. This may not be a "new" clean device but * could also be an active device. The pty drivers require special @@ -1364,16 +1631,37 @@ static int tty_reopen(struct tty_struct *tty) * relaxed for the (most common) case of reopening a tty. */ -struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, - int first_ok) +static int init_dev(struct tty_driver *driver, int idx, + struct tty_struct **ret_tty) { - struct tty_struct *tty; - int retval; + struct tty_struct *tty, *o_tty; + struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; + struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; + int retval = 0; - /* Check if pty master is being opened multiple times */ - if (driver->subtype == PTY_TYPE_MASTER && - (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) - return ERR_PTR(-EIO); + /* check whether we're reopening an existing tty */ + if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { + tty = devpts_get_tty(idx); + /* + * If we don't have a tty here on a slave open, it's because + * the master already started the close process and there's + * no relation between devpts file and tty anymore. + */ + if (!tty && driver->subtype == PTY_TYPE_SLAVE) { + retval = -EIO; + goto end_init; + } + /* + * It's safe from now on because init_dev() is called with + * tty_mutex held and release_dev() won't change tty->count + * or tty->flags without having to grab tty_mutex + */ + if (tty && driver->subtype == PTY_TYPE_MASTER) + tty = tty->link; + } else { + tty = driver->ttys[idx]; + } + if (tty) goto fast_track; /* * First time open is complex, especially for PTY devices. @@ -1383,69 +1671,189 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, * and locked termios may be retained.) */ - if (!try_module_get(driver->owner)) - return ERR_PTR(-ENODEV); + if (!try_module_get(driver->owner)) { + retval = -ENODEV; + goto end_init; + } + + o_tty = NULL; + tp = o_tp = NULL; + ltp = o_ltp = NULL; tty = alloc_tty_struct(); if (!tty) goto fail_no_mem; - initialize_tty_struct(tty, driver, idx); + initialize_tty_struct(tty); + tty->driver = driver; + tty->ops = driver->ops; + tty->index = idx; + tty_line_name(driver, idx, tty->name); + + if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { + tp_loc = &tty->termios; + ltp_loc = &tty->termios_locked; + } else { + tp_loc = &driver->termios[idx]; + ltp_loc = &driver->termios_locked[idx]; + } + + if (!*tp_loc) { + tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); + if (!tp) + goto free_mem_out; + *tp = driver->init_termios; + } + + if (!*ltp_loc) { + ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); + if (!ltp) + goto free_mem_out; + } + + if (driver->type == TTY_DRIVER_TYPE_PTY) { + o_tty = alloc_tty_struct(); + if (!o_tty) + goto free_mem_out; + initialize_tty_struct(o_tty); + o_tty->driver = driver->other; + o_tty->ops = driver->ops; + o_tty->index = idx; + tty_line_name(driver->other, idx, o_tty->name); + + if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { + o_tp_loc = &o_tty->termios; + o_ltp_loc = &o_tty->termios_locked; + } else { + o_tp_loc = &driver->other->termios[idx]; + o_ltp_loc = &driver->other->termios_locked[idx]; + } + + if (!*o_tp_loc) { + o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); + if (!o_tp) + goto free_mem_out; + *o_tp = driver->other->init_termios; + } + + if (!*o_ltp_loc) { + o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); + if (!o_ltp) + goto free_mem_out; + } - retval = tty_driver_install_tty(driver, tty); - if (retval < 0) { - free_tty_struct(tty); - module_put(driver->owner); - return ERR_PTR(retval); + /* + * Everything allocated ... set up the o_tty structure. + */ + if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM)) + driver->other->ttys[idx] = o_tty; + if (!*o_tp_loc) + *o_tp_loc = o_tp; + if (!*o_ltp_loc) + *o_ltp_loc = o_ltp; + o_tty->termios = *o_tp_loc; + o_tty->termios_locked = *o_ltp_loc; + driver->other->refcount++; + if (driver->subtype == PTY_TYPE_MASTER) + o_tty->count++; + + /* Establish the links in both directions */ + tty->link = o_tty; + o_tty->link = tty; } + /* + * All structures have been allocated, so now we install them. + * Failures after this point use release_tty to clean up, so + * there's no need to null out the local pointers. + */ + if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) + driver->ttys[idx] = tty; + + if (!*tp_loc) + *tp_loc = tp; + if (!*ltp_loc) + *ltp_loc = ltp; + tty->termios = *tp_loc; + tty->termios_locked = *ltp_loc; + /* Compatibility until drivers always set this */ + tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); + tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); + driver->refcount++; + tty->count++; + /* * Structures all installed ... call the ldisc open routines. * If we fail here just call release_tty to clean up. No need * to decrement the use counts, as release_tty doesn't care. */ - retval = tty_ldisc_setup(tty, tty->link); + retval = tty_ldisc_setup(tty, o_tty); + if (retval) goto release_mem_out; - return tty; + goto success; + + /* + * This fast open can be used if the tty is already open. + * No memory is allocated, and the only failures are from + * attempting to open a closing tty or attempting multiple + * opens on a pty master. + */ +fast_track: + if (test_bit(TTY_CLOSING, &tty->flags)) { + retval = -EIO; + goto end_init; + } + if (driver->type == TTY_DRIVER_TYPE_PTY && + driver->subtype == PTY_TYPE_MASTER) { + /* + * special case for PTY masters: only one open permitted, + * and the slave side open count is incremented as well. + */ + if (tty->count) { + retval = -EIO; + goto end_init; + } + tty->link->count++; + } + tty->count++; + tty->driver = driver; /* N.B. why do this every time?? */ + + /* FIXME */ + if (!test_bit(TTY_LDISC, &tty->flags)) + printk(KERN_ERR "init_dev but no ldisc\n"); +success: + *ret_tty = tty; + + /* All paths come through here to release the mutex */ +end_init: + return retval; + + /* Release locally allocated memory ... nothing placed in slots */ +free_mem_out: + kfree(o_tp); + if (o_tty) + free_tty_struct(o_tty); + kfree(ltp); + kfree(tp); + free_tty_struct(tty); fail_no_mem: module_put(driver->owner); - return ERR_PTR(-ENOMEM); + retval = -ENOMEM; + goto end_init; /* call the tty release_tty routine to clean out this slot */ release_mem_out: if (printk_ratelimit()) - printk(KERN_INFO "tty_init_dev: ldisc open failed, " + printk(KERN_INFO "init_dev: ldisc open failed, " "clearing slot %d\n", idx); release_tty(tty, idx); - return ERR_PTR(retval); -} - -void tty_free_termios(struct tty_struct *tty) -{ - struct ktermios *tp; - int idx = tty->index; - /* Kill this flag and push into drivers for locking etc */ - if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { - /* FIXME: Locking on ->termios array */ - tp = tty->termios; - tty->driver->termios[idx] = NULL; - kfree(tp); - } -} -EXPORT_SYMBOL(tty_free_termios); - -void tty_shutdown(struct tty_struct *tty) -{ - tty_driver_remove_tty(tty->driver, tty); - tty_free_termios(tty); + goto end_init; } -EXPORT_SYMBOL(tty_shutdown); /** * release_one_tty - release tty structure memory - * @kref: kref of tty we are obliterating * * Releases memory associated with a tty structure, and clears out the * driver table slots. This function is called when a device is no longer @@ -1455,19 +1863,31 @@ EXPORT_SYMBOL(tty_shutdown); * tty_mutex - sometimes only * takes the file list lock internally when working on the list * of ttys that the driver keeps. + * FIXME: should we require tty_mutex is held here ?? */ -static void release_one_tty(struct kref *kref) +static void release_one_tty(struct tty_struct *tty, int idx) { - struct tty_struct *tty = container_of(kref, struct tty_struct, kref); - struct tty_driver *driver = tty->driver; + int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; + struct ktermios *tp; + + if (!devpts) + tty->driver->ttys[idx] = NULL; + + if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { + tp = tty->termios; + if (!devpts) + tty->driver->termios[idx] = NULL; + kfree(tp); + + tp = tty->termios_locked; + if (!devpts) + tty->driver->termios_locked[idx] = NULL; + kfree(tp); + } + - if (tty->ops->shutdown) - tty->ops->shutdown(tty); - else - tty_shutdown(tty); tty->magic = 0; - tty_driver_kref_put(driver); - module_put(driver->owner); + tty->driver->refcount--; file_list_lock(); list_del_init(&tty->tty_files); @@ -1476,21 +1896,6 @@ static void release_one_tty(struct kref *kref) free_tty_struct(tty); } -/** - * tty_kref_put - release a tty kref - * @tty: tty device - * - * Release a reference to a tty device and if need be let the kref - * layer destruct the object for us - */ - -void tty_kref_put(struct tty_struct *tty) -{ - if (tty) - kref_put(&tty->kref, release_one_tty); -} -EXPORT_SYMBOL(tty_kref_put); - /** * release_tty - release tty structure memory * @@ -1502,16 +1907,15 @@ EXPORT_SYMBOL(tty_kref_put); * takes the file list lock internally when working on the list * of ttys that the driver keeps. * FIXME: should we require tty_mutex is held here ?? - * */ static void release_tty(struct tty_struct *tty, int idx) { - /* This should always be true but check for the moment */ - WARN_ON(tty->index != idx); + struct tty_driver *driver = tty->driver; if (tty->link) - tty_kref_put(tty->link); - tty_kref_put(tty); + release_one_tty(tty->link, idx); + release_one_tty(tty, idx); + module_put(driver->owner); } /* @@ -1522,21 +1926,20 @@ static void release_tty(struct tty_struct *tty, int idx) * WSH 09/09/97: rewritten to avoid some nasty race conditions that could * lead to double frees or releasing memory still in use. */ -void tty_release_dev(struct file *filp) +static void release_dev(struct file *filp) { struct tty_struct *tty, *o_tty; int pty_master, tty_closing, o_tty_closing, do_sleep; int devpts; int idx; char buf[64]; - struct inode *inode; - inode = filp->f_path.dentry->d_inode; tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, inode, "tty_release_dev")) + if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, + "release_dev")) return; - check_tty_count(tty, "tty_release_dev"); + check_tty_count(tty, "release_dev"); tty_fasync(-1, filp, 0); @@ -1548,27 +1951,33 @@ void tty_release_dev(struct file *filp) #ifdef TTY_PARANOIA_CHECK if (idx < 0 || idx >= tty->driver->num) { - printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " + printk(KERN_DEBUG "release_dev: bad idx when trying to " "free (%s)\n", tty->name); return; } - if (!devpts) { + if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { if (tty != tty->driver->ttys[idx]) { - printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " + printk(KERN_DEBUG "release_dev: driver.table[%d] not tty " "for (%s)\n", idx, tty->name); return; } if (tty->termios != tty->driver->termios[idx]) { - printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " + printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios " "for (%s)\n", idx, tty->name); return; } + if (tty->termios_locked != tty->driver->termios_locked[idx]) { + printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not " + "termios_locked for (%s)\n", + idx, tty->name); + return; + } } #endif #ifdef TTY_DEBUG_HANGUP - printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", + printk(KERN_DEBUG "release_dev of %s (tty count=%d)...", tty_name(tty, buf), tty->count); #endif @@ -1576,19 +1985,26 @@ void tty_release_dev(struct file *filp) if (tty->driver->other && !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { if (o_tty != tty->driver->other->ttys[idx]) { - printk(KERN_DEBUG "tty_release_dev: other->table[%d] " + printk(KERN_DEBUG "release_dev: other->table[%d] " "not o_tty for (%s)\n", idx, tty->name); return; } if (o_tty->termios != tty->driver->other->termios[idx]) { - printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " + printk(KERN_DEBUG "release_dev: other->termios[%d] " "not o_termios for (%s)\n", idx, tty->name); return; } + if (o_tty->termios_locked != + tty->driver->other->termios_locked[idx]) { + printk(KERN_DEBUG "release_dev: other->termios_locked[" + "%d] not o_termios_locked for (%s)\n", + idx, tty->name); + return; + } if (o_tty->link != tty) { - printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); + printk(KERN_DEBUG "release_dev: bad pty pointers\n"); return; } } @@ -1646,7 +2062,7 @@ void tty_release_dev(struct file *filp) if (!do_sleep) break; - printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " + printk(KERN_WARNING "release_dev: %s: read/write wait queue " "active!\n", tty_name(tty, buf)); mutex_unlock(&tty_mutex); schedule(); @@ -1659,14 +2075,14 @@ void tty_release_dev(struct file *filp) */ if (pty_master) { if (--o_tty->count < 0) { - printk(KERN_WARNING "tty_release_dev: bad pty slave count " + printk(KERN_WARNING "release_dev: bad pty slave count " "(%d) for %s\n", o_tty->count, tty_name(o_tty, buf)); o_tty->count = 0; } } if (--tty->count < 0) { - printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n", + printk(KERN_WARNING "release_dev: bad tty->count (%d) for %s\n", tty->count, tty_name(tty, buf)); tty->count = 0; } @@ -1729,11 +2145,11 @@ void tty_release_dev(struct file *filp) /* Make this pty number available for reallocation */ if (devpts) - devpts_kill_index(inode, idx); + devpts_kill_index(idx); } /** - * __tty_open - open a tty device + * tty_open - open a tty device * @inode: inode of device file * @filp: file pointer to tty * @@ -1748,14 +2164,14 @@ void tty_release_dev(struct file *filp) * The termios state of a pty is reset on first open so that * settings don't persist across reuse. * - * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work. + * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. * tty->count should protect the rest. * ->siglock protects ->signal/->sighand */ static int __tty_open(struct inode *inode, struct file *filp) { - struct tty_struct *tty = NULL; + struct tty_struct *tty; int noctty, retval; struct tty_driver *driver; int index; @@ -1777,25 +2193,23 @@ static int __tty_open(struct inode *inode, struct file *filp) mutex_unlock(&tty_mutex); return -ENXIO; } - driver = tty_driver_kref_get(tty->driver); + driver = tty->driver; index = tty->index; filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ /* noctty = 1; */ - /* FIXME: Should we take a driver reference ? */ - tty_kref_put(tty); goto got_driver; } #ifdef CONFIG_VT if (device == MKDEV(TTY_MAJOR, 0)) { extern struct tty_driver *console_driver; - driver = tty_driver_kref_get(console_driver); + driver = console_driver; index = fg_console; noctty = 1; goto got_driver; } #endif if (device == MKDEV(TTYAUX_MAJOR, 1)) { - driver = tty_driver_kref_get(console_device(&index)); + driver = console_device(&index); if (driver) { /* Don't let /dev/console block */ filp->f_flags |= O_NONBLOCK; @@ -1812,25 +2226,10 @@ static int __tty_open(struct inode *inode, struct file *filp) return -ENODEV; } got_driver: - if (!tty) { - /* check whether we're reopening an existing tty */ - tty = tty_driver_lookup_tty(driver, inode, index); - - if (IS_ERR(tty)) - return PTR_ERR(tty); - } - - if (tty) { - retval = tty_reopen(tty); - if (retval) - tty = ERR_PTR(retval); - } else - tty = tty_init_dev(driver, index, 0); - + retval = init_dev(driver, index, &tty); mutex_unlock(&tty_mutex); - tty_driver_kref_put(driver); - if (IS_ERR(tty)) - return PTR_ERR(tty); + if (retval) + return retval; filp->private_data = tty; file_move(filp, &tty->tty_files); @@ -1858,7 +2257,7 @@ static int __tty_open(struct inode *inode, struct file *filp) printk(KERN_DEBUG "error %d in opening %s...", retval, tty->name); #endif - tty_release_dev(filp); + release_dev(filp); if (retval != -ERESTARTSYS) return retval; if (signal_pending(current)) @@ -1897,6 +2296,69 @@ static int tty_open(struct inode *inode, struct file *filp) +#ifdef CONFIG_UNIX98_PTYS +/** + * ptmx_open - open a unix 98 pty master + * @inode: inode of device file + * @filp: file pointer to tty + * + * Allocate a unix98 pty master device from the ptmx driver. + * + * Locking: tty_mutex protects theinit_dev work. tty->count should + * protect the rest. + * allocated_ptys_lock handles the list of free pty numbers + */ + +static int __ptmx_open(struct inode *inode, struct file *filp) +{ + struct tty_struct *tty; + int retval; + int index; + + nonseekable_open(inode, filp); + + /* find a device that is not in use. */ + index = devpts_new_index(); + if (index < 0) + return index; + + mutex_lock(&tty_mutex); + retval = init_dev(ptm_driver, index, &tty); + mutex_unlock(&tty_mutex); + + if (retval) + goto out; + + set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ + filp->private_data = tty; + file_move(filp, &tty->tty_files); + + retval = devpts_pty_new(tty->link); + if (retval) + goto out1; + + check_tty_count(tty, "ptmx_open"); + retval = ptm_driver->ops->open(tty, filp); + if (!retval) + return 0; +out1: + release_dev(filp); + return retval; +out: + devpts_kill_index(index); + return retval; +} + +static int ptmx_open(struct inode *inode, struct file *filp) +{ + int ret; + + lock_kernel(); + ret = __ptmx_open(inode, filp); + unlock_kernel(); + return ret; +} +#endif /** * tty_release - vfs callback for close @@ -1907,13 +2369,13 @@ static int tty_open(struct inode *inode, struct file *filp) * this tty. There may however be several such references. * * Locking: - * Takes bkl. See tty_release_dev + * Takes bkl. See release_dev */ static int tty_release(struct inode *inode, struct file *filp) { lock_kernel(); - tty_release_dev(filp); + release_dev(filp); unlock_kernel(); return 0; } @@ -2062,7 +2524,7 @@ int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, /* For a PTY we need to lock the tty side */ mutex_lock(&real_tty->termios_mutex); - if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) + if (!memcmp(ws, &tty->winsize, sizeof(*ws))) goto done; /* Get the PID values and reference them so we can avoid holding the tty ctrl lock while sending signals */ @@ -2534,7 +2996,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCSTI: return tiocsti(tty, p); case TIOCGWINSZ: - return tiocgwinsz(real_tty, p); + return tiocgwinsz(tty, p); case TIOCSWINSZ: return tiocswinsz(tty, real_tty, p); case TIOCCONS: @@ -2564,6 +3026,10 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return put_user(tty->ldisc.ops->num, (int __user *)p); case TIOCSETD: return tiocsetd(tty, p); +#ifdef CONFIG_VT + case TIOCLINUX: + return tioclinux(tty, arg); +#endif /* * Break handling */ @@ -2753,6 +3219,113 @@ void do_SAK(struct tty_struct *tty) EXPORT_SYMBOL(do_SAK); +/** + * flush_to_ldisc + * @work: tty structure passed from work queue. + * + * This routine is called out of the software interrupt to flush data + * from the buffer chain to the line discipline. + * + * Locking: holds tty->buf.lock to guard buffer list. Drops the lock + * while invoking the line discipline receive_buf method. The + * receive_buf method is single threaded for each tty instance. + */ + +static void flush_to_ldisc(struct work_struct *work) +{ + struct tty_struct *tty = + container_of(work, struct tty_struct, buf.work.work); + unsigned long flags; + struct tty_ldisc *disc; + struct tty_buffer *tbuf, *head; + char *char_buf; + unsigned char *flag_buf; + + disc = tty_ldisc_ref(tty); + if (disc == NULL) /* !TTY_LDISC */ + return; + + spin_lock_irqsave(&tty->buf.lock, flags); + /* So we know a flush is running */ + set_bit(TTY_FLUSHING, &tty->flags); + head = tty->buf.head; + if (head != NULL) { + tty->buf.head = NULL; + for (;;) { + int count = head->commit - head->read; + if (!count) { + if (head->next == NULL) + break; + tbuf = head; + head = head->next; + tty_buffer_free(tty, tbuf); + continue; + } + /* Ldisc or user is trying to flush the buffers + we are feeding to the ldisc, stop feeding the + line discipline as we want to empty the queue */ + if (test_bit(TTY_FLUSHPENDING, &tty->flags)) + break; + if (!tty->receive_room) { + schedule_delayed_work(&tty->buf.work, 1); + break; + } + if (count > tty->receive_room) + count = tty->receive_room; + char_buf = head->char_buf_ptr + head->read; + flag_buf = head->flag_buf_ptr + head->read; + head->read += count; + spin_unlock_irqrestore(&tty->buf.lock, flags); + disc->ops->receive_buf(tty, char_buf, + flag_buf, count); + spin_lock_irqsave(&tty->buf.lock, flags); + } + /* Restore the queue head */ + tty->buf.head = head; + } + /* We may have a deferred request to flush the input buffer, + if so pull the chain under the lock and empty the queue */ + if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { + __tty_buffer_flush(tty); + clear_bit(TTY_FLUSHPENDING, &tty->flags); + wake_up(&tty->read_wait); + } + clear_bit(TTY_FLUSHING, &tty->flags); + spin_unlock_irqrestore(&tty->buf.lock, flags); + + tty_ldisc_deref(disc); +} + +/** + * tty_flip_buffer_push - terminal + * @tty: tty to push + * + * Queue a push of the terminal flip buffers to the line discipline. This + * function must not be called from IRQ context if tty->low_latency is set. + * + * In the event of the queue being busy for flipping the work will be + * held off and retried later. + * + * Locking: tty buffer lock. Driver locks in low latency mode. + */ + +void tty_flip_buffer_push(struct tty_struct *tty) +{ + unsigned long flags; + spin_lock_irqsave(&tty->buf.lock, flags); + if (tty->buf.tail != NULL) + tty->buf.tail->commit = tty->buf.tail->used; + spin_unlock_irqrestore(&tty->buf.lock, flags); + + if (tty->low_latency) + flush_to_ldisc(&tty->buf.work.work); + else + schedule_delayed_work(&tty->buf.work, 1); +} + +EXPORT_SYMBOL(tty_flip_buffer_push); + + /** * initialize_tty_struct * @tty: tty to initialize @@ -2763,11 +3336,9 @@ EXPORT_SYMBOL(do_SAK); * Locking: none - tty in question must not be exposed at this point */ -void initialize_tty_struct(struct tty_struct *tty, - struct tty_driver *driver, int idx) +static void initialize_tty_struct(struct tty_struct *tty) { memset(tty, 0, sizeof(struct tty_struct)); - kref_init(&tty->kref); tty->magic = TTY_MAGIC; tty_ldisc_init(tty); tty->session = NULL; @@ -2775,6 +3346,7 @@ void initialize_tty_struct(struct tty_struct *tty, tty->overrun_time = jiffies; tty->buf.head = tty->buf.tail = NULL; tty_buffer_init(tty); + INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); mutex_init(&tty->termios_mutex); init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); @@ -2785,11 +3357,6 @@ void initialize_tty_struct(struct tty_struct *tty, spin_lock_init(&tty->ctrl_lock); INIT_LIST_HEAD(&tty->tty_files); INIT_WORK(&tty->SAK_work, do_SAK_work); - - tty->driver = driver; - tty->ops = driver->ops; - tty->index = idx; - tty_line_name(driver, idx, tty->name); } /** @@ -2810,9 +3377,10 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch) return tty->ops->put_char(tty, ch); return tty->ops->write(tty, &ch, 1); } + EXPORT_SYMBOL_GPL(tty_put_char); -struct class *tty_class; +static struct class *tty_class; /** * tty_register_device - register a tty device @@ -2850,9 +3418,8 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, else tty_line_name(driver, index, name); - return device_create(tty_class, device, dev, NULL, name); + return device_create_drvdata(tty_class, device, dev, NULL, name); } -EXPORT_SYMBOL(tty_register_device); /** * tty_unregister_device - unregister a tty device @@ -2870,6 +3437,8 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); } + +EXPORT_SYMBOL(tty_register_device); EXPORT_SYMBOL(tty_unregister_device); struct tty_driver *alloc_tty_driver(int lines) @@ -2878,65 +3447,27 @@ struct tty_driver *alloc_tty_driver(int lines) driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); if (driver) { - kref_init(&driver->kref); driver->magic = TTY_DRIVER_MAGIC; driver->num = lines; /* later we'll move allocation of tables here */ } return driver; } -EXPORT_SYMBOL(alloc_tty_driver); -static void destruct_tty_driver(struct kref *kref) +void put_tty_driver(struct tty_driver *driver) { - struct tty_driver *driver = container_of(kref, struct tty_driver, kref); - int i; - struct ktermios *tp; - void *p; - - if (driver->flags & TTY_DRIVER_INSTALLED) { - /* - * Free the termios and termios_locked structures because - * we don't want to get memory leaks when modular tty - * drivers are removed from the kernel. - */ - for (i = 0; i < driver->num; i++) { - tp = driver->termios[i]; - if (tp) { - driver->termios[i] = NULL; - kfree(tp); - } - if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) - tty_unregister_device(driver, i); - } - p = driver->ttys; - proc_tty_unregister_driver(driver); - driver->ttys = NULL; - driver->termios = NULL; - kfree(p); - cdev_del(&driver->cdev); - } kfree(driver); } -void tty_driver_kref_put(struct tty_driver *driver) -{ - kref_put(&driver->kref, destruct_tty_driver); -} -EXPORT_SYMBOL(tty_driver_kref_put); - void tty_set_operations(struct tty_driver *driver, const struct tty_operations *op) { driver->ops = op; }; -EXPORT_SYMBOL(tty_set_operations); -void put_tty_driver(struct tty_driver *d) -{ - tty_driver_kref_put(d); -} +EXPORT_SYMBOL(alloc_tty_driver); EXPORT_SYMBOL(put_tty_driver); +EXPORT_SYMBOL(tty_set_operations); /* * Called by a tty driver to register itself. @@ -2948,8 +3479,11 @@ int tty_register_driver(struct tty_driver *driver) dev_t dev; void **p = NULL; + if (driver->flags & TTY_DRIVER_INSTALLED) + return 0; + if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { - p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); + p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); if (!p) return -ENOMEM; } @@ -2973,9 +3507,12 @@ int tty_register_driver(struct tty_driver *driver) if (p) { driver->ttys = (struct tty_struct **)p; driver->termios = (struct ktermios **)(p + driver->num); + driver->termios_locked = (struct ktermios **) + (p + driver->num * 2); } else { driver->ttys = NULL; driver->termios = NULL; + driver->termios_locked = NULL; } cdev_init(&driver->cdev, &tty_fops); @@ -2984,7 +3521,7 @@ int tty_register_driver(struct tty_driver *driver) if (error) { unregister_chrdev_region(dev, driver->num); driver->ttys = NULL; - driver->termios = NULL; + driver->termios = driver->termios_locked = NULL; kfree(p); return error; } @@ -2998,7 +3535,6 @@ int tty_register_driver(struct tty_driver *driver) tty_register_device(driver, i, NULL); } proc_tty_register_driver(driver); - driver->flags |= TTY_DRIVER_INSTALLED; return 0; } @@ -3009,19 +3545,46 @@ EXPORT_SYMBOL(tty_register_driver); */ int tty_unregister_driver(struct tty_driver *driver) { -#if 0 - /* FIXME */ + int i; + struct ktermios *tp; + void *p; + if (driver->refcount) return -EBUSY; -#endif + unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), driver->num); mutex_lock(&tty_mutex); list_del(&driver->tty_drivers); mutex_unlock(&tty_mutex); + + /* + * Free the termios and termios_locked structures because + * we don't want to get memory leaks when modular tty + * drivers are removed from the kernel. + */ + for (i = 0; i < driver->num; i++) { + tp = driver->termios[i]; + if (tp) { + driver->termios[i] = NULL; + kfree(tp); + } + tp = driver->termios_locked[i]; + if (tp) { + driver->termios_locked[i] = NULL; + kfree(tp); + } + if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) + tty_unregister_device(driver, i); + } + p = driver->ttys; + proc_tty_unregister_driver(driver); + driver->ttys = NULL; + driver->termios = driver->termios_locked = NULL; + kfree(p); + cdev_del(&driver->cdev); return 0; } - EXPORT_SYMBOL(tty_unregister_driver); dev_t tty_devnum(struct tty_struct *tty) @@ -3032,13 +3595,9 @@ EXPORT_SYMBOL(tty_devnum); void proc_clear_tty(struct task_struct *p) { - unsigned long flags; - struct tty_struct *tty; - spin_lock_irqsave(&p->sighand->siglock, flags); - tty = p->signal->tty; + spin_lock_irq(&p->sighand->siglock); p->signal->tty = NULL; - spin_unlock_irqrestore(&p->sighand->siglock, flags); - tty_kref_put(tty); + spin_unlock_irq(&p->sighand->siglock); } /* Called under the sighand lock */ @@ -3054,13 +3613,9 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) tty->pgrp = get_pid(task_pgrp(tsk)); spin_unlock_irqrestore(&tty->ctrl_lock, flags); tty->session = get_pid(task_session(tsk)); - if (tsk->signal->tty) { - printk(KERN_DEBUG "tty not NULL!!\n"); - tty_kref_put(tsk->signal->tty); - } } put_pid(tsk->signal->tty_old_pgrp); - tsk->signal->tty = tty_kref_get(tty); + tsk->signal->tty = tty; tsk->signal->tty_old_pgrp = NULL; } @@ -3074,20 +3629,18 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) struct tty_struct *get_current_tty(void) { struct tty_struct *tty; - unsigned long flags; - - spin_lock_irqsave(¤t->sighand->siglock, flags); - tty = tty_kref_get(current->signal->tty); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); + tty = current->signal->tty; + /* + * session->tty can be changed/cleared from under us, make sure we + * issue the load. The obtained pointer, when not NULL, is valid as + * long as we hold tty_mutex. + */ + barrier(); return tty; } EXPORT_SYMBOL_GPL(get_current_tty); -void tty_default_fops(struct file_operations *fops) -{ - *fops = tty_fops; -} - /* * Initialize the console device. This is called *early*, so * we can't necessarily depend on lots of kernel help here. @@ -3125,6 +3678,12 @@ postcore_initcall(tty_class_init); /* 3/2004 jmc: why do these devices exist? */ static struct cdev tty_cdev, console_cdev; +#ifdef CONFIG_UNIX98_PTYS +static struct cdev ptmx_cdev; +#endif +#ifdef CONFIG_VT +static struct cdev vc0_cdev; +#endif /* * Ok, now we can initialize the rest of the tty devices and can count @@ -3136,18 +3695,32 @@ static int __init tty_init(void) if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn't register /dev/tty driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, + device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, + device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); +#ifdef CONFIG_UNIX98_PTYS + cdev_init(&ptmx_cdev, &ptmx_fops); + if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || + register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) + panic("Couldn't register /dev/ptmx driver\n"); + device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); +#endif + #ifdef CONFIG_VT - vty_init(&console_fops); + cdev_init(&vc0_cdev, &console_fops); + if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || + register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) + panic("Couldn't register /dev/tty0 driver\n"); + device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); + + vty_init(); #endif return 0; } diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index a408c8e487ec..bf34e4597421 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -40,15 +40,6 @@ #define TERMIOS_OLD 8 -/** - * tty_chars_in_buffer - characters pending - * @tty: terminal - * - * Return the number of bytes of data in the device private - * output queue. If no private method is supplied there is assumed - * to be no queue on the device. - */ - int tty_chars_in_buffer(struct tty_struct *tty) { if (tty->ops->chars_in_buffer) @@ -56,48 +47,25 @@ int tty_chars_in_buffer(struct tty_struct *tty) else return 0; } + EXPORT_SYMBOL(tty_chars_in_buffer); -/** - * tty_write_room - write queue space - * @tty: terminal - * - * Return the number of bytes that can be queued to this device - * at the present time. The result should be treated as a guarantee - * and the driver cannot offer a value it later shrinks by more than - * the number of bytes written. If no method is provided 2K is always - * returned and data may be lost as there will be no flow control. - */ - int tty_write_room(struct tty_struct *tty) { if (tty->ops->write_room) return tty->ops->write_room(tty); return 2048; } + EXPORT_SYMBOL(tty_write_room); -/** - * tty_driver_flush_buffer - discard internal buffer - * @tty: terminal - * - * Discard the internal output buffer for this device. If no method - * is provided then either the buffer cannot be hardware flushed or - * there is no buffer driver side. - */ void tty_driver_flush_buffer(struct tty_struct *tty) { if (tty->ops->flush_buffer) tty->ops->flush_buffer(tty); } -EXPORT_SYMBOL(tty_driver_flush_buffer); -/** - * tty_throttle - flow control - * @tty: terminal - * - * Indicate that a tty should stop transmitting data down the stack. - */ +EXPORT_SYMBOL(tty_driver_flush_buffer); void tty_throttle(struct tty_struct *tty) { @@ -108,13 +76,6 @@ void tty_throttle(struct tty_struct *tty) } EXPORT_SYMBOL(tty_throttle); -/** - * tty_unthrottle - flow control - * @tty: terminal - * - * Indicate that a tty may continue transmitting data down the stack. - */ - void tty_unthrottle(struct tty_struct *tty) { if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && @@ -151,11 +112,6 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) } EXPORT_SYMBOL(tty_wait_until_sent); - -/* - * Termios Helper Methods - */ - static void unset_locked_termios(struct ktermios *termios, struct ktermios *old, struct ktermios *locked) @@ -390,16 +346,6 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, } EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); -/** - * tty_encode_baud_rate - set baud rate of the tty - * @ibaud: input baud rate - * @obad: output baud rate - * - * Update the current termios data for the tty with the new speed - * settings. The caller must hold the termios_mutex for the tty in - * question. - */ - void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) { tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); @@ -484,11 +430,12 @@ EXPORT_SYMBOL(tty_termios_hw_change); * is a bit of layering violation here with n_tty in terms of the * internal knowledge of this function. * - * Locking: termios_mutex + * Locking: termios_sem */ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) { + int canon_change; struct ktermios old_termios; struct tty_ldisc *ld; unsigned long flags; @@ -504,6 +451,18 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) old_termios = *tty->termios; *tty->termios = *new_termios; unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); + canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; + if (canon_change) { + memset(&tty->read_flags, 0, sizeof tty->read_flags); + tty->canon_head = tty->read_tail; + tty->canon_data = 0; + tty->erasing = 0; + } + + /* This bit should be in the ldisc code */ + if (canon_change && !L_ICANON(tty) && tty->read_cnt) + /* Get characters left over from canonical mode. */ + wake_up_interruptible(&tty->read_wait); /* See if packet mode change of state. */ if (tty->link && tty->link->packet) { @@ -549,7 +508,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) * functions before using change_termios to do the actual changes. * * Locking: - * Called functions take ldisc and termios_mutex locks + * Called functions take ldisc and termios_sem locks */ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) @@ -620,51 +579,25 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio) return 0; } - -#ifdef TCGETX - -/** - * set_termiox - set termiox fields if possible - * @tty: terminal - * @arg: termiox structure from user - * @opt: option flags for ioctl type - * - * Implement the device calling points for the SYS5 termiox ioctl - * interface in Linux - */ - -static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) +static unsigned long inq_canon(struct tty_struct *tty) { - struct termiox tnew; - struct tty_ldisc *ld; + int nr, head, tail; - if (tty->termiox == NULL) - return -EINVAL; - if (copy_from_user(&tnew, arg, sizeof(struct termiox))) - return -EFAULT; - - ld = tty_ldisc_ref(tty); - if (ld != NULL) { - if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) - ld->ops->flush_buffer(tty); - tty_ldisc_deref(ld); - } - if (opt & TERMIOS_WAIT) { - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; + if (!tty->canon_data || !tty->read_buf) + return 0; + head = tty->canon_head; + tail = tty->read_tail; + nr = (head - tail) & (N_TTY_BUF_SIZE-1); + /* Skip EOF-chars.. */ + while (head != tail) { + if (test_bit(tail, tty->read_flags) && + tty->read_buf[tail] == __DISABLED_CHAR) + nr--; + tail = (tail+1) & (N_TTY_BUF_SIZE-1); } - - mutex_lock(&tty->termios_mutex); - if (tty->ops->set_termiox) - tty->ops->set_termiox(tty, &tnew); - mutex_unlock(&tty->termios_mutex); - return 0; + return nr; } -#endif - - #ifdef TIOCGETP /* * These are deprecated, but there is limited support.. @@ -738,7 +671,7 @@ static void set_sgflags(struct ktermios *termios, int flags) * Updates a terminal from the legacy BSD style terminal information * structure. * - * Locking: termios_mutex + * Locking: termios_sem */ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) @@ -916,7 +849,6 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, { struct tty_struct *real_tty; void __user *p = (void __user *)arg; - int ret = 0; if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) @@ -952,24 +884,18 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, return set_termios(real_tty, p, TERMIOS_OLD); #ifndef TCGETS2 case TCGETS: - mutex_lock(&real_tty->termios_mutex); if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; #else case TCGETS: - mutex_lock(&real_tty->termios_mutex); if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; case TCGETS2: - mutex_lock(&real_tty->termios_mutex); if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; case TCSETSF2: return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); case TCSETSW2: @@ -987,59 +913,34 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, return set_termios(real_tty, p, TERMIOS_TERMIO); #ifndef TCGETS2 case TIOCGLCKTRMIOS: - mutex_lock(&real_tty->termios_mutex); if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; case TIOCSLCKTRMIOS: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - mutex_lock(&real_tty->termios_mutex); if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; #else case TIOCGLCKTRMIOS: - mutex_lock(&real_tty->termios_mutex); if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; case TIOCSLCKTRMIOS: if (!capable(CAP_SYS_ADMIN)) - ret = -EPERM; - mutex_lock(&real_tty->termios_mutex); + return -EPERM; if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg)) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; + return -EFAULT; + return 0; #endif -#ifdef TCGETX - case TCGETX: - if (real_tty->termiox == NULL) - return -EINVAL; - mutex_lock(&real_tty->termios_mutex); - if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox))) - ret = -EFAULT; - mutex_unlock(&real_tty->termios_mutex); - return ret; - case TCSETX: - return set_termiox(real_tty, p, 0); - case TCSETXW: - return set_termiox(real_tty, p, TERMIOS_WAIT); - case TCSETXF: - return set_termiox(real_tty, p, TERMIOS_FLUSH); -#endif case TIOCGSOFTCAR: - mutex_lock(&real_tty->termios_mutex); - ret = put_user(C_CLOCAL(real_tty) ? 1 : 0, + /* FIXME: for correctness we may need to take the termios + lock here - review */ + return put_user(C_CLOCAL(real_tty) ? 1 : 0, (int __user *)arg); - mutex_unlock(&real_tty->termios_mutex); - return ret; case TIOCSSOFTCAR: if (get_user(arg, (unsigned int __user *) arg)) return -EFAULT; @@ -1079,7 +980,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) } EXPORT_SYMBOL_GPL(tty_perform_flush); -int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, +int n_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { unsigned long flags; @@ -1117,6 +1018,13 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, return 0; case TCFLSH: return tty_perform_flush(tty, arg); + case TIOCOUTQ: + return put_user(tty_chars_in_buffer(tty), (int __user *) arg); + case TIOCINQ: + retval = tty->read_cnt; + if (L_ICANON(tty)) + retval = inq_canon(tty); + return put_user(retval, (unsigned int __user *) arg); case TIOCPKT: { int pktmode; @@ -1142,4 +1050,4 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, return tty_mode_ioctl(tty, file, cmd, arg); } } -EXPORT_SYMBOL(n_tty_ioctl_helper); +EXPORT_SYMBOL(n_tty_ioctl); diff --git a/trunk/drivers/char/tty_port.c b/trunk/drivers/char/tty_port.c deleted file mode 100644 index 553b0e9d8d17..000000000000 --- a/trunk/drivers/char/tty_port.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Tty port functions - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void tty_port_init(struct tty_port *port) -{ - memset(port, 0, sizeof(*port)); - init_waitqueue_head(&port->open_wait); - init_waitqueue_head(&port->close_wait); - mutex_init(&port->mutex); - spin_lock_init(&port->lock); - port->close_delay = (50 * HZ) / 100; - port->closing_wait = (3000 * HZ) / 100; -} -EXPORT_SYMBOL(tty_port_init); - -int tty_port_alloc_xmit_buf(struct tty_port *port) -{ - /* We may sleep in get_zeroed_page() */ - mutex_lock(&port->mutex); - if (port->xmit_buf == NULL) - port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); - mutex_unlock(&port->mutex); - if (port->xmit_buf == NULL) - return -ENOMEM; - return 0; -} -EXPORT_SYMBOL(tty_port_alloc_xmit_buf); - -void tty_port_free_xmit_buf(struct tty_port *port) -{ - mutex_lock(&port->mutex); - if (port->xmit_buf != NULL) { - free_page((unsigned long)port->xmit_buf); - port->xmit_buf = NULL; - } - mutex_unlock(&port->mutex); -} -EXPORT_SYMBOL(tty_port_free_xmit_buf); - - -/** - * tty_port_tty_get - get a tty reference - * @port: tty port - * - * Return a refcount protected tty instance or NULL if the port is not - * associated with a tty (eg due to close or hangup) - */ - -struct tty_struct *tty_port_tty_get(struct tty_port *port) -{ - unsigned long flags; - struct tty_struct *tty; - - spin_lock_irqsave(&port->lock, flags); - tty = tty_kref_get(port->tty); - spin_unlock_irqrestore(&port->lock, flags); - return tty; -} -EXPORT_SYMBOL(tty_port_tty_get); - -/** - * tty_port_tty_set - set the tty of a port - * @port: tty port - * @tty: the tty - * - * Associate the port and tty pair. Manages any internal refcounts. - * Pass NULL to deassociate a port - */ - -void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) -{ - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - if (port->tty) - tty_kref_put(port->tty); - port->tty = tty; - spin_unlock_irqrestore(&port->lock, flags); -} -EXPORT_SYMBOL(tty_port_tty_set); diff --git a/trunk/drivers/char/vc_screen.c b/trunk/drivers/char/vc_screen.c index 4f3b3f95fc42..c2ae52dd53d1 100644 --- a/trunk/drivers/char/vc_screen.c +++ b/trunk/drivers/char/vc_screen.c @@ -481,10 +481,10 @@ static struct class *vc_class; void vcs_make_sysfs(struct tty_struct *tty) { - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL, - "vcs%u", tty->index + 1); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL, - "vcsa%u", tty->index + 1); + device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), + NULL, "vcs%u", tty->index + 1); + device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), + NULL, "vcsa%u", tty->index + 1); } void vcs_remove_sysfs(struct tty_struct *tty) @@ -499,7 +499,7 @@ int __init vcs_init(void) panic("unable to get major %d for vcs device", VCS_MAJOR); vc_class = class_create(THIS_MODULE, "vc"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); return 0; } diff --git a/trunk/drivers/char/viotape.c b/trunk/drivers/char/viotape.c index ffc9254f7e02..7a70a40ad639 100644 --- a/trunk/drivers/char/viotape.c +++ b/trunk/drivers/char/viotape.c @@ -886,10 +886,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) state[i].cur_part = 0; for (j = 0; j < MAX_PARTITIONS; ++j) state[i].part_stat_rwi[j] = VIOT_IDLE; - device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL, - "iseries!vt%d", i); - device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL, - "iseries!nvt%d", i); + device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), + NULL, "iseries!vt%d", i); + device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), + NULL, "iseries!nvt%d", i); printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " "resource %10.10s type %4.4s, model %3.3s\n", i, viotape_unitinfo[i].rsrcname, diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index d8f83e26e4a4..60359c360912 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -59,7 +59,7 @@ * by Martin Mares , July 1998 * * Removed old-style timers, introduced console_timer, made timer - * deletion SMP-safe. 17Jun00, Andrew Morton + * deletion SMP-safe. 17Jun00, Andrew Morton * * Removed console_lock, enabled interrupts across all console operations * 13 March 2001, Andrew Morton @@ -100,10 +100,10 @@ #include #include #include -#include -#include + +#include #include -#include +#include #define MAX_NR_CON_DRIVER 16 @@ -301,7 +301,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); - scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, + scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_scrl_erase_char, vc->vc_size_row * nr); } @@ -319,7 +319,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr) s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); step = vc->vc_cols * nr; scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row); - scr_memsetw(s, vc->vc_video_erase_char, 2 * step); + scr_memsetw(s, vc->vc_scrl_erase_char, 2 * step); } static void do_update_region(struct vc_data *vc, unsigned long start, int count) @@ -434,6 +434,7 @@ static void update_attr(struct vc_data *vc) vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; + vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, vc->vc_decscnm, false) << 8) | ' '; } /* Note: inverting the screen twice should revert to the original state */ @@ -2135,9 +2136,27 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co release_console_sem(); return 0; } + release_console_sem(); + orig_buf = buf; orig_count = count; + /* At this point 'buf' is guaranteed to be a kernel buffer + * and therefore no access to userspace (and therefore sleeping) + * will be needed. The con_buf_mtx serializes all tty based + * console rendering and vcs write/read operations. We hold + * the console spinlock during the entire write. + */ + + acquire_console_sem(); + + vc = tty->driver_data; + if (vc == NULL) { + printk(KERN_ERR "vt: argh, driver_data _became_ NULL !\n"); + release_console_sem(); + goto out; + } + himask = vc->vc_hi_font_mask; charmask = himask ? 0x1ff : 0xff; @@ -2351,6 +2370,8 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co FLUSH console_conditional_schedule(); release_console_sem(); + +out: notify_update(vc); return n; #undef FLUSH @@ -2562,6 +2583,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) int lines; int ret; + if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) + return -EINVAL; if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(type, p)) @@ -2755,12 +2778,6 @@ static int con_open(struct tty_struct *tty, struct file *filp) ret = vc_allocate(currcons); if (ret == 0) { struct vc_data *vc = vc_cons[currcons].d; - - /* Still being freed */ - if (vc->vc_tty) { - release_console_sem(); - return -ERESTARTSYS; - } tty->driver_data = vc; vc->vc_tty = tty; @@ -2781,20 +2798,34 @@ static int con_open(struct tty_struct *tty, struct file *filp) return ret; } +/* + * We take tty_mutex in here to prevent another thread from coming in via init_dev + * and taking a ref against the tty while we're in the process of forgetting + * about it and cleaning things up. + * + * This is because vcs_remove_sysfs() can sleep and will drop the BKL. + */ static void con_close(struct tty_struct *tty, struct file *filp) { - /* Nothing to do - we defer to shutdown */ -} - -static void con_shutdown(struct tty_struct *tty) -{ - struct vc_data *vc = tty->driver_data; - BUG_ON(vc == NULL); + mutex_lock(&tty_mutex); acquire_console_sem(); - vc->vc_tty = NULL; - vcs_remove_sysfs(tty); + if (tty && tty->count == 1) { + struct vc_data *vc = tty->driver_data; + + if (vc) + vc->vc_tty = NULL; + tty->driver_data = NULL; + vcs_remove_sysfs(tty); + release_console_sem(); + mutex_unlock(&tty_mutex); + /* + * tty_mutex is released, but we still hold BKL, so there is + * still exclusion against init_dev() + */ + return; + } release_console_sem(); - tty_shutdown(tty); + mutex_unlock(&tty_mutex); } static int default_italic_color = 2; // green (ASCII) @@ -2919,19 +2950,10 @@ static const struct tty_operations con_ops = { .throttle = con_throttle, .unthrottle = con_unthrottle, .resize = vt_resize, - .shutdown = con_shutdown }; -static struct cdev vc0_cdev; - -int __init vty_init(const struct file_operations *console_fops) +int __init vty_init(void) { - cdev_init(&vc0_cdev, console_fops); - if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || - register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) - panic("Couldn't register /dev/tty0 driver\n"); - device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); - vcs_init(); console_driver = alloc_tty_driver(MAX_NR_CONSOLES); @@ -2950,6 +2972,7 @@ int __init vty_init(const struct file_operations *console_fops) tty_set_operations(console_driver, &con_ops); if (tty_register_driver(console_driver)) panic("Couldn't register console driver\n"); + kbd_init(); console_map_init(); #ifdef CONFIG_PROM_CONSOLE @@ -3443,7 +3466,7 @@ int register_con_driver(const struct consw *csw, int first, int last) if (retval) goto err; - con_driver->dev = device_create(vtconsole_class, NULL, + con_driver->dev = device_create_drvdata(vtconsole_class, NULL, MKDEV(0, con_driver->node), NULL, "vtcon%i", con_driver->node); @@ -3554,7 +3577,7 @@ static int __init vtconsole_class_init(void) struct con_driver *con = ®istered_con_driver[i]; if (con->con && !con->dev) { - con->dev = device_create(vtconsole_class, NULL, + con->dev = device_create_drvdata(vtconsole_class, NULL, MKDEV(0, con->node), NULL, "vtcon%i", con->node); diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c index 8944ce508e2f..c904e9ad4a71 100644 --- a/trunk/drivers/char/vt_ioctl.c +++ b/trunk/drivers/char/vt_ioctl.c @@ -395,8 +395,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, kbd = kbd_table + console; switch (cmd) { - case TIOCLINUX: - return tioclinux(tty, arg); case KIOCSOUND: if (!perm) goto eperm; diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c index ed132fe55d3d..278c9857bcf5 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -657,7 +657,8 @@ static int __devinit hwicap_setup(struct device *dev, int id, goto failed3; } - device_create(icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id); + device_create_drvdata(icap_class, dev, devt, NULL, + "%s%d", DRIVER_NAME, id); return 0; /* success */ failed3: diff --git a/trunk/drivers/dca/dca-sysfs.c b/trunk/drivers/dca/dca-sysfs.c index bb538b9690e0..7af4b403bd2d 100644 --- a/trunk/drivers/dca/dca-sysfs.c +++ b/trunk/drivers/dca/dca-sysfs.c @@ -15,8 +15,9 @@ int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot) struct device *cd; static int req_count; - cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL, - "requester%d", req_count++); + cd = device_create_drvdata(dca_class, dca->cd, + MKDEV(0, slot + 1), NULL, + "requester%d", req_count++); if (IS_ERR(cd)) return PTR_ERR(cd); return 0; @@ -47,7 +48,8 @@ int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev) return err; } - cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id); + cd = device_create_drvdata(dca_class, dev, MKDEV(0, 0), NULL, + "dca%d", dca->id); if (IS_ERR(cd)) { spin_lock(&dca_idr_lock); idr_remove(&dca_idr, dca->id); diff --git a/trunk/drivers/edac/i5000_edac.c b/trunk/drivers/edac/i5000_edac.c index f0d9b415db50..4a16b5b61cfb 100644 --- a/trunk/drivers/edac/i5000_edac.c +++ b/trunk/drivers/edac/i5000_edac.c @@ -119,7 +119,6 @@ #define FERR_NF_UNCORRECTABLE (FERR_NF_M12ERR | \ FERR_NF_M11ERR | \ FERR_NF_M10ERR | \ - FERR_NF_M9ERR | \ FERR_NF_M8ERR | \ FERR_NF_M7ERR | \ FERR_NF_M6ERR | \ @@ -302,9 +301,6 @@ static char *numcol_toString[] = { }; #endif -/* enables the report of miscellaneous messages as CE errors - default off */ -static int misc_messages; - /* Enumeration of supported devices */ enum i5000_chips { I5000P = 0, @@ -470,8 +466,7 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci, struct i5000_error_info *info, int handle_errors) { - char msg[EDAC_MC_LABEL_LEN + 1 + 160]; - char *specific = NULL; + char msg[EDAC_MC_LABEL_LEN + 1 + 90]; u32 allErrors; int branch; int channel; @@ -485,6 +480,11 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci, if (!allErrors) return; /* if no error, return now */ + /* ONLY ONE of the possible error bits will be set, as per the docs */ + i5000_mc_printk(mci, KERN_ERR, + "FATAL ERRORS Found!!! 1st FATAL Err Reg= 0x%x\n", + allErrors); + branch = EXTRACT_FBDCHAN_INDX(info->ferr_fat_fbd); channel = branch; @@ -501,42 +501,28 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci, rdwr ? "Write" : "Read", ras, cas); /* Only 1 bit will be on */ - switch (allErrors) { - case FERR_FAT_M1ERR: - specific = "Alert on non-redundant retry or fast " - "reset timeout"; - break; - case FERR_FAT_M2ERR: - specific = "Northbound CRC error on non-redundant " - "retry"; - break; - case FERR_FAT_M3ERR: - { - static int done; - - /* - * This error is generated to inform that the intelligent - * throttling is disabled and the temperature passed the - * specified middle point. Since this is something the BIOS - * should take care of, we'll warn only once to avoid - * worthlessly flooding the log. - */ - if (done) - return; - done++; - - specific = ">Tmid Thermal event with intelligent " - "throttling disabled"; - } - break; + if (allErrors & FERR_FAT_M1ERR) { + i5000_mc_printk(mci, KERN_ERR, + "Alert on non-redundant retry or fast " + "reset timeout\n"); + + } else if (allErrors & FERR_FAT_M2ERR) { + i5000_mc_printk(mci, KERN_ERR, + "Northbound CRC error on non-redundant " + "retry\n"); + + } else if (allErrors & FERR_FAT_M3ERR) { + i5000_mc_printk(mci, KERN_ERR, + ">Tmid Thermal event with intelligent " + "throttling disabled\n"); } /* Form out message */ snprintf(msg, sizeof(msg), "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d CAS=%d " - "FATAL Err=0x%x (%s))", + "FATAL Err=0x%x)", branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas, - allErrors, specific); + allErrors); /* Call the helper to output message */ edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); @@ -553,8 +539,7 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci, struct i5000_error_info *info, int handle_errors) { - char msg[EDAC_MC_LABEL_LEN + 1 + 170]; - char *specific = NULL; + char msg[EDAC_MC_LABEL_LEN + 1 + 90]; u32 allErrors; u32 ue_errors; u32 ce_errors; @@ -572,6 +557,10 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci, return; /* if no error, return now */ /* ONLY ONE of the possible error bits will be set, as per the docs */ + i5000_mc_printk(mci, KERN_WARNING, + "NON-FATAL ERRORS Found!!! 1st NON-FATAL Err " + "Reg= 0x%x\n", allErrors); + ue_errors = allErrors & FERR_NF_UNCORRECTABLE; if (ue_errors) { debugf0("\tUncorrected bits= 0x%x\n", ue_errors); @@ -590,47 +579,12 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci, rank, channel, channel + 1, branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas); - switch (ue_errors) { - case FERR_NF_M12ERR: - specific = "Non-Aliased Uncorrectable Patrol Data ECC"; - break; - case FERR_NF_M11ERR: - specific = "Non-Aliased Uncorrectable Spare-Copy " - "Data ECC"; - break; - case FERR_NF_M10ERR: - specific = "Non-Aliased Uncorrectable Mirrored Demand " - "Data ECC"; - break; - case FERR_NF_M9ERR: - specific = "Non-Aliased Uncorrectable Non-Mirrored " - "Demand Data ECC"; - break; - case FERR_NF_M8ERR: - specific = "Aliased Uncorrectable Patrol Data ECC"; - break; - case FERR_NF_M7ERR: - specific = "Aliased Uncorrectable Spare-Copy Data ECC"; - break; - case FERR_NF_M6ERR: - specific = "Aliased Uncorrectable Mirrored Demand " - "Data ECC"; - break; - case FERR_NF_M5ERR: - specific = "Aliased Uncorrectable Non-Mirrored Demand " - "Data ECC"; - break; - case FERR_NF_M4ERR: - specific = "Uncorrectable Data ECC on Replay"; - break; - } - /* Form out message */ snprintf(msg, sizeof(msg), "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d " - "CAS=%d, UE Err=0x%x (%s))", + "CAS=%d, UE Err=0x%x)", branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas, - ue_errors, specific); + ue_errors); /* Call the helper to output message */ edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); @@ -662,74 +616,51 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci, rank, channel, branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas); - switch (ce_errors) { - case FERR_NF_M17ERR: - specific = "Correctable Non-Mirrored Demand Data ECC"; - break; - case FERR_NF_M18ERR: - specific = "Correctable Mirrored Demand Data ECC"; - break; - case FERR_NF_M19ERR: - specific = "Correctable Spare-Copy Data ECC"; - break; - case FERR_NF_M20ERR: - specific = "Correctable Patrol Data ECC"; - break; - } - /* Form out message */ snprintf(msg, sizeof(msg), "(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d " - "CAS=%d, CE Err=0x%x (%s))", branch >> 1, bank, - rdwr ? "Write" : "Read", ras, cas, ce_errors, - specific); + "CAS=%d, CE Err=0x%x)", branch >> 1, bank, + rdwr ? "Write" : "Read", ras, cas, ce_errors); /* Call the helper to output message */ edac_mc_handle_fbd_ce(mci, rank, channel, msg); } - if (!misc_messages) - return; + /* See if any of the thermal errors have fired */ + misc_errors = allErrors & FERR_NF_THERMAL; + if (misc_errors) { + i5000_printk(KERN_WARNING, "\tTHERMAL Error, bits= 0x%x\n", + misc_errors); + } - misc_errors = allErrors & (FERR_NF_NON_RETRY | FERR_NF_NORTH_CRC | - FERR_NF_SPD_PROTOCOL | FERR_NF_DIMM_SPARE); + /* See if any of the thermal errors have fired */ + misc_errors = allErrors & FERR_NF_NON_RETRY; if (misc_errors) { - switch (misc_errors) { - case FERR_NF_M13ERR: - specific = "Non-Retry or Redundant Retry FBD Memory " - "Alert or Redundant Fast Reset Timeout"; - break; - case FERR_NF_M14ERR: - specific = "Non-Retry or Redundant Retry FBD " - "Configuration Alert"; - break; - case FERR_NF_M15ERR: - specific = "Non-Retry or Redundant Retry FBD " - "Northbound CRC error on read data"; - break; - case FERR_NF_M21ERR: - specific = "FBD Northbound CRC error on " - "FBD Sync Status"; - break; - case FERR_NF_M22ERR: - specific = "SPD protocol error"; - break; - case FERR_NF_M27ERR: - specific = "DIMM-spare copy started"; - break; - case FERR_NF_M28ERR: - specific = "DIMM-spare copy completed"; - break; - } - branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd); + i5000_printk(KERN_WARNING, "\tNON-Retry Errors, bits= 0x%x\n", + misc_errors); + } - /* Form out message */ - snprintf(msg, sizeof(msg), - "(Branch=%d Err=%#x (%s))", branch >> 1, - misc_errors, specific); + /* See if any of the thermal errors have fired */ + misc_errors = allErrors & FERR_NF_NORTH_CRC; + if (misc_errors) { + i5000_printk(KERN_WARNING, + "\tNORTHBOUND CRC Error, bits= 0x%x\n", + misc_errors); + } - /* Call the helper to output message */ - edac_mc_handle_fbd_ce(mci, 0, 0, msg); + /* See if any of the thermal errors have fired */ + misc_errors = allErrors & FERR_NF_SPD_PROTOCOL; + if (misc_errors) { + i5000_printk(KERN_WARNING, + "\tSPD Protocol Error, bits= 0x%x\n", + misc_errors); + } + + /* See if any of the thermal errors have fired */ + misc_errors = allErrors & FERR_NF_DIMM_SPARE; + if (misc_errors) { + i5000_printk(KERN_WARNING, "\tDIMM-Spare Error, bits= 0x%x\n", + misc_errors); } } @@ -1566,6 +1497,3 @@ MODULE_DESCRIPTION("MC Driver for Intel I5000 memory controllers - " module_param(edac_op_state, int, 0444); MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); -module_param(misc_messages, int, 0444); -MODULE_PARM_DESC(misc_messages, "Log miscellaneous non fatal messages"); - diff --git a/trunk/drivers/edac/i82443bxgx_edac.c b/trunk/drivers/edac/i82443bxgx_edac.c index 577760a82a0f..c5305e3ee434 100644 --- a/trunk/drivers/edac/i82443bxgx_edac.c +++ b/trunk/drivers/edac/i82443bxgx_edac.c @@ -114,12 +114,6 @@ struct i82443bxgx_edacmc_error_info { static struct edac_pci_ctl_info *i82443bxgx_pci; -static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has - * already registered driver - */ - -static int i82443bxgx_registered = 1; - static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci, struct i82443bxgx_edacmc_error_info *info) @@ -351,17 +345,10 @@ EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1); static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - int rc; - debugf0("MC: " __FILE__ ": %s()\n", __func__); /* don't need to call pci_device_enable() */ - rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data); - - if (mci_pdev == NULL) - mci_pdev = pci_dev_get(pdev); - - return rc; + return i82443bxgx_edacmc_probe1(pdev, ent->driver_data); } static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) @@ -400,61 +387,15 @@ static struct pci_driver i82443bxgx_edacmc_driver = { static int __init i82443bxgx_edacmc_init(void) { - int pci_rc; /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); - pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver); - if (pci_rc < 0) - goto fail0; - - if (mci_pdev == NULL) { - const struct pci_device_id *id = &i82443bxgx_pci_tbl[0]; - int i = 0; - i82443bxgx_registered = 0; - - while (mci_pdev == NULL && id->vendor != 0) { - mci_pdev = pci_get_device(id->vendor, - id->device, NULL); - i++; - id = &i82443bxgx_pci_tbl[i]; - } - if (!mci_pdev) { - debugf0("i82443bxgx pci_get_device fail\n"); - pci_rc = -ENODEV; - goto fail1; - } - - pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl); - - if (pci_rc < 0) { - debugf0("i82443bxgx init fail\n"); - pci_rc = -ENODEV; - goto fail1; - } - } - - return 0; - -fail1: - pci_unregister_driver(&i82443bxgx_edacmc_driver); - -fail0: - if (mci_pdev != NULL) - pci_dev_put(mci_pdev); - - return pci_rc; + return pci_register_driver(&i82443bxgx_edacmc_driver); } static void __exit i82443bxgx_edacmc_exit(void) { pci_unregister_driver(&i82443bxgx_edacmc_driver); - - if (!i82443bxgx_registered) - i82443bxgx_edacmc_remove_one(mci_pdev); - - if (mci_pdev) - pci_dev_put(mci_pdev); } module_init(i82443bxgx_edacmc_init); diff --git a/trunk/drivers/edac/mpc85xx_edac.c b/trunk/drivers/edac/mpc85xx_edac.c index 0cfcb2d075a0..2265d9ca1535 100644 --- a/trunk/drivers/edac/mpc85xx_edac.c +++ b/trunk/drivers/edac/mpc85xx_edac.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -41,7 +40,7 @@ static u32 orig_pci_err_en; #endif static u32 orig_l2_err_disable; -static u32 orig_hid1[2]; +static u32 orig_hid1; /************************ MC SYSFS parts ***********************************/ @@ -648,9 +647,6 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { { .compatible = "fsl,8568-l2-cache-controller", }, - { - .compatible = "fsl,mpc8572-l2-cache-controller", - }, {}, }; @@ -916,8 +912,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, /* register interrupts */ pdata->irq = irq_of_parse_and_map(op->node, 0); res = devm_request_irq(&op->dev, pdata->irq, - mpc85xx_mc_isr, - IRQF_DISABLED | IRQF_SHARED, + mpc85xx_mc_isr, IRQF_DISABLED, "[EDAC] MC err", mci); if (res < 0) { printk(KERN_ERR "%s: Unable to request irq %d for " @@ -985,9 +980,6 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { { .compatible = "fsl,8568-memory-controller", }, - { - .compatible = "fsl,mpc8572-memory-controller", - }, {}, }; @@ -1003,14 +995,6 @@ static struct of_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)); -} - - static int __init mpc85xx_mc_init(void) { int res = 0; @@ -1046,22 +1030,19 @@ static int __init mpc85xx_mc_init(void) * 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); + if (edac_op_state == EDAC_OPSTATE_INT) { + orig_hid1 = mfspr(SPRN_HID1); + mtspr(SPRN_HID1, (orig_hid1 & ~0x20000)); + } return 0; } module_init(mpc85xx_mc_init); -static void __exit mpc85xx_mc_restore_hid1(void *data) -{ - mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]); -} - static void __exit mpc85xx_mc_exit(void) { - on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); + mtspr(SPRN_HID1, orig_hid1); #ifdef CONFIG_PCI of_unregister_platform_driver(&mpc85xx_pci_err_driver); #endif diff --git a/trunk/drivers/firewire/fw-card.c b/trunk/drivers/firewire/fw-card.c index 418c18f07e9d..bbd73a406e53 100644 --- a/trunk/drivers/firewire/fw-card.c +++ b/trunk/drivers/firewire/fw-card.c @@ -189,16 +189,39 @@ static const char gap_count_table[] = { 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 }; +struct bm_data { + struct fw_transaction t; + struct { + __be32 arg; + __be32 data; + } lock; + u32 old; + int rcode; + struct completion done; +}; + +static void +complete_bm_lock(struct fw_card *card, int rcode, + void *payload, size_t length, void *data) +{ + struct bm_data *bmd = data; + + if (rcode == RCODE_COMPLETE) + bmd->old = be32_to_cpu(*(__be32 *) payload); + bmd->rcode = rcode; + complete(&bmd->done); +} + static void fw_card_bm_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, work.work); struct fw_device *root_device; struct fw_node *root_node, *local_node; + struct bm_data bmd; unsigned long flags; - int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode; + int root_id, new_root_id, irm_id, gap_count, generation, grace; bool do_reset = false; - __be32 lock_data[2]; spin_lock_irqsave(&card->lock, flags); local_node = card->local_node; @@ -240,28 +263,33 @@ fw_card_bm_work(struct work_struct *work) goto pick_me; } - lock_data[0] = cpu_to_be32(0x3f); - lock_data[1] = cpu_to_be32(local_node->node_id); + bmd.lock.arg = cpu_to_be32(0x3f); + bmd.lock.data = cpu_to_be32(local_node->node_id); spin_unlock_irqrestore(&card->lock, flags); - rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, - irm_id, generation, SCODE_100, - CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, - lock_data, sizeof(lock_data)); + init_completion(&bmd.done); + fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP, + irm_id, generation, + SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, + &bmd.lock, sizeof(bmd.lock), + complete_bm_lock, &bmd); + wait_for_completion(&bmd.done); - if (rcode == RCODE_GENERATION) - /* Another bus reset, BM work has been rescheduled. */ + if (bmd.rcode == RCODE_GENERATION) { + /* + * Another bus reset happened. Just return, + * the BM work has been rescheduled. + */ goto out; + } - if (rcode == RCODE_COMPLETE && - lock_data[0] != cpu_to_be32(0x3f)) + if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) /* Somebody else is BM, let them do the work. */ goto out; spin_lock_irqsave(&card->lock, flags); - - if (rcode != RCODE_COMPLETE) { + if (bmd.rcode != RCODE_COMPLETE) { /* * The lock request failed, maybe the IRM * isn't really IRM capable after all. Let's diff --git a/trunk/drivers/firewire/fw-cdev.c b/trunk/drivers/firewire/fw-cdev.c index ed03234cbea8..2e6d5848d217 100644 --- a/trunk/drivers/firewire/fw-cdev.c +++ b/trunk/drivers/firewire/fw-cdev.c @@ -720,8 +720,8 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) #define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff) #define GET_INTERRUPT(v) (((v) >> 16) & 0x01) #define GET_SKIP(v) (((v) >> 17) & 0x01) -#define GET_TAG(v) (((v) >> 18) & 0x03) -#define GET_SY(v) (((v) >> 20) & 0x0f) +#define GET_TAG(v) (((v) >> 18) & 0x02) +#define GET_SY(v) (((v) >> 20) & 0x04) #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) static int ioctl_queue_iso(struct client *client, void *buffer) @@ -913,7 +913,7 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg) return -EFAULT; } - return retval; + return 0; } static long diff --git a/trunk/drivers/firewire/fw-device.c b/trunk/drivers/firewire/fw-device.c index 3fccdd484100..0855fb5568e8 100644 --- a/trunk/drivers/firewire/fw-device.c +++ b/trunk/drivers/firewire/fw-device.c @@ -381,21 +381,46 @@ static struct device_attribute fw_device_attributes[] = { __ATTR_NULL, }; +struct read_quadlet_callback_data { + struct completion done; + int rcode; + u32 data; +}; + +static void +complete_transaction(struct fw_card *card, int rcode, + void *payload, size_t length, void *data) +{ + struct read_quadlet_callback_data *callback_data = data; + + if (rcode == RCODE_COMPLETE) + callback_data->data = be32_to_cpu(*(__be32 *)payload); + callback_data->rcode = rcode; + complete(&callback_data->done); +} + static int read_rom(struct fw_device *device, int generation, int index, u32 *data) { - int rcode; + struct read_quadlet_callback_data callback_data; + struct fw_transaction t; + u64 offset; /* device->node_id, accessed below, must not be older than generation */ smp_rmb(); - rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST, + init_completion(&callback_data.done); + + offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4; + fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, device->node_id, generation, device->max_speed, - (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4, - data, 4); - be32_to_cpus(data); + offset, NULL, 4, complete_transaction, &callback_data); + + wait_for_completion(&callback_data.done); + + *data = callback_data.data; - return rcode; + return callback_data.rcode; } #define READ_BIB_ROM_SIZE 256 diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index ef0b9b419c27..aaff50ebba1d 100644 --- a/trunk/drivers/firewire/fw-sbp2.c +++ b/trunk/drivers/firewire/fw-sbp2.c @@ -29,7 +29,6 @@ */ #include -#include #include #include #include @@ -182,16 +181,10 @@ struct sbp2_target { #define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */ #define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ #define SBP2_ORB_NULL 0x80000000 +#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 #define SBP2_RETRY_LIMIT 0xf /* 15 retries */ #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ -/* - * The default maximum s/g segment size of a FireWire controller is - * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to - * be quadlet-aligned, we set the length limit to 0xffff & ~3. - */ -#define SBP2_MAX_SEG_SIZE 0xfffc - /* Unit directory keys */ #define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a #define SBP2_CSR_FIRMWARE_REVISION 0x3c @@ -628,15 +621,25 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, return retval; } +static void +complete_agent_reset_write(struct fw_card *card, int rcode, + void *payload, size_t length, void *done) +{ + complete(done); +} + static void sbp2_agent_reset(struct sbp2_logical_unit *lu) { struct fw_device *device = fw_device(lu->tgt->unit->device.parent); - __be32 d = 0; + DECLARE_COMPLETION_ONSTACK(done); + struct fw_transaction t; + static u32 z; - fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, - lu->tgt->node_id, lu->generation, device->max_speed, - lu->command_block_agent_address + SBP2_AGENT_RESET, - &d, sizeof(d)); + fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, + lu->tgt->node_id, lu->generation, device->max_speed, + lu->command_block_agent_address + SBP2_AGENT_RESET, + &z, sizeof(z), complete_agent_reset_write, &done); + wait_for_completion(&done); } static void @@ -650,7 +653,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) { struct fw_device *device = fw_device(lu->tgt->unit->device.parent); struct fw_transaction *t; - static __be32 d; + static u32 z; t = kmalloc(sizeof(*t), GFP_ATOMIC); if (t == NULL) @@ -659,7 +662,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, lu->tgt->node_id, lu->generation, device->max_speed, lu->command_block_agent_address + SBP2_AGENT_RESET, - &d, sizeof(d), complete_agent_reset_write_no_wait, t); + &z, sizeof(z), complete_agent_reset_write_no_wait, t); } static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation) @@ -820,6 +823,13 @@ static void sbp2_target_put(struct sbp2_target *tgt) kref_put(&tgt->kref, sbp2_release_target); } +static void +complete_set_busy_timeout(struct fw_card *card, int rcode, + void *payload, size_t length, void *done) +{ + complete(done); +} + /* * Write retransmit retry values into the BUSY_TIMEOUT register. * - The single-phase retry protocol is supported by all SBP-2 devices, but the @@ -839,12 +849,17 @@ static void sbp2_target_put(struct sbp2_target *tgt) static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) { struct fw_device *device = fw_device(lu->tgt->unit->device.parent); - __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); + DECLARE_COMPLETION_ONSTACK(done); + struct fw_transaction t; + static __be32 busy_timeout; + + busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); - fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, - lu->tgt->node_id, lu->generation, device->max_speed, - CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, - &d, sizeof(d)); + fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, + lu->tgt->node_id, lu->generation, device->max_speed, + CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout, + sizeof(busy_timeout), complete_set_busy_timeout, &done); + wait_for_completion(&done); } static void sbp2_reconnect(struct work_struct *work); @@ -1106,10 +1121,6 @@ static int sbp2_probe(struct device *dev) struct Scsi_Host *shost; u32 model, firmware_revision; - if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE) - BUG_ON(dma_set_max_seg_size(device->card->device, - SBP2_MAX_SEG_SIZE)); - shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt)); if (shost == NULL) return -ENOMEM; @@ -1358,12 +1369,14 @@ static int sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, struct sbp2_logical_unit *lu) { - struct scatterlist *sg = scsi_sglist(orb->cmd); - int i, n; - - n = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd), - orb->cmd->sc_data_direction); - if (n == 0) + struct scatterlist *sg; + int sg_len, l, i, j, count; + dma_addr_t sg_addr; + + sg = scsi_sglist(orb->cmd); + count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd), + orb->cmd->sc_data_direction); + if (count == 0) goto fail; /* @@ -1373,7 +1386,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, * as the second generation iPod which doesn't support page * tables. */ - if (n == 1) { + if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) { orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high); orb->request.data_descriptor.low = @@ -1383,9 +1396,29 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, return 0; } - for_each_sg(sg, sg, n, i) { - orb->page_table[i].high = cpu_to_be32(sg_dma_len(sg) << 16); - orb->page_table[i].low = cpu_to_be32(sg_dma_address(sg)); + /* + * Convert the scatterlist to an sbp2 page table. If any + * scatterlist entries are too big for sbp2, we split them as we + * go. Even if we ask the block I/O layer to not give us sg + * elements larger than 65535 bytes, some IOMMUs may merge sg elements + * during DMA mapping, and Linux currently doesn't prevent this. + */ + for (i = 0, j = 0; i < count; i++, sg = sg_next(sg)) { + sg_len = sg_dma_len(sg); + sg_addr = sg_dma_address(sg); + while (sg_len) { + /* FIXME: This won't get us out of the pinch. */ + if (unlikely(j >= ARRAY_SIZE(orb->page_table))) { + fw_error("page table overflow\n"); + goto fail_page_table; + } + l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); + orb->page_table[j].low = cpu_to_be32(sg_addr); + orb->page_table[j].high = cpu_to_be32(l << 16); + sg_addr += l; + sg_len -= l; + j++; + } } orb->page_table_bus = @@ -1404,13 +1437,13 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high); orb->request.data_descriptor.low = cpu_to_be32(orb->page_table_bus); orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT | - COMMAND_ORB_DATA_SIZE(n)); + COMMAND_ORB_DATA_SIZE(j)); return 0; fail_page_table: - dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd), - scsi_sg_count(orb->cmd), orb->cmd->sc_data_direction); + dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd), + orb->cmd->sc_data_direction); fail: return -ENOMEM; } @@ -1423,7 +1456,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) struct fw_device *device = fw_device(lu->tgt->unit->device.parent); struct sbp2_command_orb *orb; unsigned int max_payload; - int generation, retval = SCSI_MLQUEUE_HOST_BUSY; + int retval = SCSI_MLQUEUE_HOST_BUSY; /* * Bidirectional commands are not yet implemented, and unknown @@ -1467,9 +1500,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) if (cmd->sc_data_direction == DMA_FROM_DEVICE) orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION); - generation = device->generation; - smp_rmb(); /* sbp2_map_scatterlist looks at tgt->address_high */ - if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) goto out; @@ -1482,7 +1512,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto out; - sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation, + sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation, lu->command_block_agent_address + SBP2_ORB_POINTER); retval = 0; out: @@ -1534,8 +1564,6 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); - blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE); - return 0; } diff --git a/trunk/drivers/firewire/fw-transaction.c b/trunk/drivers/firewire/fw-transaction.c index 022ac4fabb67..e5d1a0b64fcf 100644 --- a/trunk/drivers/firewire/fw-transaction.c +++ b/trunk/drivers/firewire/fw-transaction.c @@ -247,7 +247,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, */ void fw_send_request(struct fw_card *card, struct fw_transaction *t, - int tcode, int destination_id, int generation, int speed, + int tcode, int node_id, int generation, int speed, unsigned long long offset, void *payload, size_t length, fw_transaction_callback_t callback, void *callback_data) @@ -279,14 +279,13 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, card->current_tlabel = (card->current_tlabel + 1) & 0x1f; card->tlabel_mask |= (1 << tlabel); - t->node_id = destination_id; + t->node_id = node_id; t->tlabel = tlabel; t->callback = callback; t->callback_data = callback_data; - fw_fill_request(&t->packet, tcode, t->tlabel, - destination_id, card->node_id, generation, - speed, offset, payload, length); + fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id, + generation, speed, offset, payload, length); t->packet.callback = transmit_complete_callback; list_add_tail(&t->link, &card->transaction_list); @@ -297,45 +296,6 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, } EXPORT_SYMBOL(fw_send_request); -struct transaction_callback_data { - struct completion done; - void *payload; - int rcode; -}; - -static void transaction_callback(struct fw_card *card, int rcode, - void *payload, size_t length, void *data) -{ - struct transaction_callback_data *d = data; - - if (rcode == RCODE_COMPLETE) - memcpy(d->payload, payload, length); - d->rcode = rcode; - complete(&d->done); -} - -/** - * fw_run_transaction - send request and sleep until transaction is completed - * - * Returns the RCODE. - */ -int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, - int generation, int speed, unsigned long long offset, - void *data, size_t length) -{ - struct transaction_callback_data d; - struct fw_transaction t; - - init_completion(&d.done); - d.payload = data; - fw_send_request(card, &t, tcode, destination_id, generation, speed, - offset, data, length, transaction_callback, &d); - wait_for_completion(&d.done); - - return d.rcode; -} -EXPORT_SYMBOL(fw_run_transaction); - static DEFINE_MUTEX(phy_config_mutex); static DECLARE_COMPLETION(phy_config_done); diff --git a/trunk/drivers/firewire/fw-transaction.h b/trunk/drivers/firewire/fw-transaction.h index 027f58ce81ad..2ae1b0d6cb7b 100644 --- a/trunk/drivers/firewire/fw-transaction.h +++ b/trunk/drivers/firewire/fw-transaction.h @@ -426,14 +426,11 @@ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); void fw_send_request(struct fw_card *card, struct fw_transaction *t, - int tcode, int destination_id, int generation, int speed, - unsigned long long offset, void *data, size_t length, + int tcode, int node_id, int generation, int speed, + unsigned long long offset, + void *data, size_t length, fw_transaction_callback_t callback, void *callback_data); -int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, - int generation, int speed, unsigned long long offset, - void *data, size_t length); - int fw_cancel_transaction(struct fw_card *card, struct fw_transaction *transaction); diff --git a/trunk/drivers/firmware/iscsi_ibft.c b/trunk/drivers/firmware/iscsi_ibft.c index deb154aa47c4..b91ef63126ed 100644 --- a/trunk/drivers/firmware/iscsi_ibft.c +++ b/trunk/drivers/firmware/iscsi_ibft.c @@ -334,9 +334,9 @@ static void ibft_release(struct kobject *kobj) /* * Routines for parsing the iBFT data to be human readable. */ -static ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry, - struct ibft_attribute *attr, - char *buf) +ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry, + struct ibft_attribute *attr, + char *buf) { struct ibft_initiator *initiator = entry->initiator; void *ibft_loc = entry->header; @@ -376,9 +376,9 @@ static ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry, return str - buf; } -static ssize_t ibft_attr_show_nic(struct ibft_kobject *entry, - struct ibft_attribute *attr, - char *buf) +ssize_t ibft_attr_show_nic(struct ibft_kobject *entry, + struct ibft_attribute *attr, + char *buf) { struct ibft_nic *nic = entry->nic; void *ibft_loc = entry->header; @@ -440,9 +440,9 @@ static ssize_t ibft_attr_show_nic(struct ibft_kobject *entry, return str - buf; }; -static ssize_t ibft_attr_show_target(struct ibft_kobject *entry, - struct ibft_attribute *attr, - char *buf) +ssize_t ibft_attr_show_target(struct ibft_kobject *entry, + struct ibft_attribute *attr, + char *buf) { struct ibft_tgt *tgt = entry->tgt; void *ibft_loc = entry->header; diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index 9112830107a5..8d2940517c99 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -67,28 +67,17 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) * when setting direction, and otherwise illegal. Until board setup code * and drivers use explicit requests everywhere (which won't happen when * those calls have no teeth) we can't avoid autorequesting. This nag - * message should motivate switching to explicit requests... so should - * the weaker cleanup after faults, compared to gpio_request(). + * message should motivate switching to explicit requests... */ -static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset) +static void gpio_ensure_requested(struct gpio_desc *desc) { if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { - struct gpio_chip *chip = desc->chip; - int gpio = chip->base + offset; - - if (!try_module_get(chip->owner)) { - pr_err("GPIO-%d: module can't be gotten \n", gpio); - clear_bit(FLAG_REQUESTED, &desc->flags); - /* lose */ - return -EIO; - } - pr_warning("GPIO-%d autorequested\n", gpio); + pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); desc_set_label(desc, "[auto]"); - /* caller must chip->request() w/o spinlock */ - if (chip->request) - return 1; + if (!try_module_get(desc->chip->owner)) + pr_err("GPIO-%d: module can't be gotten \n", + (int)(desc - gpio_desc)); } - return 0; } /* caller holds gpio_lock *OR* gpio is marked as requested */ @@ -763,7 +752,6 @@ EXPORT_SYMBOL_GPL(gpiochip_remove); int gpio_request(unsigned gpio, const char *label) { struct gpio_desc *desc; - struct gpio_chip *chip; int status = -EINVAL; unsigned long flags; @@ -772,15 +760,14 @@ int gpio_request(unsigned gpio, const char *label) if (!gpio_is_valid(gpio)) goto done; desc = &gpio_desc[gpio]; - chip = desc->chip; - if (chip == NULL) + if (desc->chip == NULL) goto done; - if (!try_module_get(chip->owner)) + if (!try_module_get(desc->chip->owner)) goto done; /* NOTE: gpio_request() can be called in early boot, - * before IRQs are enabled, for non-sleeping (SOC) GPIOs. + * before IRQs are enabled. */ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { @@ -788,20 +775,7 @@ int gpio_request(unsigned gpio, const char *label) status = 0; } else { status = -EBUSY; - module_put(chip->owner); - } - - if (chip->request) { - /* chip->request may sleep */ - spin_unlock_irqrestore(&gpio_lock, flags); - status = chip->request(chip, gpio - chip->base); - spin_lock_irqsave(&gpio_lock, flags); - - if (status < 0) { - desc_set_label(desc, NULL); - module_put(chip->owner); - clear_bit(FLAG_REQUESTED, &desc->flags); - } + module_put(desc->chip->owner); } done: @@ -817,9 +791,6 @@ void gpio_free(unsigned gpio) { unsigned long flags; struct gpio_desc *desc; - struct gpio_chip *chip; - - might_sleep(); if (!gpio_is_valid(gpio)) { WARN_ON(extra_checks); @@ -831,17 +802,9 @@ void gpio_free(unsigned gpio) spin_lock_irqsave(&gpio_lock, flags); desc = &gpio_desc[gpio]; - chip = desc->chip; - if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) { - if (chip->free) { - spin_unlock_irqrestore(&gpio_lock, flags); - might_sleep_if(extra_checks && chip->can_sleep); - chip->free(chip, gpio - chip->base); - spin_lock_irqsave(&gpio_lock, flags); - } + if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) { desc_set_label(desc, NULL); module_put(desc->chip->owner); - clear_bit(FLAG_REQUESTED, &desc->flags); } else WARN_ON(extra_checks); @@ -906,9 +869,7 @@ int gpio_direction_input(unsigned gpio) gpio -= chip->base; if (gpio >= chip->ngpio) goto fail; - status = gpio_ensure_requested(desc, gpio); - if (status < 0) - goto fail; + gpio_ensure_requested(desc); /* now we know the gpio is valid and chip won't vanish */ @@ -916,22 +877,9 @@ int gpio_direction_input(unsigned gpio) might_sleep_if(extra_checks && chip->can_sleep); - if (status) { - status = chip->request(chip, gpio); - if (status < 0) { - pr_debug("GPIO-%d: chip request fail, %d\n", - chip->base + gpio, status); - /* and it's not available to anyone else ... - * gpio_request() is the fully clean solution. - */ - goto lose; - } - } - status = chip->direction_input(chip, gpio); if (status == 0) clear_bit(FLAG_IS_OUT, &desc->flags); -lose: return status; fail: spin_unlock_irqrestore(&gpio_lock, flags); @@ -959,9 +907,7 @@ int gpio_direction_output(unsigned gpio, int value) gpio -= chip->base; if (gpio >= chip->ngpio) goto fail; - status = gpio_ensure_requested(desc, gpio); - if (status < 0) - goto fail; + gpio_ensure_requested(desc); /* now we know the gpio is valid and chip won't vanish */ @@ -969,22 +915,9 @@ int gpio_direction_output(unsigned gpio, int value) might_sleep_if(extra_checks && chip->can_sleep); - if (status) { - status = chip->request(chip, gpio); - if (status < 0) { - pr_debug("GPIO-%d: chip request fail, %d\n", - chip->base + gpio, status); - /* and it's not available to anyone else ... - * gpio_request() is the fully clean solution. - */ - goto lose; - } - } - status = chip->direction_output(chip, gpio, value); if (status == 0) set_bit(FLAG_IS_OUT, &desc->flags); -lose: return status; fail: spin_unlock_irqrestore(&gpio_lock, flags); @@ -1075,24 +1008,6 @@ int __gpio_cansleep(unsigned gpio) } EXPORT_SYMBOL_GPL(__gpio_cansleep); -/** - * __gpio_to_irq() - return the IRQ corresponding to a GPIO - * @gpio: gpio whose IRQ will be returned (already requested) - * Context: any - * - * This is used directly or indirectly to implement gpio_to_irq(). - * It returns the number of the IRQ signaled by this (input) GPIO, - * or a negative errno. - */ -int __gpio_to_irq(unsigned gpio) -{ - struct gpio_chip *chip; - - chip = gpio_to_chip(gpio); - return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO; -} -EXPORT_SYMBOL_GPL(__gpio_to_irq); - /* There's no value in making it easy to inline GPIO calls that may sleep. diff --git a/trunk/drivers/gpio/max7301.c b/trunk/drivers/gpio/max7301.c index 8b24d784db93..39c795ad8312 100644 --- a/trunk/drivers/gpio/max7301.c +++ b/trunk/drivers/gpio/max7301.c @@ -255,6 +255,10 @@ static int __devinit max7301_probe(struct spi_device *spi) ts->chip.dev = &spi->dev; ts->chip.owner = THIS_MODULE; + ret = gpiochip_add(&ts->chip); + if (ret) + goto exit_destroy; + /* * tristate all pins in hardware and cache the * register values for later use. @@ -265,19 +269,17 @@ static int __devinit max7301_probe(struct spi_device *spi) max7301_write(spi, 0x08 + i, 0xAA); ts->port_config[i] = 0xAA; for (j = 0; j < 4; j++) { - int offset = (i - 1) * 4 + j; - ret = max7301_direction_input(&ts->chip, offset); + int idx = ts->chip.base + (i - 1) * 4 + j; + ret = gpio_direction_input(idx); if (ret) - goto exit_destroy; + goto exit_remove; + gpio_free(idx); } } - - ret = gpiochip_add(&ts->chip); - if (ret) - goto exit_destroy; - return ret; +exit_remove: + gpiochip_remove(&ts->chip); exit_destroy: dev_set_drvdata(&spi->dev, NULL); mutex_destroy(&ts->lock); @@ -323,15 +325,13 @@ static int __init max7301_init(void) { return spi_register_driver(&max7301_driver); } -/* register after spi postcore initcall and before - * subsys initcalls that may rely on these GPIOs - */ -subsys_initcall(max7301_init); static void __exit max7301_exit(void) { spi_unregister_driver(&max7301_driver); } + +module_init(max7301_init); module_exit(max7301_exit); MODULE_AUTHOR("Juergen Beisert"); diff --git a/trunk/drivers/gpio/max732x.c b/trunk/drivers/gpio/max732x.c index 55ae9a41897a..b51c8135ca28 100644 --- a/trunk/drivers/gpio/max732x.c +++ b/trunk/drivers/gpio/max732x.c @@ -372,10 +372,7 @@ static int __init max732x_init(void) { return i2c_add_driver(&max732x_driver); } -/* register after i2c postcore initcall and before - * subsys initcalls that may rely on these GPIOs - */ -subsys_initcall(max732x_init); +module_init(max732x_init); static void __exit max732x_exit(void) { diff --git a/trunk/drivers/gpio/mcp23s08.c b/trunk/drivers/gpio/mcp23s08.c index 89c1d222e9d1..8a1b405fefda 100644 --- a/trunk/drivers/gpio/mcp23s08.c +++ b/trunk/drivers/gpio/mcp23s08.c @@ -419,10 +419,7 @@ static int __init mcp23s08_init(void) { return spi_register_driver(&mcp23s08_driver); } -/* register after spi postcore initcall and before - * subsys initcalls that may rely on these GPIOs - */ -subsys_initcall(mcp23s08_init); +module_init(mcp23s08_init); static void __exit mcp23s08_exit(void) { diff --git a/trunk/drivers/gpio/pca953x.c b/trunk/drivers/gpio/pca953x.c index 9ceeb89f1325..cc8468692ae0 100644 --- a/trunk/drivers/gpio/pca953x.c +++ b/trunk/drivers/gpio/pca953x.c @@ -289,10 +289,7 @@ static int __init pca953x_init(void) { return i2c_add_driver(&pca953x_driver); } -/* register after i2c postcore initcall and before - * subsys initcalls that may rely on these GPIOs - */ -subsys_initcall(pca953x_init); +module_init(pca953x_init); static void __exit pca953x_exit(void) { diff --git a/trunk/drivers/gpio/pcf857x.c b/trunk/drivers/gpio/pcf857x.c index 4bc2070dd4a1..fc9c6ae739ee 100644 --- a/trunk/drivers/gpio/pcf857x.c +++ b/trunk/drivers/gpio/pcf857x.c @@ -351,10 +351,7 @@ static int __init pcf857x_init(void) { return i2c_add_driver(&pcf857x_driver); } -/* register after i2c postcore initcall and before - * subsys initcalls that may rely on these GPIOs - */ -subsys_initcall(pcf857x_init); +module_init(pcf857x_init); static void __exit pcf857x_exit(void) { diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 9ac4720e647b..88974342933c 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -517,7 +517,7 @@ static int i915_dispatch_flip(struct drm_device * dev) RING_LOCALS; DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", - __func__, + __FUNCTION__, dev_priv->current_page, dev_priv->sarea_priv->pf_current_page); @@ -642,7 +642,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEBUG("%s\n", __func__); + DRM_DEBUG("%s\n", __FUNCTION__); LOCK_TEST_WITH_RETURN(dev, file_priv); diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index f5999a91614e..cacf89e65af4 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -67,201 +67,4 @@ config HIDRAW source "drivers/hid/usbhid/Kconfig" -menu "Special HID drivers" - depends on HID - -config HID_COMPAT - bool "Load all HID drivers on hid core load" - default y - ---help--- - Compatible option for older userspace. If you have system without udev - support of module loading through aliases and also old - module-init-tools which can't handle hid bus, choose Y here. Otherwise - say N. If you say N and your userspace is old enough, the only - functionality you lose is modules autoloading. - - If unsure, say Y. - -config HID_A4TECH - tristate "A4 tech" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for A4 tech X5 and WOP-35 / Trust 450L mice. - -config HID_APPLE - tristate "Apple" if EMBEDDED - depends on (USB_HID || BT_HIDP) - default y - ---help--- - Support for some Apple devices which less or more break - HID specification. - - Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, - MacBooks, MacBook Pros and Apple Aluminum. - -config HID_BELKIN - tristate "Belkin" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Belkin Flip KVM and Wireless keyboard. - -config HID_BRIGHT - tristate "Bright" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Bright ABNT-2 keyboard. - -config HID_CHERRY - tristate "Cherry" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Cherry Cymotion keyboard. - -config HID_CHICONY - tristate "Chicony" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Chicony Tactical pad. - -config HID_CYPRESS - tristate "Cypress" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for cypress mouse and barcode readers. - -config HID_DELL - tristate "Dell" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for quirky Dell HID hardware that require - special LED handling (W7658 and SK8115 models) - -config HID_EZKEY - tristate "Ezkey" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Ezkey BTC 8193 keyboard. - -config HID_GYRATION - tristate "Gyration" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Gyration remote control. - -config HID_LOGITECH - tristate "Logitech" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Logitech devices that are not fully compliant with HID standard. - -config LOGITECH_FF - bool "Logitech force feedback" - depends on HID_LOGITECH - select INPUT_FF_MEMLESS - help - Say Y here if you have one of these devices: - - Logitech WingMan Cordless RumblePad - - Logitech WingMan Cordless RumblePad 2 - - Logitech WingMan Force 3D - - Logitech Formula Force EX - - Logitech MOMO Force wheel - - and if you want to enable force feedback for them. - Note: if you say N here, this device will still be supported, but without - force feedback. - -config LOGIRUMBLEPAD2_FF - bool "Logitech Rumblepad 2 force feedback" - depends on HID_LOGITECH - select INPUT_FF_MEMLESS - help - Say Y here if you want to enable force feedback support for Logitech - Rumblepad 2 devices. - -config HID_MICROSOFT - tristate "Microsoft" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Microsoft devices that are not fully compliant with HID standard. - -config HID_MONTEREY - tristate "Monterey" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Monterey Genius KB29E. - -config HID_PANTHERLORD - tristate "Pantherlord devices support" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for PantherLord/GreenAsia based device support. - -config PANTHERLORD_FF - bool "Pantherlord force feedback support" - depends on HID_PANTHERLORD - select INPUT_FF_MEMLESS - help - Say Y here if you have a PantherLord/GreenAsia based game controller - or adapter and want to enable force feedback support for it. - -config HID_PETALYNX - tristate "Petalynx" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Petalynx Maxter remote control. - -config HID_SAMSUNG - tristate "Samsung" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Samsung InfraRed remote control. - -config HID_SONY - tristate "Sony" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Sony PS3 controller. - -config HID_SUNPLUS - tristate "Sunplus" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Sunplus wireless desktop. - -config THRUSTMASTER_FF - tristate "ThrustMaster devices support" - default m - depends on USB_HID - select INPUT_FF_MEMLESS - help - Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or - a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel. - -config ZEROPLUS_FF - tristate "Zeroplus based game controller support" - default m - depends on USB_HID - select INPUT_FF_MEMLESS - help - Say Y here if you have a Zeroplus based game controller. - -endmenu - endif # HID_SUPPORT diff --git a/trunk/drivers/hid/Makefile b/trunk/drivers/hid/Makefile index b09e43e7413e..275dc522c738 100644 --- a/trunk/drivers/hid/Makefile +++ b/trunk/drivers/hid/Makefile @@ -1,46 +1,13 @@ # # Makefile for the HID driver # -hid-objs := hid-core.o hid-input.o +hid-objs := hid-core.o hid-input.o hid-input-quirks.o obj-$(CONFIG_HID) += hid.o hid-$(CONFIG_HID_DEBUG) += hid-debug.o hid-$(CONFIG_HIDRAW) += hidraw.o -ifdef CONFIG_HID_COMPAT -obj-m += hid-dummy.o -endif - -hid-logitech-objs := hid-lg.o -ifdef CONFIG_LOGITECH_FF - hid-logitech-objs += hid-lgff.o -endif -ifdef CONFIG_LOGIRUMBLEPAD2_FF - hid-logitech-objs += hid-lg2ff.o -endif - -obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o -obj-$(CONFIG_HID_APPLE) += hid-apple.o -obj-$(CONFIG_HID_BELKIN) += hid-belkin.o -obj-$(CONFIG_HID_BRIGHT) += hid-bright.o -obj-$(CONFIG_HID_CHERRY) += hid-cherry.o -obj-$(CONFIG_HID_CHICONY) += hid-chicony.o -obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o -obj-$(CONFIG_HID_DELL) += hid-dell.o -obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o -obj-$(CONFIG_HID_GYRATION) += hid-gyration.o -obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o -obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o -obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o -obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o -obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o -obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o -obj-$(CONFIG_HID_SONY) += hid-sony.o -obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o -obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o -obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o - obj-$(CONFIG_USB_HID) += usbhid/ obj-$(CONFIG_USB_MOUSE) += usbhid/ obj-$(CONFIG_USB_KBD) += usbhid/ diff --git a/trunk/drivers/hid/hid-a4tech.c b/trunk/drivers/hid/hid-a4tech.c deleted file mode 100644 index ebca00e6c103..000000000000 --- a/trunk/drivers/hid/hid-a4tech.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * HID driver for some a4tech "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define A4_2WHEEL_MOUSE_HACK_7 0x01 -#define A4_2WHEEL_MOUSE_HACK_B8 0x02 - -struct a4tech_sc { - unsigned long quirks; - unsigned int hw_wheel; - __s32 delayed_value; -}; - -static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - struct a4tech_sc *a4 = hid_get_drvdata(hdev); - - if (usage->type == EV_REL && usage->code == REL_WHEEL) - set_bit(REL_HWHEEL, *bit); - - if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) - return -1; - - return 0; -} - -static int a4_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct a4tech_sc *a4 = hid_get_drvdata(hdev); - struct input_dev *input; - - if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || - !usage->type) - return 0; - - input = field->hidinput->input; - - if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { - if (usage->type == EV_REL && usage->code == REL_WHEEL) { - a4->delayed_value = value; - return 1; - } - - if (usage->hid == 0x000100b8) { - input_event(input, EV_REL, value ? REL_HWHEEL : - REL_WHEEL, a4->delayed_value); - return 1; - } - } - - if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) { - a4->hw_wheel = !!value; - return 1; - } - - if (usage->code == REL_WHEEL && a4->hw_wheel) { - input_event(input, usage->type, REL_HWHEEL, value); - return 1; - } - - return 0; -} - -static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - struct a4tech_sc *a4; - int ret; - - a4 = kzalloc(sizeof(*a4), GFP_KERNEL); - if (a4 == NULL) { - dev_err(&hdev->dev, "can't alloc device descriptor\n"); - ret = -ENOMEM; - goto err_free; - } - - a4->quirks = id->driver_data; - - hid_set_drvdata(hdev, a4); - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - kfree(a4); - return ret; -} - -static void a4_remove(struct hid_device *hdev) -{ - struct a4tech_sc *a4 = hid_get_drvdata(hdev); - - hid_hw_stop(hdev); - kfree(a4); -} - -static const struct hid_device_id a4_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), - .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, - { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), - .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, - { } -}; -MODULE_DEVICE_TABLE(hid, a4_devices); - -static struct hid_driver a4_driver = { - .name = "a4tech", - .id_table = a4_devices, - .input_mapped = a4_input_mapped, - .event = a4_event, - .probe = a4_probe, - .remove = a4_remove, -}; - -static int a4_init(void) -{ - return hid_register_driver(&a4_driver); -} - -static void a4_exit(void) -{ - hid_unregister_driver(&a4_driver); -} - -module_init(a4_init); -module_exit(a4_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(a4tech); diff --git a/trunk/drivers/hid/hid-apple.c b/trunk/drivers/hid/hid-apple.c deleted file mode 100644 index fd7f896b34f7..000000000000 --- a/trunk/drivers/hid/hid-apple.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * USB HID quirks support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define APPLE_RDESC_JIS 0x0001 -#define APPLE_IGNORE_MOUSE 0x0002 -#define APPLE_HAS_FN 0x0004 -#define APPLE_HIDDEV 0x0008 -#define APPLE_ISO_KEYBOARD 0x0010 -#define APPLE_MIGHTYMOUSE 0x0020 -#define APPLE_INVERT_HWHEEL 0x0040 -#define APPLE_IGNORE_HIDINPUT 0x0080 -#define APPLE_NUMLOCK_EMULATION 0x0100 - -#define APPLE_FLAG_FKEY 0x01 - -static unsigned int fnmode = 1; -module_param(fnmode, uint, 0644); -MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " - "[1] = fkeyslast, 2 = fkeysfirst)"); - -struct apple_sc { - unsigned long quirks; - unsigned int fn_on; - DECLARE_BITMAP(pressed_fn, KEY_CNT); - DECLARE_BITMAP(pressed_numlock, KEY_CNT); -}; - -struct apple_key_translation { - u16 from; - u16 to; - u8 flags; -}; - -static struct apple_key_translation apple_fn_keys[] = { - { KEY_BACKSPACE, KEY_DELETE }, - { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, - { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, - { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ - { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ - { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, - { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, - { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, - { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, - { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, - { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, - { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, - { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, - { KEY_UP, KEY_PAGEUP }, - { KEY_DOWN, KEY_PAGEDOWN }, - { KEY_LEFT, KEY_HOME }, - { KEY_RIGHT, KEY_END }, - { } -}; - -static struct apple_key_translation powerbook_fn_keys[] = { - { KEY_BACKSPACE, KEY_DELETE }, - { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, - { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, - { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, - { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, - { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, - { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, - { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, - { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, - { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, - { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, - { KEY_UP, KEY_PAGEUP }, - { KEY_DOWN, KEY_PAGEDOWN }, - { KEY_LEFT, KEY_HOME }, - { KEY_RIGHT, KEY_END }, - { } -}; - -static struct apple_key_translation powerbook_numlock_keys[] = { - { KEY_J, KEY_KP1 }, - { KEY_K, KEY_KP2 }, - { KEY_L, KEY_KP3 }, - { KEY_U, KEY_KP4 }, - { KEY_I, KEY_KP5 }, - { KEY_O, KEY_KP6 }, - { KEY_7, KEY_KP7 }, - { KEY_8, KEY_KP8 }, - { KEY_9, KEY_KP9 }, - { KEY_M, KEY_KP0 }, - { KEY_DOT, KEY_KPDOT }, - { KEY_SLASH, KEY_KPPLUS }, - { KEY_SEMICOLON, KEY_KPMINUS }, - { KEY_P, KEY_KPASTERISK }, - { KEY_MINUS, KEY_KPEQUAL }, - { KEY_0, KEY_KPSLASH }, - { KEY_F6, KEY_NUMLOCK }, - { KEY_KPENTER, KEY_KPENTER }, - { KEY_BACKSPACE, KEY_BACKSPACE }, - { } -}; - -static struct apple_key_translation apple_iso_keyboard[] = { - { KEY_GRAVE, KEY_102ND }, - { KEY_102ND, KEY_GRAVE }, - { } -}; - -static struct apple_key_translation *apple_find_translation( - struct apple_key_translation *table, u16 from) -{ - struct apple_key_translation *trans; - - /* Look for the translation */ - for (trans = table; trans->from; trans++) - if (trans->from == from) - return trans; - - return NULL; -} - -static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, - struct hid_usage *usage, __s32 value) -{ - struct apple_sc *asc = hid_get_drvdata(hid); - struct apple_key_translation *trans; - - if (usage->code == KEY_FN) { - asc->fn_on = !!value; - input_event(input, usage->type, usage->code, value); - return 1; - } - - if (fnmode) { - int do_translate; - - trans = apple_find_translation((hid->product < 0x220 || - hid->product >= 0x300) ? - powerbook_fn_keys : apple_fn_keys, - usage->code); - if (trans) { - if (test_bit(usage->code, asc->pressed_fn)) - do_translate = 1; - else if (trans->flags & APPLE_FLAG_FKEY) - do_translate = (fnmode == 2 && asc->fn_on) || - (fnmode == 1 && !asc->fn_on); - else - do_translate = asc->fn_on; - - if (do_translate) { - if (value) - set_bit(usage->code, asc->pressed_fn); - else - clear_bit(usage->code, asc->pressed_fn); - - input_event(input, usage->type, trans->to, - value); - - return 1; - } - } - - if (asc->quirks & APPLE_NUMLOCK_EMULATION && - (test_bit(usage->code, asc->pressed_numlock) || - test_bit(LED_NUML, input->led))) { - trans = apple_find_translation(powerbook_numlock_keys, - usage->code); - - if (trans) { - if (value) - set_bit(usage->code, - asc->pressed_numlock); - else - clear_bit(usage->code, - asc->pressed_numlock); - - input_event(input, usage->type, trans->to, - value); - } - - return 1; - } - } - - if (asc->quirks & APPLE_ISO_KEYBOARD) { - trans = apple_find_translation(apple_iso_keyboard, usage->code); - if (trans) { - input_event(input, usage->type, trans->to, value); - return 1; - } - } - - return 0; -} - -static int apple_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct apple_sc *asc = hid_get_drvdata(hdev); - - if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || - !usage->type) - return 0; - - if ((asc->quirks & APPLE_INVERT_HWHEEL) && - usage->code == REL_HWHEEL) { - input_event(field->hidinput->input, usage->type, usage->code, - -value); - return 1; - } - - if ((asc->quirks & APPLE_HAS_FN) && - hidinput_apple_event(hdev, field->hidinput->input, - usage, value)) - return 1; - - - return 0; -} - -/* - * MacBook JIS keyboard has wrong logical maximum - */ -static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - struct apple_sc *asc = hid_get_drvdata(hdev); - - if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 && - rdesc[53] == 0x65 && rdesc[59] == 0x65) { - dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " - "descriptor\n"); - rdesc[53] = rdesc[59] = 0xe7; - } -} - -static void apple_setup_input(struct input_dev *input) -{ - struct apple_key_translation *trans; - - set_bit(KEY_NUMLOCK, input->keybit); - - /* Enable all needed keys */ - for (trans = apple_fn_keys; trans->from; trans++) - set_bit(trans->to, input->keybit); - - for (trans = powerbook_fn_keys; trans->from; trans++) - set_bit(trans->to, input->keybit); - - for (trans = powerbook_numlock_keys; trans->from; trans++) - set_bit(trans->to, input->keybit); - - for (trans = apple_iso_keyboard; trans->from; trans++) - set_bit(trans->to, input->keybit); -} - -static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if (usage->hid == (HID_UP_CUSTOM | 0x0003)) { - /* The fn key on Apple USB keyboards */ - set_bit(EV_REP, hi->input->evbit); - hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); - apple_setup_input(hi->input); - return 1; - } - - /* we want the hid layer to go through standard path (set and ignore) */ - return 0; -} - -static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - struct apple_sc *asc = hid_get_drvdata(hdev); - - if (asc->quirks & APPLE_MIGHTYMOUSE) { - if (usage->hid == HID_GD_Z) - hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); - else if (usage->code == BTN_1) - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2); - else if (usage->code == BTN_2) - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1); - } - - return 0; -} - -static int apple_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - unsigned long quirks = id->driver_data; - struct apple_sc *asc; - unsigned int connect_mask = HID_CONNECT_DEFAULT; - int ret; - - /* return something else or move to hid layer? device will reside - allocated */ - if (id->bus == BUS_USB && (quirks & APPLE_IGNORE_MOUSE) && - to_usb_interface(hdev->dev.parent)->cur_altsetting-> - desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) - return -ENODEV; - - asc = kzalloc(sizeof(*asc), GFP_KERNEL); - if (asc == NULL) { - dev_err(&hdev->dev, "can't alloc apple descriptor\n"); - return -ENOMEM; - } - - asc->quirks = quirks; - - hid_set_drvdata(hdev, asc); - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - if (quirks & APPLE_HIDDEV) - connect_mask |= HID_CONNECT_HIDDEV_FORCE; - if (quirks & APPLE_IGNORE_HIDINPUT) - connect_mask &= ~HID_CONNECT_HIDINPUT; - - ret = hid_hw_start(hdev, connect_mask); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - kfree(asc); - return ret; -} - -static void apple_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); -} - -static const struct hid_device_id apple_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL), - .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4), - .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), - .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, - - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS}, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), - .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS), - .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), - .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), - .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), - .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | - APPLE_IGNORE_MOUSE }, - - /* Apple wireless Mighty Mouse */ - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c), - .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, - - { } -}; -MODULE_DEVICE_TABLE(hid, apple_devices); - -static struct hid_driver apple_driver = { - .name = "apple", - .id_table = apple_devices, - .report_fixup = apple_report_fixup, - .probe = apple_probe, - .remove = apple_remove, - .event = apple_event, - .input_mapping = apple_input_mapping, - .input_mapped = apple_input_mapped, -}; - -static int apple_init(void) -{ - int ret; - - ret = hid_register_driver(&apple_driver); - if (ret) - printk(KERN_ERR "can't register apple driver\n"); - - return ret; -} - -static void apple_exit(void) -{ - hid_unregister_driver(&apple_driver); -} - -module_init(apple_init); -module_exit(apple_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(apple); diff --git a/trunk/drivers/hid/hid-belkin.c b/trunk/drivers/hid/hid-belkin.c deleted file mode 100644 index 12c8a9ba6ed6..000000000000 --- a/trunk/drivers/hid/hid-belkin.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * HID driver for some belkin "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -#define BELKIN_HIDDEV 0x01 -#define BELKIN_WKBD 0x02 - -#define belkin_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int belkin_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER || - !(quirks & BELKIN_WKBD)) - return 0; - - switch (usage->hid & HID_USAGE) { - case 0x03a: belkin_map_key_clear(KEY_SOUND); break; - case 0x03b: belkin_map_key_clear(KEY_CAMERA); break; - case 0x03c: belkin_map_key_clear(KEY_DOCUMENTS); break; - default: - return 0; - } - return 1; -} - -static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - unsigned long quirks = id->driver_data; - int ret; - - hid_set_drvdata(hdev, (void *)quirks); - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | - ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id belkin_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM), - .driver_data = BELKIN_HIDDEV }, - { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD), - .driver_data = BELKIN_WKBD }, - { } -}; -MODULE_DEVICE_TABLE(hid, belkin_devices); - -static struct hid_driver belkin_driver = { - .name = "belkin", - .id_table = belkin_devices, - .input_mapping = belkin_input_mapping, - .probe = belkin_probe, -}; - -static int belkin_init(void) -{ - return hid_register_driver(&belkin_driver); -} - -static void belkin_exit(void) -{ - hid_unregister_driver(&belkin_driver); -} - -module_init(belkin_init); -module_exit(belkin_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(belkin); diff --git a/trunk/drivers/hid/hid-bright.c b/trunk/drivers/hid/hid-bright.c deleted file mode 100644 index 38517a117dfd..000000000000 --- a/trunk/drivers/hid/hid-bright.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * HID driver for some bright "special" devices - * - * Copyright (c) 2008 Mauro Carvalho Chehab - * - * Based on hid-dell driver - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -static int bright_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - usbhid_set_leds(hdev); - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id bright_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, - { } -}; -MODULE_DEVICE_TABLE(hid, bright_devices); - -static struct hid_driver bright_driver = { - .name = "bright", - .id_table = bright_devices, - .probe = bright_probe, -}; - -static int bright_init(void) -{ - return hid_register_driver(&bright_driver); -} - -static void bright_exit(void) -{ - hid_unregister_driver(&bright_driver); -} - -module_init(bright_init); -module_exit(bright_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(bright); diff --git a/trunk/drivers/hid/hid-cherry.c b/trunk/drivers/hid/hid-cherry.c deleted file mode 100644 index b833b9769aba..000000000000 --- a/trunk/drivers/hid/hid-cherry.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * HID driver for some cherry "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -/* - * Cherry Cymotion keyboard have an invalid HID report descriptor, - * that needs fixing before we can parse it. - */ -static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - dev_info(&hdev->dev, "fixing up Cherry Cymotion report " - "descriptor\n"); - rdesc[11] = rdesc[16] = 0xff; - rdesc[12] = rdesc[17] = 0x03; - } -} - -#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) - return 0; - - switch (usage->hid & HID_USAGE) { - case 0x301: ch_map_key_clear(KEY_PROG1); break; - case 0x302: ch_map_key_clear(KEY_PROG2); break; - case 0x303: ch_map_key_clear(KEY_PROG3); break; - default: - return 0; - } - - return 1; -} - -static const struct hid_device_id ch_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, - { } -}; -MODULE_DEVICE_TABLE(hid, ch_devices); - -static struct hid_driver ch_driver = { - .name = "cherry", - .id_table = ch_devices, - .report_fixup = ch_report_fixup, - .input_mapping = ch_input_mapping, -}; - -static int ch_init(void) -{ - return hid_register_driver(&ch_driver); -} - -static void ch_exit(void) -{ - hid_unregister_driver(&ch_driver); -} - -module_init(ch_init); -module_exit(ch_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(cherry); diff --git a/trunk/drivers/hid/hid-chicony.c b/trunk/drivers/hid/hid-chicony.c deleted file mode 100644 index a54d4096e0f7..000000000000 --- a/trunk/drivers/hid/hid-chicony.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * HID driver for some chicony "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) - return 0; - - set_bit(EV_REP, hi->input->evbit); - switch (usage->hid & HID_USAGE) { - case 0xff01: ch_map_key_clear(BTN_1); break; - case 0xff02: ch_map_key_clear(BTN_2); break; - case 0xff03: ch_map_key_clear(BTN_3); break; - case 0xff04: ch_map_key_clear(BTN_4); break; - case 0xff05: ch_map_key_clear(BTN_5); break; - case 0xff06: ch_map_key_clear(BTN_6); break; - case 0xff07: ch_map_key_clear(BTN_7); break; - case 0xff08: ch_map_key_clear(BTN_8); break; - case 0xff09: ch_map_key_clear(BTN_9); break; - case 0xff0a: ch_map_key_clear(BTN_A); break; - case 0xff0b: ch_map_key_clear(BTN_B); break; - default: - return 0; - } - return 1; -} - -static const struct hid_device_id ch_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, - { } -}; -MODULE_DEVICE_TABLE(hid, ch_devices); - -static struct hid_driver ch_driver = { - .name = "chicony", - .id_table = ch_devices, - .input_mapping = ch_input_mapping, -}; - -static int ch_init(void) -{ - return hid_register_driver(&ch_driver); -} - -static void ch_exit(void) -{ - hid_unregister_driver(&ch_driver); -} - -module_init(ch_init); -module_exit(ch_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(chicony); diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index 721a36d97582..426ac5add585 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -33,8 +33,6 @@ #include #include -#include "hid-ids.h" - /* * Version Information */ @@ -270,9 +268,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign static u32 item_udata(struct hid_item *item) { switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; + case 1: return item->data.u8; + case 2: return item->data.u16; + case 4: return item->data.u32; } return 0; } @@ -280,9 +278,9 @@ static u32 item_udata(struct hid_item *item) static s32 item_sdata(struct hid_item *item) { switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; + case 1: return item->data.s8; + case 2: return item->data.s16; + case 4: return item->data.s32; } return 0; } @@ -294,91 +292,87 @@ static s32 item_sdata(struct hid_item *item) static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) { switch (item->tag) { - case HID_GLOBAL_ITEM_TAG_PUSH: - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg_hid("global enviroment stack overflow\n"); - return -1; - } + case HID_GLOBAL_ITEM_TAG_PUSH: - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; + if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { + dbg_hid("global enviroment stack overflow\n"); + return -1; + } - case HID_GLOBAL_ITEM_TAG_POP: + memcpy(parser->global_stack + parser->global_stack_ptr++, + &parser->global, sizeof(struct hid_global)); + return 0; - if (!parser->global_stack_ptr) { - dbg_hid("global enviroment stack underflow\n"); - return -1; - } + case HID_GLOBAL_ITEM_TAG_POP: - memcpy(&parser->global, parser->global_stack + - --parser->global_stack_ptr, sizeof(struct hid_global)); - return 0; + if (!parser->global_stack_ptr) { + dbg_hid("global enviroment stack underflow\n"); + return -1; + } - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; + memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, + sizeof(struct hid_global)); + return 0; - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; + case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: + parser->global.usage_page = item_udata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; + case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: + parser->global.logical_minimum = item_sdata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; + case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: + if (parser->global.logical_minimum < 0) + parser->global.logical_maximum = item_sdata(item); + else + parser->global.logical_maximum = item_udata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; + case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: + parser->global.physical_minimum = item_sdata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; + case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: + if (parser->global.physical_minimum < 0) + parser->global.physical_maximum = item_sdata(item); + else + parser->global.physical_maximum = item_udata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; + case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: + parser->global.unit_exponent = item_sdata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - parser->global.report_size = item_udata(item); - if (parser->global.report_size > 32) { - dbg_hid("invalid report_size %d\n", - parser->global.report_size); - return -1; - } - return 0; + case HID_GLOBAL_ITEM_TAG_UNIT: + parser->global.unit = item_udata(item); + return 0; - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - parser->global.report_count = item_udata(item); - if (parser->global.report_count > HID_MAX_USAGES) { - dbg_hid("invalid report_count %d\n", - parser->global.report_count); - return -1; - } - return 0; + case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: + if ((parser->global.report_size = item_udata(item)) > 32) { + dbg_hid("invalid report_size %d\n", parser->global.report_size); + return -1; + } + return 0; - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - parser->global.report_id = item_udata(item); - if (parser->global.report_id == 0) { - dbg_hid("report_id 0 is invalid\n"); - return -1; - } - return 0; + case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: + if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { + dbg_hid("invalid report_count %d\n", parser->global.report_count); + return -1; + } + return 0; - default: - dbg_hid("unknown global tag 0x%x\n", item->tag); - return -1; + case HID_GLOBAL_ITEM_TAG_REPORT_ID: + if ((parser->global.report_id = item_udata(item)) == 0) { + dbg_hid("report_id 0 is invalid\n"); + return -1; + } + return 0; + + default: + dbg_hid("unknown global tag 0x%x\n", item->tag); + return -1; } } @@ -399,76 +393,77 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) data = item_udata(item); switch (item->tag) { - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg_hid("nested delimiters\n"); - return -1; + + case HID_LOCAL_ITEM_TAG_DELIMITER: + + if (data) { + /* + * We treat items before the first delimiter + * as global to all usage sets (branch 0). + * In the moment we process only these global + * items and the first delimiter set. + */ + if (parser->local.delimiter_depth != 0) { + dbg_hid("nested delimiters\n"); + return -1; + } + parser->local.delimiter_depth++; + parser->local.delimiter_branch++; + } else { + if (parser->local.delimiter_depth < 1) { + dbg_hid("bogus close delimiter\n"); + return -1; + } + parser->local.delimiter_depth--; } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg_hid("bogus close delimiter\n"); - return -1; + return 1; + + case HID_LOCAL_ITEM_TAG_USAGE: + + if (parser->local.delimiter_branch > 1) { + dbg_hid("alternative usage ignored\n"); + return 0; } - parser->local.delimiter_depth--; - } - return 1; - case HID_LOCAL_ITEM_TAG_USAGE: + if (item->size <= 2) + data = (parser->global.usage_page << 16) + data; - if (parser->local.delimiter_branch > 1) { - dbg_hid("alternative usage ignored\n"); - return 0; - } + return hid_add_usage(parser, data); - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; + case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - return hid_add_usage(parser, data); + if (parser->local.delimiter_branch > 1) { + dbg_hid("alternative usage ignored\n"); + return 0; + } - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: + if (item->size <= 2) + data = (parser->global.usage_page << 16) + data; - if (parser->local.delimiter_branch > 1) { - dbg_hid("alternative usage ignored\n"); + parser->local.usage_minimum = data; return 0; - } - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; + case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - parser->local.usage_minimum = data; - return 0; + if (parser->local.delimiter_branch > 1) { + dbg_hid("alternative usage ignored\n"); + return 0; + } - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: + if (item->size <= 2) + data = (parser->global.usage_page << 16) + data; - if (parser->local.delimiter_branch > 1) { - dbg_hid("alternative usage ignored\n"); + for (n = parser->local.usage_minimum; n <= data; n++) + if (hid_add_usage(parser, n)) { + dbg_hid("hid_add_usage failed\n"); + return -1; + } return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg_hid("hid_add_usage failed\n"); - return -1; - } - return 0; + default: - default: - - dbg_hid("unknown local item tag 0x%x\n", item->tag); - return 0; + dbg_hid("unknown local item tag 0x%x\n", item->tag); + return 0; } return 0; } @@ -485,24 +480,24 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) data = item_udata(item); switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg_hid("unknown main item tag 0x%x\n", item->tag); - ret = 0; + case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: + ret = open_collection(parser, data & 0xff); + break; + case HID_MAIN_ITEM_TAG_END_COLLECTION: + ret = close_collection(parser); + break; + case HID_MAIN_ITEM_TAG_INPUT: + ret = hid_add_field(parser, HID_INPUT_REPORT, data); + break; + case HID_MAIN_ITEM_TAG_OUTPUT: + ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); + break; + case HID_MAIN_ITEM_TAG_FEATURE: + ret = hid_add_field(parser, HID_FEATURE_REPORT, data); + break; + default: + dbg_hid("unknown main item tag 0x%x\n", item->tag); + ret = 0; } memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ @@ -539,10 +534,9 @@ static void hid_free_report(struct hid_report *report) * Free a device structure, all reports, and all fields. */ -static void hid_device_release(struct device *dev) +void hid_free_device(struct hid_device *device) { - struct hid_device *device = container_of(dev, struct hid_device, dev); - unsigned i, j; + unsigned i,j; for (i = 0; i < HID_REPORT_TYPES; i++) { struct hid_report_enum *report_enum = device->report_enum + i; @@ -558,6 +552,7 @@ static void hid_device_release(struct device *dev) kfree(device->collection); kfree(device); } +EXPORT_SYMBOL_GPL(hid_free_device); /* * Fetch a report description item from the data stream. We support long @@ -598,52 +593,47 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) item->size = b & 3; switch (item->size) { - case 0: - return start; - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; + case 0: + return start; - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = get_unaligned_le16(start); - start = (__u8 *)((__le16 *)start + 1); - return start; + case 1: + if ((end - start) < 1) + return NULL; + item->data.u8 = *start++; + return start; - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = get_unaligned_le32(start); - start = (__u8 *)((__le32 *)start + 1); - return start; + case 2: + if ((end - start) < 2) + return NULL; + item->data.u16 = get_unaligned_le16(start); + start = (__u8 *)((__le16 *)start + 1); + return start; + + case 3: + item->size++; + if ((end - start) < 4) + return NULL; + item->data.u32 = get_unaligned_le32(start); + start = (__u8 *)((__le32 *)start + 1); + return start; } return NULL; } -/** - * hid_parse_report - parse device report - * - * @device: hid device - * @start: report start - * @size: report size - * +/* * Parse a report description into a hid_device structure. Reports are * enumerated, fields are attached to these reports. - * 0 returned on success, otherwise nonzero error value. */ -int hid_parse_report(struct hid_device *device, __u8 *start, - unsigned size) + +struct hid_device *hid_parse_report(__u8 *start, unsigned size) { + struct hid_device *device; struct hid_parser *parser; struct hid_item item; __u8 *end; - int ret; + unsigned i; static int (*dispatch_type[])(struct hid_parser *parser, struct hid_item *item) = { hid_parser_main, @@ -652,57 +642,76 @@ int hid_parse_report(struct hid_device *device, __u8 *start, hid_parser_reserved }; - if (device->driver->report_fixup) - device->driver->report_fixup(device, start, size); + if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL))) + return NULL; - device->rdesc = kmalloc(size, GFP_KERNEL); - if (device->rdesc == NULL) - return -ENOMEM; + if (!(device->collection = kzalloc(sizeof(struct hid_collection) * + HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { + kfree(device); + return NULL; + } + device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + + for (i = 0; i < HID_REPORT_TYPES; i++) + INIT_LIST_HEAD(&device->report_enum[i].report_list); + + if (!(device->rdesc = kmalloc(size, GFP_KERNEL))) { + kfree(device->collection); + kfree(device); + return NULL; + } memcpy(device->rdesc, start, size); device->rsize = size; - parser = vmalloc(sizeof(struct hid_parser)); - if (!parser) { - ret = -ENOMEM; - goto err; + if (!(parser = vmalloc(sizeof(struct hid_parser)))) { + kfree(device->rdesc); + kfree(device->collection); + kfree(device); + return NULL; } - memset(parser, 0, sizeof(struct hid_parser)); parser->device = device; end = start + size; - ret = -EINVAL; while ((start = fetch_item(start, end, &item)) != NULL) { if (item.format != HID_ITEM_FORMAT_SHORT) { dbg_hid("unexpected long global item\n"); - goto err; + hid_free_device(device); + vfree(parser); + return NULL; } if (dispatch_type[item.type](parser, &item)) { dbg_hid("item %u %u %u %u parsing failed\n", item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - goto err; + hid_free_device(device); + vfree(parser); + return NULL; } if (start == end) { if (parser->collection_stack_ptr) { dbg_hid("unbalanced collection at end of report description\n"); - goto err; + hid_free_device(device); + vfree(parser); + return NULL; } if (parser->local.delimiter_depth) { dbg_hid("unbalanced delimiter at end of report description\n"); - goto err; + hid_free_device(device); + vfree(parser); + return NULL; } vfree(parser); - return 0; + return device; } } dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); -err: + hid_free_device(device); vfree(parser); - return ret; + return NULL; } EXPORT_SYMBOL_GPL(hid_parse_report); @@ -715,9 +724,9 @@ EXPORT_SYMBOL_GPL(hid_parse_report); static s32 snto32(__u32 value, unsigned n) { switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); + case 8: return ((__s8)value); + case 16: return ((__s16)value); + case 32: return ((__s32)value); } return value & (1 << (n - 1)) ? value | (-1 << n) : value; } @@ -806,73 +815,9 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n) return -1; } -/** - * hid_match_report - check if driver's raw_event should be called - * - * @hid: hid device - * @report_type: type to match against - * - * compare hid->driver->report_table->report_type to report->type - */ -static int hid_match_report(struct hid_device *hid, struct hid_report *report) -{ - const struct hid_report_id *id = hid->driver->report_table; - - if (!id) /* NULL means all */ - return 1; - - for (; id->report_type != HID_TERMINATOR; id++) - if (id->report_type == HID_ANY_ID || - id->report_type == report->type) - return 1; - return 0; -} - -/** - * hid_match_usage - check if driver's event should be called - * - * @hid: hid device - * @usage: usage to match against - * - * compare hid->driver->usage_table->usage_{type,code} to - * usage->usage_{type,code} - */ -static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage) +static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt) { - const struct hid_usage_id *id = hid->driver->usage_table; - - if (!id) /* NULL means all */ - return 1; - - for (; id->usage_type != HID_ANY_ID - 1; id++) - if ((id->usage_hid == HID_ANY_ID || - id->usage_hid == usage->hid) && - (id->usage_type == HID_ANY_ID || - id->usage_type == usage->type) && - (id->usage_code == HID_ANY_ID || - id->usage_code == usage->code)) - return 1; - return 0; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value, int interrupt) -{ - struct hid_driver *hdrv = hid->driver; - int ret; - hid_dump_input(usage, value); - - if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { - ret = hdrv->event(hid, field, usage, value); - if (ret != 0) { - if (ret < 0) - dbg_hid("%s's event failed with %d\n", - hdrv->name, ret); - return; - } - } - if (hid->claimed & HID_CLAIMED_INPUT) hidinput_hid_event(hid, field, usage, value); if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) @@ -1001,87 +946,13 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) } EXPORT_SYMBOL_GPL(hid_set_field); -static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, - const u8 *data) -{ - struct hid_report *report; - unsigned int n = 0; /* Normally report number is 0 */ - - /* Device uses numbered reports, data[0] is report number */ - if (report_enum->numbered) - n = *data; - - report = report_enum->report_id_hash[n]; - if (report == NULL) - dbg_hid("undefined report_id %u received\n", n); - - return report; -} - -void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, - int interrupt) -{ - struct hid_report_enum *report_enum = hid->report_enum + type; - struct hid_report *report; - unsigned int a; - int rsize, csize = size; - u8 *cdata = data; - - report = hid_get_report(report_enum, data); - if (!report) - return; - - if (report_enum->numbered) { - cdata++; - csize--; - } - - rsize = ((report->size - 1) >> 3) + 1; - - if (csize < rsize) { - dbg_hid("report %d is too short, (%d < %d)\n", report->id, - csize, rsize); - memset(cdata + csize, 0, rsize - csize); - } - - if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) - hid->hiddev_report_event(hid, report); - if (hid->claimed & HID_CLAIMED_HIDRAW) { - /* numbered reports need to be passed with the report num */ - if (report_enum->numbered) - hidraw_report_event(hid, data - 1, size + 1); - else - hidraw_report_event(hid, data, size); - } - - for (a = 0; a < report->maxfield; a++) - hid_input_field(hid, report->field[a], cdata, interrupt); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); -} -EXPORT_SYMBOL_GPL(hid_report_raw_event); - -/** - * hid_input_report - report data from lower layer (usb, bt...) - * - * @hid: hid device - * @type: HID report type (HID_*_REPORT) - * @data: report contents - * @size: size of data parameter - * @interrupt: called from atomic? - * - * This is data entry for lower layers. - */ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) { struct hid_report_enum *report_enum = hid->report_enum + type; - struct hid_driver *hdrv = hid->driver; struct hid_report *report; - unsigned int i; - int ret; + int n, rsize, i; - if (!hid || !hid->driver) + if (!hid) return -ENODEV; if (!size) { @@ -1091,626 +962,58 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); - report = hid_get_report(report_enum, data); - if (!report) - return -1; + n = 0; /* Normally report number is 0 */ + if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ + n = *data++; + size--; + } /* dump the report */ - dbg_hid("report %d (size %u) = ", report->id, size); + dbg_hid("report %d (size %u) = ", n, size); for (i = 0; i < size; i++) dbg_hid_line(" %02x", data[i]); dbg_hid_line("\n"); - if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { - ret = hdrv->raw_event(hid, report, data, size); - if (ret != 0) - return ret < 0 ? ret : 0; - } - - hid_report_raw_event(hid, type, data, size, interrupt); - - return 0; -} -EXPORT_SYMBOL_GPL(hid_input_report); - -static bool hid_match_one_id(struct hid_device *hdev, - const struct hid_device_id *id) -{ - return id->bus == hdev->bus && - (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && - (id->product == HID_ANY_ID || id->product == hdev->product); -} - -static const struct hid_device_id *hid_match_id(struct hid_device *hdev, - const struct hid_device_id *id) -{ - for (; id->bus; id++) - if (hid_match_one_id(hdev, id)) - return id; - - return NULL; -} - -static const struct hid_device_id hid_hiddev_list[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1) }, - { } -}; - -static bool hid_hiddev(struct hid_device *hdev) -{ - return !!hid_match_id(hdev, hid_hiddev_list); -} - -int hid_connect(struct hid_device *hdev, unsigned int connect_mask) -{ - static const char *types[] = { "Device", "Pointer", "Mouse", "Device", - "Joystick", "Gamepad", "Keyboard", "Keypad", - "Multi-Axis Controller" - }; - const char *type, *bus; - char buf[64]; - unsigned int i; - int len; - - if (hdev->bus != BUS_USB) - connect_mask &= ~HID_CONNECT_HIDDEV; - if (hid_hiddev(hdev)) - connect_mask |= HID_CONNECT_HIDDEV_FORCE; - - if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, - connect_mask & HID_CONNECT_HIDINPUT_FORCE)) - hdev->claimed |= HID_CLAIMED_INPUT; - if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && - !hdev->hiddev_connect(hdev, - connect_mask & HID_CONNECT_HIDDEV_FORCE)) - hdev->claimed |= HID_CLAIMED_HIDDEV; - if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) - hdev->claimed |= HID_CLAIMED_HIDRAW; - - if (!hdev->claimed) { - dev_err(&hdev->dev, "claimed by neither input, hiddev nor " - "hidraw\n"); - return -ENODEV; - } - - if ((hdev->claimed & HID_CLAIMED_INPUT) && - (connect_mask & HID_CONNECT_FF) && hdev->ff_init) - hdev->ff_init(hdev); - - len = 0; - if (hdev->claimed & HID_CLAIMED_INPUT) - len += sprintf(buf + len, "input"); - if (hdev->claimed & HID_CLAIMED_HIDDEV) - len += sprintf(buf + len, "%shiddev%d", len ? "," : "", - hdev->minor); - if (hdev->claimed & HID_CLAIMED_HIDRAW) - len += sprintf(buf + len, "%shidraw%d", len ? "," : "", - ((struct hidraw *)hdev->hidraw)->minor); - - type = "Device"; - for (i = 0; i < hdev->maxcollection; i++) { - struct hid_collection *col = &hdev->collection[i]; - if (col->type == HID_COLLECTION_APPLICATION && - (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (col->usage & 0xffff) < ARRAY_SIZE(types)) { - type = types[col->usage & 0xffff]; - break; - } - } - - switch (hdev->bus) { - case BUS_USB: - bus = "USB"; - break; - case BUS_BLUETOOTH: - bus = "BLUETOOTH"; - break; - default: - bus = ""; + if (!(report = report_enum->report_id_hash[n])) { + dbg_hid("undefined report_id %d received\n", n); + return -1; } - dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", - buf, bus, hdev->version >> 8, hdev->version & 0xff, - type, hdev->name, hdev->phys); - - return 0; -} -EXPORT_SYMBOL_GPL(hid_connect); - -static const struct hid_device_id hid_blacklist[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, - { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, - { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) }, - { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, - { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, - - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, - { } -}; - -static int hid_bus_match(struct device *dev, struct device_driver *drv) -{ - struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); - - if (!hid_match_id(hdev, hdrv->id_table)) - return 0; - - /* generic wants all non-blacklisted */ - if (!strncmp(hdrv->name, "generic-", 8)) - return !hid_match_id(hdev, hid_blacklist); - - return 1; -} + rsize = ((report->size - 1) >> 3) + 1; -static int hid_device_probe(struct device *dev) -{ - struct hid_driver *hdrv = container_of(dev->driver, - struct hid_driver, driver); - struct hid_device *hdev = container_of(dev, struct hid_device, dev); - const struct hid_device_id *id; - int ret = 0; - - if (!hdev->driver) { - id = hid_match_id(hdev, hdrv->id_table); - if (id == NULL) - return -ENODEV; - - hdev->driver = hdrv; - if (hdrv->probe) { - ret = hdrv->probe(hdev, id); - } else { /* default probe */ - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - } - if (ret) - hdev->driver = NULL; + if (size < rsize) { + dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize); + memset(data + size, 0, rsize - size); } - return ret; -} -static int hid_device_remove(struct device *dev) -{ - struct hid_device *hdev = container_of(dev, struct hid_device, dev); - struct hid_driver *hdrv = hdev->driver; - - if (hdrv) { - if (hdrv->remove) - hdrv->remove(hdev); - else /* default remove */ - hid_hw_stop(hdev); - hdev->driver = NULL; + if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) + hid->hiddev_report_event(hid, report); + if (hid->claimed & HID_CLAIMED_HIDRAW) { + /* numbered reports need to be passed with the report num */ + if (report_enum->numbered) + hidraw_report_event(hid, data - 1, size + 1); + else + hidraw_report_event(hid, data, size); } - return 0; -} - -static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct hid_device *hdev = container_of(dev, struct hid_device, dev); - - if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", - hdev->bus, hdev->vendor, hdev->product)) - return -ENOMEM; - - if (add_uevent_var(env, "HID_NAME=%s", hdev->name)) - return -ENOMEM; - - if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys)) - return -ENOMEM; - - if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) - return -ENOMEM; + for (n = 0; n < report->maxfield; n++) + hid_input_field(hid, report->field[n], data, interrupt); - if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", - hdev->bus, hdev->vendor, hdev->product)) - return -ENOMEM; + if (hid->claimed & HID_CLAIMED_INPUT) + hidinput_report_event(hid, report); return 0; } - -static struct bus_type hid_bus_type = { - .name = "hid", - .match = hid_bus_match, - .probe = hid_device_probe, - .remove = hid_device_remove, - .uevent = hid_uevent, -}; - -static const struct hid_device_id hid_ignore_list[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, - { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, - { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, - { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, - { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) }, - { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) }, - { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, - { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, - { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, - { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, - { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) }, - { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, - { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, - { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, - { } -}; - -static bool hid_ignore(struct hid_device *hdev) -{ - switch (hdev->vendor) { - case USB_VENDOR_ID_CODEMERCS: - /* ignore all Code Mercenaries IOWarrior devices */ - if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && - hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) - return true; - break; - case USB_VENDOR_ID_LOGITECH: - if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && - hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) - return true; - break; - } - - return !!hid_match_id(hdev, hid_ignore_list); -} - -int hid_add_device(struct hid_device *hdev) -{ - static atomic_t id = ATOMIC_INIT(0); - int ret; - - if (WARN_ON(hdev->status & HID_STAT_ADDED)) - return -EBUSY; - - /* we need to kill them here, otherwise they will stay allocated to - * wait for coming driver */ - if (hid_ignore(hdev)) - return -ENODEV; - - /* XXX hack, any other cleaner solution < 20 bus_id bytes? */ - sprintf(hdev->dev.bus_id, "%04X:%04X:%04X.%04X", hdev->bus, - hdev->vendor, hdev->product, atomic_inc_return(&id)); - - ret = device_add(&hdev->dev); - if (!ret) - hdev->status |= HID_STAT_ADDED; - - return ret; -} -EXPORT_SYMBOL_GPL(hid_add_device); - -/** - * hid_allocate_device - allocate new hid device descriptor - * - * Allocate and initialize hid device, so that hid_destroy_device might be - * used to free it. - * - * New hid_device pointer is returned on success, otherwise ERR_PTR encoded - * error value. - */ -struct hid_device *hid_allocate_device(void) -{ - struct hid_device *hdev; - unsigned int i; - int ret = -ENOMEM; - - hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); - if (hdev == NULL) - return ERR_PTR(ret); - - device_initialize(&hdev->dev); - hdev->dev.release = hid_device_release; - hdev->dev.bus = &hid_bus_type; - - hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, - sizeof(struct hid_collection), GFP_KERNEL); - if (hdev->collection == NULL) - goto err; - hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&hdev->report_enum[i].report_list); - - return hdev; -err: - put_device(&hdev->dev); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(hid_allocate_device); - -static void hid_remove_device(struct hid_device *hdev) -{ - if (hdev->status & HID_STAT_ADDED) { - device_del(&hdev->dev); - hdev->status &= ~HID_STAT_ADDED; - } -} - -/** - * hid_destroy_device - free previously allocated device - * - * @hdev: hid device - * - * If you allocate hid_device through hid_allocate_device, you should ever - * free by this function. - */ -void hid_destroy_device(struct hid_device *hdev) -{ - hid_remove_device(hdev); - put_device(&hdev->dev); -} -EXPORT_SYMBOL_GPL(hid_destroy_device); - -int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, - const char *mod_name) -{ - hdrv->driver.name = hdrv->name; - hdrv->driver.bus = &hid_bus_type; - hdrv->driver.owner = owner; - hdrv->driver.mod_name = mod_name; - - return driver_register(&hdrv->driver); -} -EXPORT_SYMBOL_GPL(__hid_register_driver); - -void hid_unregister_driver(struct hid_driver *hdrv) -{ - driver_unregister(&hdrv->driver); -} -EXPORT_SYMBOL_GPL(hid_unregister_driver); - -#ifdef CONFIG_HID_COMPAT -static void hid_compat_load(struct work_struct *ws) -{ - request_module("hid-dummy"); -} -static DECLARE_WORK(hid_compat_work, hid_compat_load); -static struct workqueue_struct *hid_compat_wq; -#endif +EXPORT_SYMBOL_GPL(hid_input_report); static int __init hid_init(void) { - int ret; - - ret = bus_register(&hid_bus_type); - if (ret) { - printk(KERN_ERR "HID: can't register hid bus\n"); - goto err; - } - - ret = hidraw_init(); - if (ret) - goto err_bus; - -#ifdef CONFIG_HID_COMPAT - hid_compat_wq = create_workqueue("hid_compat"); - if (!hid_compat_wq) { - hidraw_exit(); - goto err; - } - queue_work(hid_compat_wq, &hid_compat_work); -#endif - - return 0; -err_bus: - bus_unregister(&hid_bus_type); -err: - return ret; + return hidraw_init(); } static void __exit hid_exit(void) { -#ifdef CONFIG_HID_COMPAT - destroy_workqueue(hid_compat_wq); -#endif hidraw_exit(); - bus_unregister(&hid_bus_type); } module_init(hid_init); diff --git a/trunk/drivers/hid/hid-cypress.c b/trunk/drivers/hid/hid-cypress.c deleted file mode 100644 index 5d69d27b935d..000000000000 --- a/trunk/drivers/hid/hid-cypress.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * HID driver for some cypress "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define CP_RDESC_SWAPPED_MIN_MAX 0x01 -#define CP_2WHEEL_MOUSE_HACK 0x02 -#define CP_2WHEEL_MOUSE_HACK_ON 0x04 - -/* - * Some USB barcode readers from cypress have usage min and usage max in - * the wrong order - */ -static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - unsigned int i; - - if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) - return; - - for (i = 0; i < rsize - 4; i++) - if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) { - __u8 tmp; - - rdesc[i] = 0x19; - rdesc[i + 2] = 0x29; - tmp = rdesc[i + 3]; - rdesc[i + 3] = rdesc[i + 1]; - rdesc[i + 1] = tmp; - } -} - -static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if (!(quirks & CP_2WHEEL_MOUSE_HACK)) - return 0; - - if (usage->type == EV_REL && usage->code == REL_WHEEL) - set_bit(REL_HWHEEL, *bit); - if (usage->hid == 0x00090005) - return -1; - - return 0; -} - -static int cp_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || - !usage->type || !(quirks & CP_2WHEEL_MOUSE_HACK)) - return 0; - - if (usage->hid == 0x00090005) { - if (value) - quirks |= CP_2WHEEL_MOUSE_HACK_ON; - else - quirks &= ~CP_2WHEEL_MOUSE_HACK_ON; - hid_set_drvdata(hdev, (void *)quirks); - return 1; - } - - if (usage->code == REL_WHEEL && (quirks & CP_2WHEEL_MOUSE_HACK_ON)) { - struct input_dev *input = field->hidinput->input; - - input_event(input, usage->type, REL_HWHEEL, value); - return 1; - } - - return 0; -} - -static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - unsigned long quirks = id->driver_data; - int ret; - - hid_set_drvdata(hdev, (void *)quirks); - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id cp_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1), - .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2), - .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, - { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), - .driver_data = CP_2WHEEL_MOUSE_HACK }, - { } -}; -MODULE_DEVICE_TABLE(hid, cp_devices); - -static struct hid_driver cp_driver = { - .name = "cypress", - .id_table = cp_devices, - .report_fixup = cp_report_fixup, - .input_mapped = cp_input_mapped, - .event = cp_event, - .probe = cp_probe, -}; - -static int cp_init(void) -{ - return hid_register_driver(&cp_driver); -} - -static void cp_exit(void) -{ - hid_unregister_driver(&cp_driver); -} - -module_init(cp_init); -module_exit(cp_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(cypress); diff --git a/trunk/drivers/hid/hid-dell.c b/trunk/drivers/hid/hid-dell.c deleted file mode 100644 index 1a0d0dfc62fc..000000000000 --- a/trunk/drivers/hid/hid-dell.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * HID driver for some dell "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - usbhid_set_leds(hdev); - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id dell_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) }, - { } -}; -MODULE_DEVICE_TABLE(hid, dell_devices); - -static struct hid_driver dell_driver = { - .name = "dell", - .id_table = dell_devices, - .probe = dell_probe, -}; - -static int dell_init(void) -{ - return hid_register_driver(&dell_driver); -} - -static void dell_exit(void) -{ - hid_unregister_driver(&dell_driver); -} - -module_init(dell_init); -module_exit(dell_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(dell); diff --git a/trunk/drivers/hid/hid-dummy.c b/trunk/drivers/hid/hid-dummy.c deleted file mode 100644 index e148f86fb58e..000000000000 --- a/trunk/drivers/hid/hid-dummy.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include - -static int __init hid_dummy_init(void) -{ -#ifdef CONFIG_HID_A4TECH_MODULE - HID_COMPAT_CALL_DRIVER(a4tech); -#endif -#ifdef CONFIG_HID_APPLE_MODULE - HID_COMPAT_CALL_DRIVER(apple); -#endif -#ifdef CONFIG_HID_BELKIN_MODULE - HID_COMPAT_CALL_DRIVER(belkin); -#endif -#ifdef CONFIG_HID_BRIGHT_MODULE - HID_COMPAT_CALL_DRIVER(bright); -#endif -#ifdef CONFIG_HID_CHERRY_MODULE - HID_COMPAT_CALL_DRIVER(cherry); -#endif -#ifdef CONFIG_HID_CHICONY_MODULE - HID_COMPAT_CALL_DRIVER(chicony); -#endif -#ifdef CONFIG_HID_CYPRESS_MODULE - HID_COMPAT_CALL_DRIVER(cypress); -#endif -#ifdef CONFIG_HID_DELL_MODULE - HID_COMPAT_CALL_DRIVER(dell); -#endif -#ifdef CONFIG_HID_EZKEY_MODULE - HID_COMPAT_CALL_DRIVER(ezkey); -#endif -#ifdef CONFIG_HID_GYRATION_MODULE - HID_COMPAT_CALL_DRIVER(gyration); -#endif -#ifdef CONFIG_HID_LOGITECH_MODULE - HID_COMPAT_CALL_DRIVER(logitech); -#endif -#ifdef CONFIG_HID_MICROSOFT_MODULE - HID_COMPAT_CALL_DRIVER(microsoft); -#endif -#ifdef CONFIG_HID_MONTEREY_MODULE - HID_COMPAT_CALL_DRIVER(monterey); -#endif -#ifdef CONFIG_HID_PANTHERLORD_MODULE - HID_COMPAT_CALL_DRIVER(pantherlord); -#endif -#ifdef CONFIG_HID_PETALYNX_MODULE - HID_COMPAT_CALL_DRIVER(petalynx); -#endif -#ifdef CONFIG_HID_SAMSUNG_MODULE - HID_COMPAT_CALL_DRIVER(samsung); -#endif -#ifdef CONFIG_HID_SONY_MODULE - HID_COMPAT_CALL_DRIVER(sony); -#endif -#ifdef CONFIG_HID_SUNPLUS_MODULE - HID_COMPAT_CALL_DRIVER(sunplus); -#endif -#ifdef CONFIG_THRUSTMASTER_FF_MODULE - HID_COMPAT_CALL_DRIVER(thrustmaster); -#endif -#ifdef CONFIG_ZEROPLUS_FF_MODULE - HID_COMPAT_CALL_DRIVER(zeroplus); -#endif - - return -EIO; -} -module_init(hid_dummy_init); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hid/hid-ezkey.c b/trunk/drivers/hid/hid-ezkey.c deleted file mode 100644 index deb42f931b7e..000000000000 --- a/trunk/drivers/hid/hid-ezkey.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * HID driver for some ezkey "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define ez_map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c)) -#define ez_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c)) - -static int ez_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) - return 0; - - switch (usage->hid & HID_USAGE) { - case 0x230: ez_map_key(BTN_MOUSE); break; - case 0x231: ez_map_rel(REL_WHEEL); break; - /* - * this keyboard has a scrollwheel implemented in - * totally broken way. We map this usage temporarily - * to HWHEEL and handle it in the event quirk handler - */ - case 0x232: ez_map_rel(REL_HWHEEL); break; - default: - return 0; - } - return 1; -} - -static int ez_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || - !usage->type) - return 0; - - /* handle the temporary quirky mapping to HWHEEL */ - if (usage->type == EV_REL && usage->code == REL_HWHEEL) { - struct input_dev *input = field->hidinput->input; - input_event(input, usage->type, REL_WHEEL, -value); - return 1; - } - - return 0; -} - -static const struct hid_device_id ez_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, - { } -}; -MODULE_DEVICE_TABLE(hid, ez_devices); - -static struct hid_driver ez_driver = { - .name = "ezkey", - .id_table = ez_devices, - .input_mapping = ez_input_mapping, - .event = ez_event, -}; - -static int ez_init(void) -{ - return hid_register_driver(&ez_driver); -} - -static void ez_exit(void) -{ - hid_unregister_driver(&ez_driver); -} - -module_init(ez_init); -module_exit(ez_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(ezkey); diff --git a/trunk/drivers/hid/hid-gyration.c b/trunk/drivers/hid/hid-gyration.c deleted file mode 100644 index ac5120f542cc..000000000000 --- a/trunk/drivers/hid/hid-gyration.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * HID driver for some gyration "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define gy_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) - return 0; - - set_bit(EV_REP, hi->input->evbit); - switch (usage->hid & HID_USAGE) { - /* Reported on Gyration MCE Remote */ - case 0x00d: gy_map_key_clear(KEY_HOME); break; - case 0x024: gy_map_key_clear(KEY_DVD); break; - case 0x025: gy_map_key_clear(KEY_PVR); break; - case 0x046: gy_map_key_clear(KEY_MEDIA); break; - case 0x047: gy_map_key_clear(KEY_MP3); break; - case 0x049: gy_map_key_clear(KEY_CAMERA); break; - case 0x04a: gy_map_key_clear(KEY_VIDEO); break; - - default: - return 0; - } - return 1; -} - -static int gyration_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct input_dev *input = field->hidinput->input; - - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && - (usage->hid & 0xff) == 0x82) { - input_event(input, usage->type, usage->code, 1); - input_sync(input); - input_event(input, usage->type, usage->code, 0); - input_sync(input); - return 1; - } - - return 0; -} - -static const struct hid_device_id gyration_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, - { } -}; -MODULE_DEVICE_TABLE(hid, gyration_devices); - -static struct hid_driver gyration_driver = { - .name = "gyration", - .id_table = gyration_devices, - .input_mapping = gyration_input_mapping, - .event = gyration_event, -}; - -static int gyration_init(void) -{ - return hid_register_driver(&gyration_driver); -} - -static void gyration_exit(void) -{ - hid_unregister_driver(&gyration_driver); -} - -module_init(gyration_init); -module_exit(gyration_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(gyration); diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h deleted file mode 100644 index d9a1ba920c23..000000000000 --- a/trunk/drivers/hid/hid-ids.h +++ /dev/null @@ -1,406 +0,0 @@ -/* - * USB HID quirks support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#ifndef HID_IDS_H_FILE -#define HID_IDS_H_FILE - -#define USB_VENDOR_ID_A4TECH 0x09da -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 -#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a - -#define USB_VENDOR_ID_AASHIMA 0x06d6 -#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 -#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 - -#define USB_VENDOR_ID_ACECAD 0x0460 -#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 -#define USB_DEVICE_ID_ACECAD_302 0x0008 - -#define USB_VENDOR_ID_ADS_TECH 0x06e1 -#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 - -#define USB_VENDOR_ID_AFATECH 0x15a4 -#define USB_DEVICE_ID_AFATECH_AF9016 0x9016 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_AIRCABLE 0x16CA -#define USB_DEVICE_ID_AIRCABLE1 0x1502 - -#define USB_VENDOR_ID_ALCOR 0x058f -#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_APPLE 0x05ac -#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 -#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e -#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f -#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 -#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 -#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 -#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 -#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 -#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 -#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a -#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b -#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c -#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 -#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 -#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 -#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 -#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 -#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 -#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 -#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a -#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e -#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 -#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 -#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 -#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a -#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b -#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 -#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 - -#define USB_VENDOR_ID_ASUS 0x0b05 -#define USB_DEVICE_ID_ASUS_LCM 0x1726 - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_AVERMEDIA 0x07ca -#define USB_DEVICE_ID_AVER_FM_MR800 0xb800 - -#define USB_VENDOR_ID_BELKIN 0x050d -#define USB_DEVICE_ID_FLIP_KVM 0x3201 - -#define USB_VENDOR_ID_BRIGHT 0x1241 -#define USB_DEVICE_ID_BRIGHT_ABNT2 0x1503 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_CHERRY 0x046a -#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_CHICONY 0x04f2 -#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 - -#define USB_VENDOR_ID_CIDC 0x1677 - -#define USB_VENDOR_ID_CMEDIA 0x0d8c -#define USB_DEVICE_ID_CM109 0x000e - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff - -#define USB_VENDOR_ID_CYGNAL 0x10c4 -#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 -#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 -#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 -#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 - -#define USB_VENDOR_ID_DELL 0x413c -#define USB_DEVICE_ID_DELL_W7658 0x2005 -#define USB_DEVICE_ID_DELL_SK8115 0x2105 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 - -#define USB_VENDOR_ID_DMI 0x0c0b -#define USB_DEVICE_ID_DMI_ENC 0x5fab - -#define USB_VENDOR_ID_ELO 0x04E7 -#define USB_DEVICE_ID_ELO_TS2700 0x0020 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_EZKEY 0x0518 -#define USB_DEVICE_ID_BTC_8193 0x0002 - -#define USB_VENDOR_ID_GAMERON 0x0810 -#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 - -#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 -#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 - -#define USB_VENDOR_ID_GOTOP 0x08f2 -#define USB_DEVICE_ID_SUPER_Q2 0x007f -#define USB_DEVICE_ID_GOGOPEN 0x00ce -#define USB_DEVICE_ID_PENPOWER 0x00f4 - -#define USB_VENDOR_ID_GREENASIA 0x0e8f - -#define USB_VENDOR_ID_GRETAGMACBETH 0x0971 -#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_GTCO 0x078c -#define USB_DEVICE_ID_GTCO_90 0x0090 -#define USB_DEVICE_ID_GTCO_100 0x0100 -#define USB_DEVICE_ID_GTCO_101 0x0101 -#define USB_DEVICE_ID_GTCO_103 0x0103 -#define USB_DEVICE_ID_GTCO_104 0x0104 -#define USB_DEVICE_ID_GTCO_105 0x0105 -#define USB_DEVICE_ID_GTCO_106 0x0106 -#define USB_DEVICE_ID_GTCO_107 0x0107 -#define USB_DEVICE_ID_GTCO_108 0x0108 -#define USB_DEVICE_ID_GTCO_200 0x0200 -#define USB_DEVICE_ID_GTCO_201 0x0201 -#define USB_DEVICE_ID_GTCO_202 0x0202 -#define USB_DEVICE_ID_GTCO_203 0x0203 -#define USB_DEVICE_ID_GTCO_204 0x0204 -#define USB_DEVICE_ID_GTCO_205 0x0205 -#define USB_DEVICE_ID_GTCO_206 0x0206 -#define USB_DEVICE_ID_GTCO_207 0x0207 -#define USB_DEVICE_ID_GTCO_300 0x0300 -#define USB_DEVICE_ID_GTCO_301 0x0301 -#define USB_DEVICE_ID_GTCO_302 0x0302 -#define USB_DEVICE_ID_GTCO_303 0x0303 -#define USB_DEVICE_ID_GTCO_304 0x0304 -#define USB_DEVICE_ID_GTCO_305 0x0305 -#define USB_DEVICE_ID_GTCO_306 0x0306 -#define USB_DEVICE_ID_GTCO_307 0x0307 -#define USB_DEVICE_ID_GTCO_308 0x0308 -#define USB_DEVICE_ID_GTCO_309 0x0309 -#define USB_DEVICE_ID_GTCO_400 0x0400 -#define USB_DEVICE_ID_GTCO_401 0x0401 -#define USB_DEVICE_ID_GTCO_402 0x0402 -#define USB_DEVICE_ID_GTCO_403 0x0403 -#define USB_DEVICE_ID_GTCO_404 0x0404 -#define USB_DEVICE_ID_GTCO_405 0x0405 -#define USB_DEVICE_ID_GTCO_500 0x0500 -#define USB_DEVICE_ID_GTCO_501 0x0501 -#define USB_DEVICE_ID_GTCO_502 0x0502 -#define USB_DEVICE_ID_GTCO_503 0x0503 -#define USB_DEVICE_ID_GTCO_504 0x0504 -#define USB_DEVICE_ID_GTCO_1000 0x1000 -#define USB_DEVICE_ID_GTCO_1001 0x1001 -#define USB_DEVICE_ID_GTCO_1002 0x1002 -#define USB_DEVICE_ID_GTCO_1003 0x1003 -#define USB_DEVICE_ID_GTCO_1004 0x1004 -#define USB_DEVICE_ID_GTCO_1005 0x1005 -#define USB_DEVICE_ID_GTCO_1006 0x1006 -#define USB_DEVICE_ID_GTCO_1007 0x1007 - -#define USB_VENDOR_ID_GYRATION 0x0c16 -#define USB_DEVICE_ID_GYRATION_REMOTE 0x0002 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_IMATION 0x0718 -#define USB_DEVICE_ID_DISC_STAKKA 0xd000 - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_LABTEC 0x1020 -#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 - -#define USB_VENDOR_ID_LD 0x0f11 -#define USB_DEVICE_ID_LD_CASSY 0x1000 -#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 -#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 -#define USB_DEVICE_ID_LD_JWM 0x1080 -#define USB_DEVICE_ID_LD_DMMP 0x1081 -#define USB_DEVICE_ID_LD_UMIP 0x1090 -#define USB_DEVICE_ID_LD_XRAY1 0x1100 -#define USB_DEVICE_ID_LD_XRAY2 0x1101 -#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 -#define USB_DEVICE_ID_LD_COM3LAB 0x2000 -#define USB_DEVICE_ID_LD_TELEPORT 0x2010 -#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 -#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 -#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 - -#define USB_VENDOR_ID_LOGITECH 0x046d -#define USB_DEVICE_ID_LOGITECH_LX3 0xc044 -#define USB_DEVICE_ID_LOGITECH_V150 0xc047 -#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 -#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 -#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f -#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 -#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 -#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 -#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 -#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 -#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 -#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 -#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 -#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a -#define USB_DEVICE_ID_LOGITECH_KBD 0xc311 -#define USB_DEVICE_ID_S510_RECEIVER 0xc50c -#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 -#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 -#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 -#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 -#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 -#define USB_DEVICE_ID_DINOVO_MINI 0xc71f -#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 - -#define USB_VENDOR_ID_MCC 0x09db -#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 -#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_MICROCHIP 0x04d8 -#define USB_DEVICE_ID_PICKIT1 0x0032 -#define USB_DEVICE_ID_PICKIT2 0x0033 - -#define USB_VENDOR_ID_MICROSOFT 0x045e -#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b -#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d -#define USB_DEVICE_ID_MS_NE4K 0x00db -#define USB_DEVICE_ID_MS_LK6K 0x00f9 -#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 -#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 - - -#define USB_VENDOR_ID_MONTEREY 0x0566 -#define USB_DEVICE_ID_GENIUS_KB29E 0x3004 - -#define USB_VENDOR_ID_NCR 0x0404 -#define USB_DEVICE_ID_NCR_FIRST 0x0300 -#define USB_DEVICE_ID_NCR_LAST 0x03ff - -#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 -#define USB_DEVICE_ID_N_S_HARMONY 0xc359 - -#define USB_VENDOR_ID_NATSU 0x08b7 -#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_PANJIT 0x134c - -#define USB_VENDOR_ID_PANTHERLORD 0x0810 -#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 - -#define USB_VENDOR_ID_PETALYNX 0x18b1 -#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 - -#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 -#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_SAMSUNG 0x0419 -#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 - -#define USB_VENDOR_ID_SONY 0x054c -#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 - -#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 -#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 -#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036 -#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034 - -#define USB_VENDOR_ID_SUN 0x0430 -#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab - -#define USB_VENDOR_ID_SUNPLUS 0x04fc -#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 - -#define USB_VENDOR_ID_TENX 0x1130 -#define USB_DEVICE_ID_TENX_IBUDDY1 0x0001 -#define USB_DEVICE_ID_TENX_IBUDDY2 0x0002 - -#define USB_VENDOR_ID_THRUSTMASTER 0x044f - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_TURBOX 0x062a -#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 - -#define USB_VENDOR_ID_VERNIER 0x08f7 -#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 -#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 -#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 -#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 -#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201 -#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800 -#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 - -#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666 -#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 -#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 - -#define USB_VENDOR_ID_YEALINK 0x6993 -#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 - -#define USB_VENDOR_ID_ZEROPLUS 0x0c12 - -#define USB_VENDOR_ID_KYE 0x0458 -#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 - -#endif diff --git a/trunk/drivers/hid/hid-input-quirks.c b/trunk/drivers/hid/hid-input-quirks.c new file mode 100644 index 000000000000..16feea014494 --- /dev/null +++ b/trunk/drivers/hid/hid-input-quirks.c @@ -0,0 +1,484 @@ +/* + * HID-input usage mapping quirks + * + * This is used to handle HID-input mappings for devices violating + * HUT 1.12 specification. + * + * Copyright (c) 2007-2008 Jiri Kosina + */ + +/* + * 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 + */ + +#include +#include + +#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0) +#define map_rel(c) do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0) +#define map_key(c) do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0) +#define map_led(c) do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } while (0) + +#define map_abs_clear(c) do { map_abs(c); clear_bit(c, *bit); } while (0) +#define map_key_clear(c) do { map_key(c); clear_bit(c, *bit); } while (0) + +static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x03a: map_key_clear(KEY_SOUND); break; + case 0x03b: map_key_clear(KEY_CAMERA); break; + case 0x03c: map_key_clear(KEY_DOCUMENTS); break; + default: + return 0; + } + return 1; +} + +static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x301: map_key_clear(KEY_PROG1); break; + case 0x302: map_key_clear(KEY_PROG2); break; + case 0x303: map_key_clear(KEY_PROG3); break; + default: + return 0; + } + return 1; +} + +static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) + return 0; + + set_bit(EV_REP, input->evbit); + switch(usage->hid & HID_USAGE) { + /* Reported on Logitech Ultra X Media Remote */ + case 0x004: map_key_clear(KEY_AGAIN); break; + case 0x00d: map_key_clear(KEY_HOME); break; + case 0x024: map_key_clear(KEY_SHUFFLE); break; + case 0x025: map_key_clear(KEY_TV); break; + case 0x026: map_key_clear(KEY_MENU); break; + case 0x031: map_key_clear(KEY_AUDIO); break; + case 0x032: map_key_clear(KEY_TEXT); break; + case 0x033: map_key_clear(KEY_LAST); break; + case 0x047: map_key_clear(KEY_MP3); break; + case 0x048: map_key_clear(KEY_DVD); break; + case 0x049: map_key_clear(KEY_MEDIA); break; + case 0x04a: map_key_clear(KEY_VIDEO); break; + case 0x04b: map_key_clear(KEY_ANGLE); break; + case 0x04c: map_key_clear(KEY_LANGUAGE); break; + case 0x04d: map_key_clear(KEY_SUBTITLE); break; + case 0x051: map_key_clear(KEY_RED); break; + case 0x052: map_key_clear(KEY_CLOSE); break; + + default: + return 0; + } + return 1; +} + +static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) + return 0; + + set_bit(EV_REP, input->evbit); + switch(usage->hid & HID_USAGE) { + /* Reported on Gyration MCE Remote */ + case 0x00d: map_key_clear(KEY_HOME); break; + case 0x024: map_key_clear(KEY_DVD); break; + case 0x025: map_key_clear(KEY_PVR); break; + case 0x046: map_key_clear(KEY_MEDIA); break; + case 0x047: map_key_clear(KEY_MP3); break; + case 0x049: map_key_clear(KEY_CAMERA); break; + case 0x04a: map_key_clear(KEY_VIDEO); break; + + default: + return 0; + } + return 1; +} + +static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) + return 0; + + set_bit(EV_REP, input->evbit); + switch (usage->hid & HID_USAGE) { + case 0xff01: map_key_clear(BTN_1); break; + case 0xff02: map_key_clear(BTN_2); break; + case 0xff03: map_key_clear(BTN_3); break; + case 0xff04: map_key_clear(BTN_4); break; + case 0xff05: map_key_clear(BTN_5); break; + case 0xff06: map_key_clear(BTN_6); break; + case 0xff07: map_key_clear(BTN_7); break; + case 0xff08: map_key_clear(BTN_8); break; + case 0xff09: map_key_clear(BTN_9); break; + case 0xff0a: map_key_clear(BTN_A); break; + case 0xff0b: map_key_clear(BTN_B); break; + default: + return 0; + } + return 1; +} + +static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) + return 0; + + switch(usage->hid & HID_USAGE) { + case 0xfd06: map_key_clear(KEY_CHAT); break; + case 0xfd07: map_key_clear(KEY_PHONE); break; + case 0xff05: + set_bit(EV_REP, input->evbit); + map_key_clear(KEY_F13); + set_bit(KEY_F14, input->keybit); + set_bit(KEY_F15, input->keybit); + set_bit(KEY_F16, input->keybit); + set_bit(KEY_F17, input->keybit); + set_bit(KEY_F18, input->keybit); + default: + return 0; + } + return 1; +} + +static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) + return 0; + + set_bit(EV_REP, input->evbit); + switch(usage->hid & HID_USAGE) { + case 0xfd08: map_key_clear(KEY_FORWARD); break; + case 0xfd09: map_key_clear(KEY_BACK); break; + case 0xfd0b: map_key_clear(KEY_PLAYPAUSE); break; + case 0xfd0e: map_key_clear(KEY_CLOSE); break; + case 0xfd0f: map_key_clear(KEY_PLAY); break; + default: + return 0; + } + return 1; +} + +static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) && + ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)) + return 0; + + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) + switch(usage->hid & HID_USAGE) { + case 0x05a: map_key_clear(KEY_TEXT); break; + case 0x05b: map_key_clear(KEY_RED); break; + case 0x05c: map_key_clear(KEY_GREEN); break; + case 0x05d: map_key_clear(KEY_YELLOW); break; + case 0x05e: map_key_clear(KEY_BLUE); break; + default: + return 0; + } + + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) + switch(usage->hid & HID_USAGE) { + case 0x0f6: map_key_clear(KEY_NEXT); break; + case 0x0fa: map_key_clear(KEY_BACK); break; + default: + return 0; + } + return 1; +} + +static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x1001: map_key_clear(KEY_MESSENGER); break; + case 0x1003: map_key_clear(KEY_SOUND); break; + case 0x1004: map_key_clear(KEY_VIDEO); break; + case 0x1005: map_key_clear(KEY_AUDIO); break; + case 0x100a: map_key_clear(KEY_DOCUMENTS); break; + case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; + case 0x1012: map_key_clear(KEY_NEXTSONG); break; + case 0x1013: map_key_clear(KEY_CAMERA); break; + case 0x1014: map_key_clear(KEY_MESSENGER); break; + case 0x1015: map_key_clear(KEY_RECORD); break; + case 0x1016: map_key_clear(KEY_PLAYER); break; + case 0x1017: map_key_clear(KEY_EJECTCD); break; + case 0x1018: map_key_clear(KEY_MEDIA); break; + case 0x1019: map_key_clear(KEY_PROG1); break; + case 0x101a: map_key_clear(KEY_PROG2); break; + case 0x101b: map_key_clear(KEY_PROG3); break; + case 0x101f: map_key_clear(KEY_ZOOMIN); break; + case 0x1020: map_key_clear(KEY_ZOOMOUT); break; + case 0x1021: map_key_clear(KEY_ZOOMRESET); break; + case 0x1023: map_key_clear(KEY_CLOSE); break; + case 0x1027: map_key_clear(KEY_MENU); break; + /* this one is marked as 'Rotate' */ + case 0x1028: map_key_clear(KEY_ANGLE); break; + case 0x1029: map_key_clear(KEY_SHUFFLE); break; + case 0x102a: map_key_clear(KEY_BACK); break; + case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; + case 0x1041: map_key_clear(KEY_BATTERY); break; + case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; + case 0x1043: map_key_clear(KEY_SPREADSHEET); break; + case 0x1044: map_key_clear(KEY_PRESENTATION); break; + case 0x1045: map_key_clear(KEY_UNDO); break; + case 0x1046: map_key_clear(KEY_REDO); break; + case 0x1047: map_key_clear(KEY_PRINT); break; + case 0x1048: map_key_clear(KEY_SAVE); break; + case 0x1049: map_key_clear(KEY_PROG1); break; + case 0x104a: map_key_clear(KEY_PROG2); break; + case 0x104b: map_key_clear(KEY_PROG3); break; + case 0x104c: map_key_clear(KEY_PROG4); break; + + default: + return 0; + } + return 1; +} + +static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x156: map_key_clear(KEY_WORDPROCESSOR); break; + case 0x157: map_key_clear(KEY_SPREADSHEET); break; + case 0x158: map_key_clear(KEY_PRESENTATION); break; + case 0x15c: map_key_clear(KEY_STOP); break; + + default: + return 0; + } + return 1; +} + +static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x230: map_key(BTN_MOUSE); break; + case 0x231: map_rel(REL_WHEEL); break; + /* + * this keyboard has a scrollwheel implemented in + * totally broken way. We map this usage temporarily + * to HWHEEL and handle it in the event quirk handler + */ + case 0x232: map_rel(REL_HWHEEL); break; + + default: + return 0; + } + return 1; +} + +static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *input, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x2003: map_key_clear(KEY_ZOOMIN); break; + case 0x2103: map_key_clear(KEY_ZOOMOUT); break; + default: + return 0; + } + return 1; +} + +#define VENDOR_ID_BELKIN 0x1020 +#define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006 + +#define VENDOR_ID_CHERRY 0x046a +#define DEVICE_ID_CHERRY_CYMOTION 0x0023 + +#define VENDOR_ID_CHICONY 0x04f2 +#define DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 + +#define VENDOR_ID_EZKEY 0x0518 +#define DEVICE_ID_BTC_8193 0x0002 + +#define VENDOR_ID_GYRATION 0x0c16 +#define DEVICE_ID_GYRATION_REMOTE 0x0002 + +#define VENDOR_ID_LOGITECH 0x046d +#define DEVICE_ID_LOGITECH_RECEIVER 0xc101 +#define DEVICE_ID_S510_RECEIVER 0xc50c +#define DEVICE_ID_S510_RECEIVER_2 0xc517 +#define DEVICE_ID_MX3000_RECEIVER 0xc513 + +#define VENDOR_ID_MICROSOFT 0x045e +#define DEVICE_ID_MS4K 0x00db +#define DEVICE_ID_MS6K 0x00f9 +#define DEVICE_IS_MS_PRESENTER_8K_BT 0x0701 +#define DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 + +#define VENDOR_ID_MONTEREY 0x0566 +#define DEVICE_ID_GENIUS_KB29E 0x3004 + +#define VENDOR_ID_PETALYNX 0x18b1 +#define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 + +#define VENDOR_ID_SUNPLUS 0x04fc +#define DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 + +static const struct hid_input_blacklist { + __u16 idVendor; + __u16 idProduct; + int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *); +} hid_input_blacklist[] = { + { VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd }, + + { VENDOR_ID_CHERRY, DEVICE_ID_CHERRY_CYMOTION, quirk_cherry_cymotion }, + + { VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad }, + + { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, + + { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote }, + + { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote }, + { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless }, + { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless }, + { VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless }, + + { VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb }, + { VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb }, + { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k }, + { VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k }, + + { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e }, + + { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote }, + + { VENDOR_ID_SUNPLUS, DEVICE_ID_SUNPLUS_WDESKTOP, quirk_sunplus_wdesktop }, + + { 0, 0, NULL } +}; + +int hidinput_mapping_quirks(struct hid_usage *usage, + struct input_dev *input, + unsigned long **bit, int *max) +{ + struct hid_device *device = input_get_drvdata(input); + int i = 0; + + while (hid_input_blacklist[i].quirk) { + if (hid_input_blacklist[i].idVendor == device->vendor && + hid_input_blacklist[i].idProduct == device->product) + return hid_input_blacklist[i].quirk(usage, input, bit, max); + i++; + } + return 0; +} + +int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) +{ + struct input_dev *input; + + input = field->hidinput->input; + + if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) + || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { + if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; + else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; + return 1; + } + + if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && + (usage->type == EV_REL) && + (usage->code == REL_WHEEL)) { + hid->delayed_value = value; + return 1; + } + + if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && + (usage->hid == 0x000100b8)) { + input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); + return 1; + } + + if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { + input_event(input, usage->type, usage->code, -value); + return 1; + } + + if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { + input_event(input, usage->type, REL_HWHEEL, value); + return 1; + } + + if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) + return 1; + + /* Handling MS keyboards special buttons */ + if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS && + usage->hid == (HID_UP_MSVENDOR | 0xff05)) { + int key = 0; + static int last_key = 0; + switch (value) { + case 0x01: key = KEY_F14; break; + case 0x02: key = KEY_F15; break; + case 0x04: key = KEY_F16; break; + case 0x08: key = KEY_F17; break; + case 0x10: key = KEY_F18; break; + default: break; + } + if (key) { + input_event(input, usage->type, key, 1); + last_key = key; + } else { + input_event(input, usage->type, last_key, 0); + } + } + + /* handle the temporary quirky mapping to HWHEEL */ + if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && + usage->type == EV_REL && usage->code == REL_HWHEEL) { + input_event(input, usage->type, REL_WHEEL, -value); + return 1; + } + + /* Gyration MCE remote "Sleep" key */ + if (hid->vendor == VENDOR_ID_GYRATION && + hid->product == DEVICE_ID_GYRATION_REMOTE && + (usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && + (usage->hid & 0xff) == 0x82) { + input_event(input, usage->type, usage->code, 1); + input_sync(input); + input_event(input, usage->type, usage->code, 0); + input_sync(input); + return 1; + } + return 0; +} + + diff --git a/trunk/drivers/hid/hid-input.c b/trunk/drivers/hid/hid-input.c index 7f183b7147e1..1b2e8dc3398d 100644 --- a/trunk/drivers/hid/hid-input.c +++ b/trunk/drivers/hid/hid-input.c @@ -32,6 +32,11 @@ #include #include +static int hid_apple_fnmode = 1; +module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644); +MODULE_PARM_DESC(pb_fnmode, + "Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); + #define unk KEY_UNKNOWN static const unsigned char hid_keyboard[256] = { @@ -53,20 +58,227 @@ static const unsigned char hid_keyboard[256] = { 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk }; +/* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */ +#define LOGITECH_EXPANDED_KEYMAP_SIZE 80 +static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = { + 0,216, 0,213,175,156, 0, 0, 0, 0, + 144, 0, 0, 0, 0, 0, 0, 0, 0,212, + 174,167,152,161,112, 0, 0, 0,154, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,183,184,185,186,187, + 188,189,190,191,192,193,194, 0, 0, 0 +}; + static const struct { __s32 x; __s32 y; } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; -#define map_abs(c) hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c)) -#define map_rel(c) hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c)) -#define map_key(c) hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c)) -#define map_led(c) hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c)) +#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0) +#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0) +#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0) +#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0) + +#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) +#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) + +#ifdef CONFIG_USB_HIDINPUT_POWERBOOK + +struct hidinput_key_translation { + u16 from; + u16 to; + u8 flags; +}; + +#define APPLE_FLAG_FKEY 0x01 + +static struct hidinput_key_translation apple_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ + { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ + { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, + { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, + { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_UP, KEY_PAGEUP }, + { KEY_DOWN, KEY_PAGEDOWN }, + { KEY_LEFT, KEY_HOME }, + { KEY_RIGHT, KEY_END }, + { } +}; + +static struct hidinput_key_translation powerbook_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, + { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, + { KEY_UP, KEY_PAGEUP }, + { KEY_DOWN, KEY_PAGEDOWN }, + { KEY_LEFT, KEY_HOME }, + { KEY_RIGHT, KEY_END }, + { } +}; + +static struct hidinput_key_translation powerbook_numlock_keys[] = { + { KEY_J, KEY_KP1 }, + { KEY_K, KEY_KP2 }, + { KEY_L, KEY_KP3 }, + { KEY_U, KEY_KP4 }, + { KEY_I, KEY_KP5 }, + { KEY_O, KEY_KP6 }, + { KEY_7, KEY_KP7 }, + { KEY_8, KEY_KP8 }, + { KEY_9, KEY_KP9 }, + { KEY_M, KEY_KP0 }, + { KEY_DOT, KEY_KPDOT }, + { KEY_SLASH, KEY_KPPLUS }, + { KEY_SEMICOLON, KEY_KPMINUS }, + { KEY_P, KEY_KPASTERISK }, + { KEY_MINUS, KEY_KPEQUAL }, + { KEY_0, KEY_KPSLASH }, + { KEY_F6, KEY_NUMLOCK }, + { KEY_KPENTER, KEY_KPENTER }, + { KEY_BACKSPACE, KEY_BACKSPACE }, + { } +}; + +static struct hidinput_key_translation apple_iso_keyboard[] = { + { KEY_GRAVE, KEY_102ND }, + { KEY_102ND, KEY_GRAVE }, + { } +}; -#define map_abs_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ - &max, EV_ABS, (c)) -#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ - &max, EV_KEY, (c)) +static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from) +{ + struct hidinput_key_translation *trans; + + /* Look for the translation */ + for (trans = table; trans->from; trans++) + if (trans->from == from) + return trans; + + return NULL; +} + +int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, + struct hid_usage *usage, __s32 value) +{ + struct hidinput_key_translation *trans; + + if (usage->code == KEY_FN) { + if (value) hid->quirks |= HID_QUIRK_APPLE_FN_ON; + else hid->quirks &= ~HID_QUIRK_APPLE_FN_ON; + + input_event(input, usage->type, usage->code, value); + + return 1; + } + + if (hid_apple_fnmode) { + int do_translate; + + trans = find_translation((hid->product < 0x220 || + hid->product >= 0x300) ? + powerbook_fn_keys : apple_fn_keys, + usage->code); + if (trans) { + if (test_bit(usage->code, hid->apple_pressed_fn)) + do_translate = 1; + else if (trans->flags & APPLE_FLAG_FKEY) + do_translate = + (hid_apple_fnmode == 2 && (hid->quirks & HID_QUIRK_APPLE_FN_ON)) || + (hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON)); + else + do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON); + + if (do_translate) { + if (value) + set_bit(usage->code, hid->apple_pressed_fn); + else + clear_bit(usage->code, hid->apple_pressed_fn); + + input_event(input, usage->type, trans->to, value); + + return 1; + } + } + + if (hid->quirks & HID_QUIRK_APPLE_NUMLOCK_EMULATION && ( + test_bit(usage->code, hid->pb_pressed_numlock) || + test_bit(LED_NUML, input->led))) { + trans = find_translation(powerbook_numlock_keys, usage->code); + + if (trans) { + if (value) + set_bit(usage->code, hid->pb_pressed_numlock); + else + clear_bit(usage->code, hid->pb_pressed_numlock); + + input_event(input, usage->type, trans->to, value); + } + + return 1; + } + } + + if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) { + trans = find_translation(apple_iso_keyboard, usage->code); + if (trans) { + input_event(input, usage->type, trans->to, value); + return 1; + } + } + + return 0; +} + +static void hidinput_apple_setup(struct input_dev *input) +{ + struct hidinput_key_translation *trans; + + set_bit(KEY_NUMLOCK, input->keybit); + + /* Enable all needed keys */ + for (trans = apple_fn_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + + for (trans = powerbook_fn_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + + for (trans = powerbook_numlock_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + + for (trans = apple_iso_keyboard; trans->from; trans++) + set_bit(trans->to, input->keybit); + +} +#else +inline int hidinput_apple_event(struct hid_device *hid, + struct input_dev *input, + struct hid_usage *usage, __s32 value) +{ + return 0; +} + +static inline void hidinput_apple_setup(struct input_dev *input) +{ +} +#endif static inline int match_scancode(int code, int scancode) { @@ -154,7 +366,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel { struct input_dev *input = hidinput->input; struct hid_device *device = input_get_drvdata(input); - int max = 0, code; + int max = 0, code, ret; unsigned long *bit = NULL; field->hidinput = hidinput; @@ -173,345 +385,406 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel goto ignore; } - if (device->driver->input_mapping) { - int ret = device->driver->input_mapping(device, hidinput, field, - usage, &bit, &max); - if (ret > 0) - goto mapped; - if (ret < 0) - goto ignore; - } + /* handle input mappings for quirky devices */ + ret = hidinput_mapping_quirks(usage, input, &bit, &max); + if (ret) + goto mapped; switch (usage->hid & HID_USAGE_PAGE) { - case HID_UP_UNDEFINED: - goto ignore; - case HID_UP_KEYBOARD: - set_bit(EV_REP, input->evbit); + case HID_UP_UNDEFINED: + goto ignore; - if ((usage->hid & HID_USAGE) < 256) { - if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore; - map_key_clear(hid_keyboard[usage->hid & HID_USAGE]); - } else - map_key(KEY_UNKNOWN); + case HID_UP_KEYBOARD: - break; + set_bit(EV_REP, input->evbit); - case HID_UP_BUTTON: - code = ((usage->hid - 1) & 0xf); + if ((usage->hid & HID_USAGE) < 256) { + if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore; + map_key_clear(hid_keyboard[usage->hid & HID_USAGE]); + } else + map_key(KEY_UNKNOWN); - switch (field->application) { - case HID_GD_MOUSE: - case HID_GD_POINTER: code += 0x110; break; - case HID_GD_JOYSTICK: code += 0x120; break; - case HID_GD_GAMEPAD: code += 0x130; break; - default: - switch (field->physical) { - case HID_GD_MOUSE: - case HID_GD_POINTER: code += 0x110; break; - case HID_GD_JOYSTICK: code += 0x120; break; - case HID_GD_GAMEPAD: code += 0x130; break; - default: code += 0x100; + break; + + case HID_UP_BUTTON: + + code = ((usage->hid - 1) & 0xf); + + switch (field->application) { + case HID_GD_MOUSE: + case HID_GD_POINTER: code += 0x110; break; + case HID_GD_JOYSTICK: code += 0x120; break; + case HID_GD_GAMEPAD: code += 0x130; break; + default: + switch (field->physical) { + case HID_GD_MOUSE: + case HID_GD_POINTER: code += 0x110; break; + case HID_GD_JOYSTICK: code += 0x120; break; + case HID_GD_GAMEPAD: code += 0x130; break; + default: code += 0x100; + } } - } - map_key(code); - break; - - case HID_UP_SIMULATION: - switch (usage->hid & 0xffff) { - case 0xba: map_abs(ABS_RUDDER); break; - case 0xbb: map_abs(ABS_THROTTLE); break; - case 0xc4: map_abs(ABS_GAS); break; - case 0xc5: map_abs(ABS_BRAKE); break; - case 0xc8: map_abs(ABS_WHEEL); break; - default: goto ignore; - } - break; - - case HID_UP_GENDESK: - if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ - switch (usage->hid & 0xf) { - case 0x1: map_key_clear(KEY_POWER); break; - case 0x2: map_key_clear(KEY_SLEEP); break; - case 0x3: map_key_clear(KEY_WAKEUP); break; - default: goto unknown; + /* Special handling for Logitech Cordless Desktop */ + if (field->application != HID_GD_MOUSE) { + if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) { + int hid = usage->hid & HID_USAGE; + if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0) + code = logitech_expanded_keymap[hid]; + } + } else { + if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) { + int hid = usage->hid & HID_USAGE; + if (hid == 7 || hid == 8) + goto ignore; + } } + + map_key(code); break; - } - if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ - switch (usage->hid) { - case HID_GD_UP: usage->hat_dir = 1; break; - case HID_GD_DOWN: usage->hat_dir = 5; break; - case HID_GD_RIGHT: usage->hat_dir = 3; break; - case HID_GD_LEFT: usage->hat_dir = 7; break; - default: goto unknown; - } - if (field->dpad) { - map_abs(field->dpad); - goto ignore; + + case HID_UP_SIMULATION: + + switch (usage->hid & 0xffff) { + case 0xba: map_abs(ABS_RUDDER); break; + case 0xbb: map_abs(ABS_THROTTLE); break; + case 0xc4: map_abs(ABS_GAS); break; + case 0xc5: map_abs(ABS_BRAKE); break; + case 0xc8: map_abs(ABS_WHEEL); break; + default: goto ignore; } - map_abs(ABS_HAT0X); break; - } - switch (usage->hid) { - /* These usage IDs map directly to the usage codes. */ - case HID_GD_X: case HID_GD_Y: case HID_GD_Z: - case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: - case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: - if (field->flags & HID_MAIN_ITEM_RELATIVE) - map_rel(usage->hid & 0xf); - else - map_abs(usage->hid & 0xf); - break; + case HID_UP_GENDESK: - case HID_GD_HATSWITCH: - usage->hat_min = field->logical_minimum; - usage->hat_max = field->logical_maximum; - map_abs(ABS_HAT0X); - break; + if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ + switch (usage->hid & 0xf) { + case 0x1: map_key_clear(KEY_POWER); break; + case 0x2: map_key_clear(KEY_SLEEP); break; + case 0x3: map_key_clear(KEY_WAKEUP); break; + default: goto unknown; + } + break; + } - case HID_GD_START: map_key_clear(BTN_START); break; - case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; + if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ + switch (usage->hid) { + case HID_GD_UP: usage->hat_dir = 1; break; + case HID_GD_DOWN: usage->hat_dir = 5; break; + case HID_GD_RIGHT: usage->hat_dir = 3; break; + case HID_GD_LEFT: usage->hat_dir = 7; break; + default: goto unknown; + } + if (field->dpad) { + map_abs(field->dpad); + goto ignore; + } + map_abs(ABS_HAT0X); + break; + } - default: goto unknown; - } + switch (usage->hid) { - break; - - case HID_UP_LED: - switch (usage->hid & 0xffff) { /* HID-Value: */ - case 0x01: map_led (LED_NUML); break; /* "Num Lock" */ - case 0x02: map_led (LED_CAPSL); break; /* "Caps Lock" */ - case 0x03: map_led (LED_SCROLLL); break; /* "Scroll Lock" */ - case 0x04: map_led (LED_COMPOSE); break; /* "Compose" */ - case 0x05: map_led (LED_KANA); break; /* "Kana" */ - case 0x27: map_led (LED_SLEEP); break; /* "Stand-By" */ - case 0x4c: map_led (LED_SUSPEND); break; /* "System Suspend" */ - case 0x09: map_led (LED_MUTE); break; /* "Mute" */ - case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */ - case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */ - case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */ - - default: goto ignore; - } - break; - - case HID_UP_DIGITIZER: - switch (usage->hid & 0xff) { - case 0x30: /* TipPressure */ - if (!test_bit(BTN_TOUCH, input->keybit)) { - device->quirks |= HID_QUIRK_NOTOUCH; - set_bit(EV_KEY, input->evbit); - set_bit(BTN_TOUCH, input->keybit); + /* These usage IDs map directly to the usage codes. */ + case HID_GD_X: case HID_GD_Y: case HID_GD_Z: + case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: + case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: + if (field->flags & HID_MAIN_ITEM_RELATIVE) + map_rel(usage->hid & 0xf); + else + map_abs(usage->hid & 0xf); + break; + + case HID_GD_HATSWITCH: + usage->hat_min = field->logical_minimum; + usage->hat_max = field->logical_maximum; + map_abs(ABS_HAT0X); + break; + + case HID_GD_START: map_key_clear(BTN_START); break; + case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; + + default: goto unknown; } - map_abs_clear(ABS_PRESSURE); + break; - case 0x32: /* InRange */ - switch (field->physical & 0xff) { - case 0x21: map_key(BTN_TOOL_MOUSE); break; - case 0x22: map_key(BTN_TOOL_FINGER); break; - default: map_key(BTN_TOOL_PEN); break; + case HID_UP_LED: + + switch (usage->hid & 0xffff) { /* HID-Value: */ + case 0x01: map_led (LED_NUML); break; /* "Num Lock" */ + case 0x02: map_led (LED_CAPSL); break; /* "Caps Lock" */ + case 0x03: map_led (LED_SCROLLL); break; /* "Scroll Lock" */ + case 0x04: map_led (LED_COMPOSE); break; /* "Compose" */ + case 0x05: map_led (LED_KANA); break; /* "Kana" */ + case 0x27: map_led (LED_SLEEP); break; /* "Stand-By" */ + case 0x4c: map_led (LED_SUSPEND); break; /* "System Suspend" */ + case 0x09: map_led (LED_MUTE); break; /* "Mute" */ + case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */ + case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */ + case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */ + + default: goto ignore; } break; - case 0x3c: /* Invert */ - map_key_clear(BTN_TOOL_RUBBER); + case HID_UP_DIGITIZER: + + switch (usage->hid & 0xff) { + + case 0x30: /* TipPressure */ + if (!test_bit(BTN_TOUCH, input->keybit)) { + device->quirks |= HID_QUIRK_NOTOUCH; + set_bit(EV_KEY, input->evbit); + set_bit(BTN_TOUCH, input->keybit); + } + + map_abs_clear(ABS_PRESSURE); + break; + + case 0x32: /* InRange */ + switch (field->physical & 0xff) { + case 0x21: map_key(BTN_TOOL_MOUSE); break; + case 0x22: map_key(BTN_TOOL_FINGER); break; + default: map_key(BTN_TOOL_PEN); break; + } + break; + + case 0x3c: /* Invert */ + map_key_clear(BTN_TOOL_RUBBER); + break; + + case 0x33: /* Touch */ + case 0x42: /* TipSwitch */ + case 0x43: /* TipSwitch2 */ + device->quirks &= ~HID_QUIRK_NOTOUCH; + map_key_clear(BTN_TOUCH); + break; + + case 0x44: /* BarrelSwitch */ + map_key_clear(BTN_STYLUS); + break; + + default: goto unknown; + } break; - case 0x33: /* Touch */ - case 0x42: /* TipSwitch */ - case 0x43: /* TipSwitch2 */ - device->quirks &= ~HID_QUIRK_NOTOUCH; - map_key_clear(BTN_TOUCH); + case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ + + switch (usage->hid & HID_USAGE) { + case 0x000: goto ignore; + case 0x034: map_key_clear(KEY_SLEEP); break; + case 0x036: map_key_clear(BTN_MISC); break; + + case 0x040: map_key_clear(KEY_MENU); break; + case 0x045: map_key_clear(KEY_RADIO); break; + + case 0x083: map_key_clear(KEY_LAST); break; + case 0x088: map_key_clear(KEY_PC); break; + case 0x089: map_key_clear(KEY_TV); break; + case 0x08a: map_key_clear(KEY_WWW); break; + case 0x08b: map_key_clear(KEY_DVD); break; + case 0x08c: map_key_clear(KEY_PHONE); break; + case 0x08d: map_key_clear(KEY_PROGRAM); break; + case 0x08e: map_key_clear(KEY_VIDEOPHONE); break; + case 0x08f: map_key_clear(KEY_GAMES); break; + case 0x090: map_key_clear(KEY_MEMO); break; + case 0x091: map_key_clear(KEY_CD); break; + case 0x092: map_key_clear(KEY_VCR); break; + case 0x093: map_key_clear(KEY_TUNER); break; + case 0x094: map_key_clear(KEY_EXIT); break; + case 0x095: map_key_clear(KEY_HELP); break; + case 0x096: map_key_clear(KEY_TAPE); break; + case 0x097: map_key_clear(KEY_TV2); break; + case 0x098: map_key_clear(KEY_SAT); break; + case 0x09a: map_key_clear(KEY_PVR); break; + + case 0x09c: map_key_clear(KEY_CHANNELUP); break; + case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; + case 0x0a0: map_key_clear(KEY_VCR2); break; + + case 0x0b0: map_key_clear(KEY_PLAY); break; + case 0x0b1: map_key_clear(KEY_PAUSE); break; + case 0x0b2: map_key_clear(KEY_RECORD); break; + case 0x0b3: map_key_clear(KEY_FASTFORWARD); break; + case 0x0b4: map_key_clear(KEY_REWIND); break; + case 0x0b5: map_key_clear(KEY_NEXTSONG); break; + case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; + case 0x0b7: map_key_clear(KEY_STOPCD); break; + case 0x0b8: map_key_clear(KEY_EJECTCD); break; + case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; + + case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; + case 0x0e0: map_abs_clear(ABS_VOLUME); break; + case 0x0e2: map_key_clear(KEY_MUTE); break; + case 0x0e5: map_key_clear(KEY_BASSBOOST); break; + case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; + case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; + + case 0x182: map_key_clear(KEY_BOOKMARKS); break; + case 0x183: map_key_clear(KEY_CONFIG); break; + case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; + case 0x185: map_key_clear(KEY_EDITOR); break; + case 0x186: map_key_clear(KEY_SPREADSHEET); break; + case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break; + case 0x188: map_key_clear(KEY_PRESENTATION); break; + case 0x189: map_key_clear(KEY_DATABASE); break; + case 0x18a: map_key_clear(KEY_MAIL); break; + case 0x18b: map_key_clear(KEY_NEWS); break; + case 0x18c: map_key_clear(KEY_VOICEMAIL); break; + case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break; + case 0x18e: map_key_clear(KEY_CALENDAR); break; + case 0x191: map_key_clear(KEY_FINANCE); break; + case 0x192: map_key_clear(KEY_CALC); break; + case 0x194: map_key_clear(KEY_FILE); break; + case 0x196: map_key_clear(KEY_WWW); break; + case 0x19c: map_key_clear(KEY_LOGOFF); break; + case 0x19e: map_key_clear(KEY_COFFEE); break; + case 0x1a6: map_key_clear(KEY_HELP); break; + case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; + case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; + case 0x1b6: map_key_clear(KEY_MEDIA); break; + case 0x1b7: map_key_clear(KEY_SOUND); break; + case 0x1bc: map_key_clear(KEY_MESSENGER); break; + case 0x1bd: map_key_clear(KEY_INFO); break; + case 0x201: map_key_clear(KEY_NEW); break; + case 0x202: map_key_clear(KEY_OPEN); break; + case 0x203: map_key_clear(KEY_CLOSE); break; + case 0x204: map_key_clear(KEY_EXIT); break; + case 0x207: map_key_clear(KEY_SAVE); break; + case 0x208: map_key_clear(KEY_PRINT); break; + case 0x209: map_key_clear(KEY_PROPS); break; + case 0x21a: map_key_clear(KEY_UNDO); break; + case 0x21b: map_key_clear(KEY_COPY); break; + case 0x21c: map_key_clear(KEY_CUT); break; + case 0x21d: map_key_clear(KEY_PASTE); break; + case 0x21f: map_key_clear(KEY_FIND); break; + case 0x221: map_key_clear(KEY_SEARCH); break; + case 0x222: map_key_clear(KEY_GOTO); break; + case 0x223: map_key_clear(KEY_HOMEPAGE); break; + case 0x224: map_key_clear(KEY_BACK); break; + case 0x225: map_key_clear(KEY_FORWARD); break; + case 0x226: map_key_clear(KEY_STOP); break; + case 0x227: map_key_clear(KEY_REFRESH); break; + case 0x22a: map_key_clear(KEY_BOOKMARKS); break; + case 0x22d: map_key_clear(KEY_ZOOMIN); break; + case 0x22e: map_key_clear(KEY_ZOOMOUT); break; + case 0x22f: map_key_clear(KEY_ZOOMRESET); break; + case 0x233: map_key_clear(KEY_SCROLLUP); break; + case 0x234: map_key_clear(KEY_SCROLLDOWN); break; + case 0x238: map_rel(REL_HWHEEL); break; + case 0x25f: map_key_clear(KEY_CANCEL); break; + case 0x279: map_key_clear(KEY_REDO); break; + + case 0x289: map_key_clear(KEY_REPLY); break; + case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; + case 0x28c: map_key_clear(KEY_SEND); break; + + default: goto ignore; + } break; - case 0x44: /* BarrelSwitch */ - map_key_clear(BTN_STYLUS); + case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ + + set_bit(EV_REP, input->evbit); + switch (usage->hid & HID_USAGE) { + case 0x021: map_key_clear(KEY_PRINT); break; + case 0x070: map_key_clear(KEY_HP); break; + case 0x071: map_key_clear(KEY_CAMERA); break; + case 0x072: map_key_clear(KEY_SOUND); break; + case 0x073: map_key_clear(KEY_QUESTION); break; + case 0x080: map_key_clear(KEY_EMAIL); break; + case 0x081: map_key_clear(KEY_CHAT); break; + case 0x082: map_key_clear(KEY_SEARCH); break; + case 0x083: map_key_clear(KEY_CONNECT); break; + case 0x084: map_key_clear(KEY_FINANCE); break; + case 0x085: map_key_clear(KEY_SPORT); break; + case 0x086: map_key_clear(KEY_SHOP); break; + default: goto ignore; + } break; - default: goto unknown; - } - break; - - case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ - switch (usage->hid & HID_USAGE) { - case 0x000: goto ignore; - case 0x034: map_key_clear(KEY_SLEEP); break; - case 0x036: map_key_clear(BTN_MISC); break; - - case 0x040: map_key_clear(KEY_MENU); break; - case 0x045: map_key_clear(KEY_RADIO); break; - - case 0x083: map_key_clear(KEY_LAST); break; - case 0x088: map_key_clear(KEY_PC); break; - case 0x089: map_key_clear(KEY_TV); break; - case 0x08a: map_key_clear(KEY_WWW); break; - case 0x08b: map_key_clear(KEY_DVD); break; - case 0x08c: map_key_clear(KEY_PHONE); break; - case 0x08d: map_key_clear(KEY_PROGRAM); break; - case 0x08e: map_key_clear(KEY_VIDEOPHONE); break; - case 0x08f: map_key_clear(KEY_GAMES); break; - case 0x090: map_key_clear(KEY_MEMO); break; - case 0x091: map_key_clear(KEY_CD); break; - case 0x092: map_key_clear(KEY_VCR); break; - case 0x093: map_key_clear(KEY_TUNER); break; - case 0x094: map_key_clear(KEY_EXIT); break; - case 0x095: map_key_clear(KEY_HELP); break; - case 0x096: map_key_clear(KEY_TAPE); break; - case 0x097: map_key_clear(KEY_TV2); break; - case 0x098: map_key_clear(KEY_SAT); break; - case 0x09a: map_key_clear(KEY_PVR); break; - - case 0x09c: map_key_clear(KEY_CHANNELUP); break; - case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; - case 0x0a0: map_key_clear(KEY_VCR2); break; - - case 0x0b0: map_key_clear(KEY_PLAY); break; - case 0x0b1: map_key_clear(KEY_PAUSE); break; - case 0x0b2: map_key_clear(KEY_RECORD); break; - case 0x0b3: map_key_clear(KEY_FASTFORWARD); break; - case 0x0b4: map_key_clear(KEY_REWIND); break; - case 0x0b5: map_key_clear(KEY_NEXTSONG); break; - case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; - case 0x0b7: map_key_clear(KEY_STOPCD); break; - case 0x0b8: map_key_clear(KEY_EJECTCD); break; - case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; - - case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; - case 0x0e0: map_abs_clear(ABS_VOLUME); break; - case 0x0e2: map_key_clear(KEY_MUTE); break; - case 0x0e5: map_key_clear(KEY_BASSBOOST); break; - case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; - case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; - - case 0x182: map_key_clear(KEY_BOOKMARKS); break; - case 0x183: map_key_clear(KEY_CONFIG); break; - case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; - case 0x185: map_key_clear(KEY_EDITOR); break; - case 0x186: map_key_clear(KEY_SPREADSHEET); break; - case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break; - case 0x188: map_key_clear(KEY_PRESENTATION); break; - case 0x189: map_key_clear(KEY_DATABASE); break; - case 0x18a: map_key_clear(KEY_MAIL); break; - case 0x18b: map_key_clear(KEY_NEWS); break; - case 0x18c: map_key_clear(KEY_VOICEMAIL); break; - case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break; - case 0x18e: map_key_clear(KEY_CALENDAR); break; - case 0x191: map_key_clear(KEY_FINANCE); break; - case 0x192: map_key_clear(KEY_CALC); break; - case 0x194: map_key_clear(KEY_FILE); break; - case 0x196: map_key_clear(KEY_WWW); break; - case 0x19c: map_key_clear(KEY_LOGOFF); break; - case 0x19e: map_key_clear(KEY_COFFEE); break; - case 0x1a6: map_key_clear(KEY_HELP); break; - case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; - case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; - case 0x1b6: map_key_clear(KEY_MEDIA); break; - case 0x1b7: map_key_clear(KEY_SOUND); break; - case 0x1bc: map_key_clear(KEY_MESSENGER); break; - case 0x1bd: map_key_clear(KEY_INFO); break; - case 0x201: map_key_clear(KEY_NEW); break; - case 0x202: map_key_clear(KEY_OPEN); break; - case 0x203: map_key_clear(KEY_CLOSE); break; - case 0x204: map_key_clear(KEY_EXIT); break; - case 0x207: map_key_clear(KEY_SAVE); break; - case 0x208: map_key_clear(KEY_PRINT); break; - case 0x209: map_key_clear(KEY_PROPS); break; - case 0x21a: map_key_clear(KEY_UNDO); break; - case 0x21b: map_key_clear(KEY_COPY); break; - case 0x21c: map_key_clear(KEY_CUT); break; - case 0x21d: map_key_clear(KEY_PASTE); break; - case 0x21f: map_key_clear(KEY_FIND); break; - case 0x221: map_key_clear(KEY_SEARCH); break; - case 0x222: map_key_clear(KEY_GOTO); break; - case 0x223: map_key_clear(KEY_HOMEPAGE); break; - case 0x224: map_key_clear(KEY_BACK); break; - case 0x225: map_key_clear(KEY_FORWARD); break; - case 0x226: map_key_clear(KEY_STOP); break; - case 0x227: map_key_clear(KEY_REFRESH); break; - case 0x22a: map_key_clear(KEY_BOOKMARKS); break; - case 0x22d: map_key_clear(KEY_ZOOMIN); break; - case 0x22e: map_key_clear(KEY_ZOOMOUT); break; - case 0x22f: map_key_clear(KEY_ZOOMRESET); break; - case 0x233: map_key_clear(KEY_SCROLLUP); break; - case 0x234: map_key_clear(KEY_SCROLLDOWN); break; - case 0x238: map_rel(REL_HWHEEL); break; - case 0x25f: map_key_clear(KEY_CANCEL); break; - case 0x279: map_key_clear(KEY_REDO); break; - - case 0x289: map_key_clear(KEY_REPLY); break; - case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; - case 0x28c: map_key_clear(KEY_SEND); break; - - default: goto ignore; - } - break; - - case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ - set_bit(EV_REP, input->evbit); - switch (usage->hid & HID_USAGE) { - case 0x021: map_key_clear(KEY_PRINT); break; - case 0x070: map_key_clear(KEY_HP); break; - case 0x071: map_key_clear(KEY_CAMERA); break; - case 0x072: map_key_clear(KEY_SOUND); break; - case 0x073: map_key_clear(KEY_QUESTION); break; - case 0x080: map_key_clear(KEY_EMAIL); break; - case 0x081: map_key_clear(KEY_CHAT); break; - case 0x082: map_key_clear(KEY_SEARCH); break; - case 0x083: map_key_clear(KEY_CONNECT); break; - case 0x084: map_key_clear(KEY_FINANCE); break; - case 0x085: map_key_clear(KEY_SPORT); break; - case 0x086: map_key_clear(KEY_SHOP); break; - default: goto ignore; - } - break; + case HID_UP_MSVENDOR: - case HID_UP_MSVENDOR: - goto ignore; + goto ignore; - case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ - set_bit(EV_REP, input->evbit); - goto ignore; + case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ - case HID_UP_LOGIVENDOR: - goto ignore; - - case HID_UP_PID: - switch (usage->hid & HID_USAGE) { - case 0xa4: map_key_clear(BTN_DEAD); break; - default: goto ignore; - } - break; + set_bit(EV_REP, input->evbit); + switch(usage->hid & HID_USAGE) { + case 0x003: + /* The fn key on Apple USB keyboards */ + map_key_clear(KEY_FN); + hidinput_apple_setup(input); + break; - default: - unknown: - if (field->report_size == 1) { - if (field->report->type == HID_OUTPUT_REPORT) { - map_led(LED_MISC); - break; + default: goto ignore; } - map_key(BTN_MISC); break; - } - if (field->flags & HID_MAIN_ITEM_RELATIVE) { - map_rel(REL_MISC); + + case HID_UP_LOGIVENDOR: + + goto ignore; + + case HID_UP_PID: + + switch(usage->hid & HID_USAGE) { + case 0xa4: map_key_clear(BTN_DEAD); break; + default: goto ignore; + } + break; + + default: + unknown: + if (field->report_size == 1) { + if (field->report->type == HID_OUTPUT_REPORT) { + map_led(LED_MISC); + break; + } + map_key(BTN_MISC); + break; + } + if (field->flags & HID_MAIN_ITEM_RELATIVE) { + map_rel(REL_MISC); + break; + } + map_abs(ABS_MISC); break; - } - map_abs(ABS_MISC); - break; } mapped: - if (device->driver->input_mapped && device->driver->input_mapped(device, - hidinput, field, usage, &bit, &max) < 0) + if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { + if (usage->hid == HID_GD_Z) + map_rel(REL_HWHEEL); + else if (usage->code == BTN_1) + map_key(BTN_2); + else if (usage->code == BTN_2) + map_key(BTN_1); + } + + if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 | + HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && + (usage->code == REL_WHEEL)) + set_bit(REL_HWHEEL, bit); + + if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) + || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) goto ignore; + if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) && + usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE)) + field->flags &= ~HID_MAIN_ITEM_RELATIVE; + set_bit(usage->type, input->evbit); + if (device->quirks & HID_QUIRK_DUPLICATE_USAGES && + (usage->type == EV_KEY || + usage->type == EV_REL || + usage->type == EV_ABS)) + clear_bit(usage->code, bit); + while (usage->code <= max && test_and_set_bit(usage->code, bit)) usage->code = find_next_zero_bit(bit, max + 1, usage->code); @@ -585,6 +858,10 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct if (!usage->type) return; + /* handle input events for quirky devices */ + if (hidinput_event_quirks(hid, field, usage, value)) + return; + if (usage->hat_min < usage->hat_max || usage->hat_dir) { int hat_dir = usage->hat_dir; if (!hat_dir) @@ -684,14 +961,14 @@ static int hidinput_open(struct input_dev *dev) { struct hid_device *hid = input_get_drvdata(dev); - return hid->ll_driver->open(hid); + return hid->hid_open(hid); } static void hidinput_close(struct input_dev *dev) { struct hid_device *hid = input_get_drvdata(dev); - hid->ll_driver->close(hid); + hid->hid_close(hid); } /* @@ -700,7 +977,7 @@ static void hidinput_close(struct input_dev *dev) * Read all reports and initialize the absolute field values. */ -int hidinput_connect(struct hid_device *hid, unsigned int force) +int hidinput_connect(struct hid_device *hid) { struct hid_report *report; struct hid_input *hidinput = NULL; @@ -708,20 +985,19 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) int i, j, k; int max_report_type = HID_OUTPUT_REPORT; + if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT) + return -1; + INIT_LIST_HEAD(&hid->inputs); - if (!force) { - for (i = 0; i < hid->maxcollection; i++) { - struct hid_collection *col = &hid->collection[i]; - if (col->type == HID_COLLECTION_APPLICATION || - col->type == HID_COLLECTION_PHYSICAL) - if (IS_INPUT_APPLICATION(col->usage)) - break; - } + for (i = 0; i < hid->maxcollection; i++) + if (hid->collection[i].type == HID_COLLECTION_APPLICATION || + hid->collection[i].type == HID_COLLECTION_PHYSICAL) + if (IS_INPUT_APPLICATION(hid->collection[i].usage)) + break; - if (i == hid->maxcollection) - return -1; - } + if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0) + return -1; if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) max_report_type = HID_INPUT_REPORT; @@ -743,8 +1019,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) } input_set_drvdata(input_dev, hid); - input_dev->event = - hid->ll_driver->hidinput_input_event; + input_dev->event = hid->hidinput_input_event; input_dev->open = hidinput_open; input_dev->close = hidinput_close; input_dev->setkeycode = hidinput_setkeycode; @@ -757,7 +1032,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) input_dev->id.vendor = hid->vendor; input_dev->id.product = hid->product; input_dev->id.version = hid->version; - input_dev->dev.parent = hid->dev.parent; + input_dev->dev.parent = hid->dev; hidinput->input = input_dev; list_add_tail(&hidinput->list, &hid->inputs); } diff --git a/trunk/drivers/hid/hid-lg.c b/trunk/drivers/hid/hid-lg.c deleted file mode 100644 index 406d8c82abf1..000000000000 --- a/trunk/drivers/hid/hid-lg.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * HID driver for some logitech "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" -#include "hid-lg.h" - -#define LG_RDESC 0x001 -#define LG_BAD_RELATIVE_KEYS 0x002 -#define LG_DUPLICATE_USAGES 0x004 -#define LG_RESET_LEDS 0x008 -#define LG_EXPANDED_KEYMAP 0x010 -#define LG_IGNORE_DOUBLED_WHEEL 0x020 -#define LG_WIRELESS 0x040 -#define LG_INVERT_HWHEEL 0x080 -#define LG_NOGET 0x100 -#define LG_FF 0x200 -#define LG_FF2 0x400 - -/* - * Certain Logitech keyboards send in report #3 keys which are far - * above the logical maximum described in descriptor. This extends - * the original value of 0x28c of logical maximum to 0x104d - */ -static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && - rdesc[84] == 0x8c && rdesc[85] == 0x02) { - dev_info(&hdev->dev, "fixing up Logitech keyboard report " - "descriptor\n"); - rdesc[84] = rdesc[89] = 0x4d; - rdesc[85] = rdesc[90] = 0x10; - } -} - -#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) - -static int lg_ultrax_remote_mapping(struct hid_input *hi, - struct hid_usage *usage, unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) - return 0; - - set_bit(EV_REP, hi->input->evbit); - switch (usage->hid & HID_USAGE) { - /* Reported on Logitech Ultra X Media Remote */ - case 0x004: lg_map_key_clear(KEY_AGAIN); break; - case 0x00d: lg_map_key_clear(KEY_HOME); break; - case 0x024: lg_map_key_clear(KEY_SHUFFLE); break; - case 0x025: lg_map_key_clear(KEY_TV); break; - case 0x026: lg_map_key_clear(KEY_MENU); break; - case 0x031: lg_map_key_clear(KEY_AUDIO); break; - case 0x032: lg_map_key_clear(KEY_TEXT); break; - case 0x033: lg_map_key_clear(KEY_LAST); break; - case 0x047: lg_map_key_clear(KEY_MP3); break; - case 0x048: lg_map_key_clear(KEY_DVD); break; - case 0x049: lg_map_key_clear(KEY_MEDIA); break; - case 0x04a: lg_map_key_clear(KEY_VIDEO); break; - case 0x04b: lg_map_key_clear(KEY_ANGLE); break; - case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break; - case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break; - case 0x051: lg_map_key_clear(KEY_RED); break; - case 0x052: lg_map_key_clear(KEY_CLOSE); break; - - default: - return 0; - } - return 1; -} - -static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) - return 0; - - switch (usage->hid & HID_USAGE) { - case 0x1001: lg_map_key_clear(KEY_MESSENGER); break; - case 0x1003: lg_map_key_clear(KEY_SOUND); break; - case 0x1004: lg_map_key_clear(KEY_VIDEO); break; - case 0x1005: lg_map_key_clear(KEY_AUDIO); break; - case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break; - case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break; - case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break; - case 0x1013: lg_map_key_clear(KEY_CAMERA); break; - case 0x1014: lg_map_key_clear(KEY_MESSENGER); break; - case 0x1015: lg_map_key_clear(KEY_RECORD); break; - case 0x1016: lg_map_key_clear(KEY_PLAYER); break; - case 0x1017: lg_map_key_clear(KEY_EJECTCD); break; - case 0x1018: lg_map_key_clear(KEY_MEDIA); break; - case 0x1019: lg_map_key_clear(KEY_PROG1); break; - case 0x101a: lg_map_key_clear(KEY_PROG2); break; - case 0x101b: lg_map_key_clear(KEY_PROG3); break; - case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break; - case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break; - case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break; - case 0x1023: lg_map_key_clear(KEY_CLOSE); break; - case 0x1027: lg_map_key_clear(KEY_MENU); break; - /* this one is marked as 'Rotate' */ - case 0x1028: lg_map_key_clear(KEY_ANGLE); break; - case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break; - case 0x102a: lg_map_key_clear(KEY_BACK); break; - case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break; - case 0x1041: lg_map_key_clear(KEY_BATTERY); break; - case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break; - case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break; - case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break; - case 0x1045: lg_map_key_clear(KEY_UNDO); break; - case 0x1046: lg_map_key_clear(KEY_REDO); break; - case 0x1047: lg_map_key_clear(KEY_PRINT); break; - case 0x1048: lg_map_key_clear(KEY_SAVE); break; - case 0x1049: lg_map_key_clear(KEY_PROG1); break; - case 0x104a: lg_map_key_clear(KEY_PROG2); break; - case 0x104b: lg_map_key_clear(KEY_PROG3); break; - case 0x104c: lg_map_key_clear(KEY_PROG4); break; - - default: - return 0; - } - return 1; -} - -static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - /* extended mapping for certain Logitech hardware (Logitech cordless - desktop LX500) */ - static const u8 e_keymap[] = { - 0,216, 0,213,175,156, 0, 0, 0, 0, - 144, 0, 0, 0, 0, 0, 0, 0, 0,212, - 174,167,152,161,112, 0, 0, 0,154, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,183,184,185,186,187, - 188,189,190,191,192,193,194, 0, 0, 0 - }; - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - unsigned int hid = usage->hid; - - if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && - lg_ultrax_remote_mapping(hi, usage, bit, max)) - return 1; - - if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) - return 1; - - if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) - return 0; - - hid &= HID_USAGE; - - /* Special handling for Logitech Cordless Desktop */ - if (field->application == HID_GD_MOUSE) { - if ((quirks & LG_IGNORE_DOUBLED_WHEEL) && - (hid == 7 || hid == 8)) - return -1; - } else { - if ((quirks & LG_EXPANDED_KEYMAP) && - hid < ARRAY_SIZE(e_keymap) && - e_keymap[hid] != 0) { - hid_map_usage(hi, usage, bit, max, EV_KEY, - e_keymap[hid]); - return 1; - } - } - - return 0; -} - -static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && - (field->flags & HID_MAIN_ITEM_RELATIVE)) - field->flags &= ~HID_MAIN_ITEM_RELATIVE; - - if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || - usage->type == EV_REL || usage->type == EV_ABS)) - clear_bit(usage->code, *bit); - - return 0; -} - -static int lg_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { - input_event(field->hidinput->input, usage->type, usage->code, - -value); - return 1; - } - - return 0; -} - -static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - unsigned long quirks = id->driver_data; - unsigned int connect_mask = HID_CONNECT_DEFAULT; - int ret; - - hid_set_drvdata(hdev, (void *)quirks); - - if (quirks & LG_NOGET) - hdev->quirks |= HID_QUIRK_NOGET; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - if (quirks & (LG_FF | LG_FF2)) - connect_mask &= ~HID_CONNECT_FF; - - ret = hid_hw_start(hdev, connect_mask); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - if (quirks & LG_RESET_LEDS) - usbhid_set_leds(hdev); - - if (quirks & LG_FF) - lgff_init(hdev); - if (quirks & LG_FF2) - lg2ff_init(hdev); - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id lg_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), - .driver_data = LG_RDESC | LG_WIRELESS }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER), - .driver_data = LG_RDESC | LG_WIRELESS }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2), - .driver_data = LG_RDESC | LG_WIRELESS }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER), - .driver_data = LG_BAD_RELATIVE_KEYS }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP), - .driver_data = LG_DUPLICATE_USAGES }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE), - .driver_data = LG_DUPLICATE_USAGES }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), - .driver_data = LG_DUPLICATE_USAGES }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD), - .driver_data = LG_RESET_LEDS }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), - .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), - .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3), - .driver_data = LG_INVERT_HWHEEL }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150), - .driver_data = LG_INVERT_HWHEEL }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D), - .driver_data = LG_NOGET }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), - .driver_data = LG_NOGET | LG_FF }, - - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), - .driver_data = LG_FF }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), - .driver_data = LG_FF }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), - .driver_data = LG_FF }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), - .driver_data = LG_FF }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), - .driver_data = LG_FF }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), - .driver_data = LG_FF }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), - .driver_data = LG_FF2 }, - { } -}; -MODULE_DEVICE_TABLE(hid, lg_devices); - -static struct hid_driver lg_driver = { - .name = "logitech", - .id_table = lg_devices, - .report_fixup = lg_report_fixup, - .input_mapping = lg_input_mapping, - .input_mapped = lg_input_mapped, - .event = lg_event, - .probe = lg_probe, -}; - -static int lg_init(void) -{ - return hid_register_driver(&lg_driver); -} - -static void lg_exit(void) -{ - hid_unregister_driver(&lg_driver); -} - -module_init(lg_init); -module_exit(lg_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(logitech); diff --git a/trunk/drivers/hid/hid-lg.h b/trunk/drivers/hid/hid-lg.h deleted file mode 100644 index 27ae750ca878..000000000000 --- a/trunk/drivers/hid/hid-lg.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __HID_LG_H -#define __HID_LG_H - -#include - -#ifdef CONFIG_LOGITECH_FF -int lgff_init(struct hid_device *hdev); -#else -static inline int lgff_init(struct hid_device *hdev) { return -1; } -#endif - -#ifdef CONFIG_LOGIRUMBLEPAD2_FF -int lg2ff_init(struct hid_device *hdev); -#else -static inline int lg2ff_init(struct hid_device *hdev) { return -1; } -#endif - -#endif diff --git a/trunk/drivers/hid/hid-microsoft.c b/trunk/drivers/hid/hid-microsoft.c deleted file mode 100644 index d718b1607d0f..000000000000 --- a/trunk/drivers/hid/hid-microsoft.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * HID driver for some microsoft "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -#define MS_HIDINPUT 0x01 -#define MS_ERGONOMY 0x02 -#define MS_PRESENTER 0x04 -#define MS_RDESC 0x08 -#define MS_NOGET 0x10 - -/* - * Microsoft Wireless Desktop Receiver (Model 1028) has several - * 'Usage Min/Max' where it ought to have 'Physical Min/Max' - */ -static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 && - rdesc[286] == 0x2a && rdesc[304] == 0x19 && - rdesc[306] == 0x29 && rdesc[352] == 0x1a && - rdesc[355] == 0x2a && rdesc[557] == 0x19 && - rdesc[559] == 0x29) { - dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " - "Model 1028 report descriptor\n"); - rdesc[284] = rdesc[304] = rdesc[557] = 0x35; - rdesc[352] = 0x36; - rdesc[286] = rdesc[355] = 0x46; - rdesc[306] = rdesc[559] = 0x45; - } -} - -#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - struct input_dev *input = hi->input; - - switch (usage->hid & HID_USAGE) { - case 0xfd06: ms_map_key_clear(KEY_CHAT); break; - case 0xfd07: ms_map_key_clear(KEY_PHONE); break; - case 0xff05: - set_bit(EV_REP, input->evbit); - ms_map_key_clear(KEY_F13); - set_bit(KEY_F14, input->keybit); - set_bit(KEY_F15, input->keybit); - set_bit(KEY_F16, input->keybit); - set_bit(KEY_F17, input->keybit); - set_bit(KEY_F18, input->keybit); - default: - return 0; - } - return 1; -} - -static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - set_bit(EV_REP, hi->input->evbit); - switch (usage->hid & HID_USAGE) { - case 0xfd08: ms_map_key_clear(KEY_FORWARD); break; - case 0xfd09: ms_map_key_clear(KEY_BACK); break; - case 0xfd0b: ms_map_key_clear(KEY_PLAYPAUSE); break; - case 0xfd0e: ms_map_key_clear(KEY_CLOSE); break; - case 0xfd0f: ms_map_key_clear(KEY_PLAY); break; - default: - return 0; - } - return 1; -} - -static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) - return 0; - - if (quirks & MS_ERGONOMY) { - int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max); - if (ret) - return ret; - } - - if ((quirks & MS_PRESENTER) && - ms_presenter_8k_quirk(hi, usage, bit, max)) - return 1; - - return 0; -} - -static int ms_event(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - - if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || - !usage->type) - return 0; - - /* Handling MS keyboards special buttons */ - if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { - struct input_dev *input = field->hidinput->input; - static unsigned int last_key = 0; - unsigned int key = 0; - switch (value) { - case 0x01: key = KEY_F14; break; - case 0x02: key = KEY_F15; break; - case 0x04: key = KEY_F16; break; - case 0x08: key = KEY_F17; break; - case 0x10: key = KEY_F18; break; - } - if (key) { - input_event(input, usage->type, key, 1); - last_key = key; - } else - input_event(input, usage->type, last_key, 0); - - return 1; - } - - return 0; -} - -static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - unsigned long quirks = id->driver_data; - int ret; - - hid_set_drvdata(hdev, (void *)quirks); - - if (quirks & MS_NOGET) - hdev->quirks |= HID_QUIRK_NOGET; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ? - HID_CONNECT_HIDINPUT_FORCE : 0)); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id ms_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV), - .driver_data = MS_HIDINPUT }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), - .driver_data = MS_ERGONOMY }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), - .driver_data = MS_ERGONOMY | MS_RDESC }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), - .driver_data = MS_PRESENTER }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), - .driver_data = MS_NOGET }, - - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), - .driver_data = MS_PRESENTER }, - { } -}; -MODULE_DEVICE_TABLE(hid, ms_devices); - -static struct hid_driver ms_driver = { - .name = "microsoft", - .id_table = ms_devices, - .report_fixup = ms_report_fixup, - .input_mapping = ms_input_mapping, - .event = ms_event, - .probe = ms_probe, -}; - -static int ms_init(void) -{ - return hid_register_driver(&ms_driver); -} - -static void ms_exit(void) -{ - hid_unregister_driver(&ms_driver); -} - -module_init(ms_init); -module_exit(ms_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(microsoft); diff --git a/trunk/drivers/hid/hid-monterey.c b/trunk/drivers/hid/hid-monterey.c deleted file mode 100644 index f3a85a065f18..000000000000 --- a/trunk/drivers/hid/hid-monterey.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * HID driver for some monterey "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -static void mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - if (rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { - dev_info(&hdev->dev, "fixing up button/consumer in HID report " - "descriptor\n"); - rdesc[30] = 0x0c; - } -} - -#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int mr_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) - return 0; - - switch (usage->hid & HID_USAGE) { - case 0x156: mr_map_key_clear(KEY_WORDPROCESSOR); break; - case 0x157: mr_map_key_clear(KEY_SPREADSHEET); break; - case 0x158: mr_map_key_clear(KEY_PRESENTATION); break; - case 0x15c: mr_map_key_clear(KEY_STOP); break; - default: - return 0; - } - return 1; -} - -static const struct hid_device_id mr_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, - { } -}; -MODULE_DEVICE_TABLE(hid, mr_devices); - -static struct hid_driver mr_driver = { - .name = "monterey", - .id_table = mr_devices, - .report_fixup = mr_report_fixup, - .input_mapping = mr_input_mapping, -}; - -static int mr_init(void) -{ - return hid_register_driver(&mr_driver); -} - -static void mr_exit(void) -{ - hid_unregister_driver(&mr_driver); -} - -module_init(mr_init); -module_exit(mr_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(monterey); diff --git a/trunk/drivers/hid/hid-petalynx.c b/trunk/drivers/hid/hid-petalynx.c deleted file mode 100644 index 10945fe12d50..000000000000 --- a/trunk/drivers/hid/hid-petalynx.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * HID driver for some petalynx "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -/* Petalynx Maxter Remote has maximum for consumer page set too low */ -static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && - rdesc[41] == 0x00 && rdesc[59] == 0x26 && - rdesc[60] == 0xf9 && rdesc[61] == 0x00) { - dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " - "descriptor\n"); - rdesc[60] = 0xfa; - rdesc[40] = 0xfa; - } -} - -#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int pl_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) { - switch (usage->hid & HID_USAGE) { - case 0x05a: pl_map_key_clear(KEY_TEXT); break; - case 0x05b: pl_map_key_clear(KEY_RED); break; - case 0x05c: pl_map_key_clear(KEY_GREEN); break; - case 0x05d: pl_map_key_clear(KEY_YELLOW); break; - case 0x05e: pl_map_key_clear(KEY_BLUE); break; - default: - return 0; - } - return 1; - } - - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { - switch (usage->hid & HID_USAGE) { - case 0x0f6: pl_map_key_clear(KEY_NEXT); break; - case 0x0fa: pl_map_key_clear(KEY_BACK); break; - default: - return 0; - } - return 1; - } - - return 0; -} - -static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - hdev->quirks |= HID_QUIRK_NOGET; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id pl_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, - { } -}; -MODULE_DEVICE_TABLE(hid, pl_devices); - -static struct hid_driver pl_driver = { - .name = "petalynx", - .id_table = pl_devices, - .report_fixup = pl_report_fixup, - .input_mapping = pl_input_mapping, - .probe = pl_probe, -}; - -static int pl_init(void) -{ - return hid_register_driver(&pl_driver); -} - -static void pl_exit(void) -{ - hid_unregister_driver(&pl_driver); -} - -module_init(pl_init); -module_exit(pl_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(petalynx); diff --git a/trunk/drivers/hid/hid-samsung.c b/trunk/drivers/hid/hid-samsung.c deleted file mode 100644 index 15f3c0492450..000000000000 --- a/trunk/drivers/hid/hid-samsung.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * HID driver for some samsung "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -/* - * Samsung IrDA remote controller (reports as Cypress USB Mouse). - * - * Vendor specific report #4 has a size of 48 bit, - * and therefore is not accepted when inspecting the descriptors. - * As a workaround we reinterpret the report as: - * Variable type, count 6, size 8 bit, log. maximum 255 - * The burden to reconstruct the data is moved into user space. - */ -static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && - rdesc[177] == 0x75 && rdesc[178] == 0x30 && - rdesc[179] == 0x95 && rdesc[180] == 0x01 && - rdesc[182] == 0x40) { - dev_info(&hdev->dev, "fixing up Samsung IrDA report " - "descriptor\n"); - rdesc[176] = 0xff; - rdesc[178] = 0x08; - rdesc[180] = 0x06; - rdesc[182] = 0x42; - } -} - -static int samsung_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) | - HID_CONNECT_HIDDEV_FORCE); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id samsung_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, - { } -}; -MODULE_DEVICE_TABLE(hid, samsung_devices); - -static struct hid_driver samsung_driver = { - .name = "samsung", - .id_table = samsung_devices, - .report_fixup = samsung_report_fixup, - .probe = samsung_probe, -}; - -static int samsung_init(void) -{ - return hid_register_driver(&samsung_driver); -} - -static void samsung_exit(void) -{ - hid_unregister_driver(&samsung_driver); -} - -module_init(samsung_init); -module_exit(samsung_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(samsung); diff --git a/trunk/drivers/hid/hid-sony.c b/trunk/drivers/hid/hid-sony.c deleted file mode 100644 index 3af8095a7de1..000000000000 --- a/trunk/drivers/hid/hid-sony.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * HID driver for some sony "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -#include "hid-ids.h" - -/* - * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller - * to "operational". Without this, the ps3 controller will not report any - * events. - */ -static int sony_set_operational(struct hid_device *hdev) -{ - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct usb_device *dev = interface_to_usbdev(intf); - __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; - int ret; - char *buf = kmalloc(18, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - HID_REQ_GET_REPORT, - USB_DIR_IN | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, - (3 << 8) | 0xf2, ifnum, buf, 17, - USB_CTRL_GET_TIMEOUT); - if (ret < 0) - dev_err(&hdev->dev, "can't set operational mode\n"); - - kfree(buf); - - return ret; -} - -static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | - HID_CONNECT_HIDDEV_FORCE); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - ret = sony_set_operational(hdev); - if (ret) - goto err_stop; - - return 0; -err_stop: - hid_hw_stop(hdev); -err_free: - return ret; -} - -static const struct hid_device_id sony_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, - { } -}; -MODULE_DEVICE_TABLE(hid, sony_devices); - -static struct hid_driver sony_driver = { - .name = "sony", - .id_table = sony_devices, - .probe = sony_probe, -}; - -static int sony_init(void) -{ - return hid_register_driver(&sony_driver); -} - -static void sony_exit(void) -{ - hid_unregister_driver(&sony_driver); -} - -module_init(sony_init); -module_exit(sony_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(sony); diff --git a/trunk/drivers/hid/hid-sunplus.c b/trunk/drivers/hid/hid-sunplus.c deleted file mode 100644 index 5ba68f7dbb78..000000000000 --- a/trunk/drivers/hid/hid-sunplus.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * HID driver for some sunplus "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include - -#include "hid-ids.h" - -static void sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int rsize) -{ - if (rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && - rdesc[106] == 0x03) { - dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " - "report descriptor\n"); - rdesc[105] = rdesc[110] = 0x03; - rdesc[106] = rdesc[111] = 0x21; - } -} - -#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) -static int sp_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) - return 0; - - switch (usage->hid & HID_USAGE) { - case 0x2003: sp_map_key_clear(KEY_ZOOMIN); break; - case 0x2103: sp_map_key_clear(KEY_ZOOMOUT); break; - default: - return 0; - } - return 1; -} - -static const struct hid_device_id sp_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, - { } -}; -MODULE_DEVICE_TABLE(hid, sp_devices); - -static struct hid_driver sp_driver = { - .name = "sunplus", - .id_table = sp_devices, - .report_fixup = sp_report_fixup, - .input_mapping = sp_input_mapping, -}; - -static int sp_init(void) -{ - return hid_register_driver(&sp_driver); -} - -static void sp_exit(void) -{ - hid_unregister_driver(&sp_driver); -} - -module_init(sp_init); -module_exit(sp_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(sunplus); diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index af3edb98df43..c40f0403edaf 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t if (!dev->hid_output_raw_report) return -ENODEV; - if (count > HID_MAX_BUFFER_SIZE) { + if (count > HID_MIN_BUFFER_SIZE) { printk(KERN_WARNING "hidraw: pid %d passed too large report\n", task_pid_nr(current)); return -EINVAL; @@ -181,7 +181,7 @@ static int hidraw_open(struct inode *inode, struct file *file) dev = hidraw_table[minor]; if (!dev->open++) - dev->hid->ll_driver->open(dev->hid); + dev->hid->hid_open(dev->hid); out_unlock: spin_unlock(&minors_lock); @@ -207,7 +207,7 @@ static int hidraw_release(struct inode * inode, struct file * file) dev = hidraw_table[minor]; if (!dev->open--) { if (list->hidraw->exist) - dev->hid->ll_driver->close(dev->hid); + dev->hid->hid_close(dev->hid); else kfree(list->hidraw); } @@ -326,8 +326,9 @@ int hidraw_connect(struct hid_device *hid) goto out; } - dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor), - NULL, "%s%d", "hidraw", minor); + dev->dev = device_create_drvdata(hidraw_class, NULL, + MKDEV(hidraw_major, minor), NULL, + "%s%d", "hidraw", minor); if (IS_ERR(dev->dev)) { spin_lock(&minors_lock); @@ -366,7 +367,7 @@ void hidraw_disconnect(struct hid_device *hid) device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); if (hidraw->open) { - hid->ll_driver->close(hid); + hid->hid_close(hid); wake_up_interruptible(&hidraw->wait); } else { kfree(hidraw); diff --git a/trunk/drivers/hid/usbhid/Kconfig b/trunk/drivers/hid/usbhid/Kconfig index 5d9aa95fc3ef..18f09104765c 100644 --- a/trunk/drivers/hid/usbhid/Kconfig +++ b/trunk/drivers/hid/usbhid/Kconfig @@ -24,13 +24,88 @@ config USB_HID comment "Input core support is needed for USB HID input layer or HIDBP support" depends on USB_HID && INPUT=n +config USB_HIDINPUT_POWERBOOK + bool "Enable support for Apple laptop/aluminum USB special keys" + default n + depends on USB_HID + help + Say Y here if you want support for the special keys (Fn, Numlock) on + Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB + keyboards. + + If unsure, say N. + +config HID_FF + bool "Force feedback support (EXPERIMENTAL)" + depends on USB_HID && EXPERIMENTAL + help + Say Y here is you want force feedback support for a few HID devices. + See below for a list of supported devices. + + See for a description of the force + feedback API. + + If unsure, say N. + config HID_PID bool "PID device support" + depends on HID_FF help Say Y here if you have a PID-compliant device and wish to enable force feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such devices. +config LOGITECH_FF + bool "Logitech devices support" + depends on HID_FF + select INPUT_FF_MEMLESS if USB_HID + help + Say Y here if you have one of these devices: + - Logitech WingMan Cordless RumblePad + - Logitech WingMan Cordless RumblePad 2 + - Logitech WingMan Force 3D + - Logitech Formula Force EX + - Logitech MOMO Force wheel + + and if you want to enable force feedback for them. + Note: if you say N here, this device will still be supported, but without + force feedback. + +config LOGIRUMBLEPAD2_FF + bool "Logitech Rumblepad 2 support" + depends on HID_FF + select INPUT_FF_MEMLESS if USB_HID + help + Say Y here if you want to enable force feedback support for Logitech + Rumblepad 2 devices. + +config PANTHERLORD_FF + bool "PantherLord/GreenAsia based device support" + depends on HID_FF + select INPUT_FF_MEMLESS if USB_HID + help + Say Y here if you have a PantherLord/GreenAsia based game controller + or adapter and want to enable force feedback support for it. + +config THRUSTMASTER_FF + bool "ThrustMaster devices support" + depends on HID_FF + select INPUT_FF_MEMLESS if USB_HID + help + Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or + a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel, + and want to enable force feedback support for it. + Note: if you say N here, this device will still be supported, but without + force feedback. + +config ZEROPLUS_FF + bool "Zeroplus based game controller support" + depends on HID_FF + select INPUT_FF_MEMLESS if USB_HID + help + Say Y here if you have a Zeroplus based game controller and want to + enable force feedback for it. + config USB_HIDDEV bool "/dev/hiddev raw HID device support" depends on USB_HID diff --git a/trunk/drivers/hid/usbhid/Makefile b/trunk/drivers/hid/usbhid/Makefile index 1329ecb37a1c..00a7b7090192 100644 --- a/trunk/drivers/hid/usbhid/Makefile +++ b/trunk/drivers/hid/usbhid/Makefile @@ -13,6 +13,24 @@ endif ifeq ($(CONFIG_HID_PID),y) usbhid-objs += hid-pidff.o endif +ifeq ($(CONFIG_LOGITECH_FF),y) + usbhid-objs += hid-lgff.o +endif +ifeq ($(CONFIG_LOGIRUMBLEPAD2_FF),y) + usbhid-objs += hid-lg2ff.o +endif +ifeq ($(CONFIG_PANTHERLORD_FF),y) + usbhid-objs += hid-plff.o +endif +ifeq ($(CONFIG_THRUSTMASTER_FF),y) + usbhid-objs += hid-tmff.o +endif +ifeq ($(CONFIG_ZEROPLUS_FF),y) + usbhid-objs += hid-zpff.o +endif +ifeq ($(CONFIG_HID_FF),y) + usbhid-objs += hid-ff.o +endif obj-$(CONFIG_USB_HID) += usbhid.o obj-$(CONFIG_USB_KBD) += usbkbd.o diff --git a/trunk/drivers/hid/usbhid/hid-core.c b/trunk/drivers/hid/usbhid/hid-core.c index 1d3b8a394d46..27fe4d8912cb 100644 --- a/trunk/drivers/hid/usbhid/hid-core.c +++ b/trunk/drivers/hid/usbhid/hid-core.c @@ -44,6 +44,8 @@ #define DRIVER_DESC "USB HID core driver" #define DRIVER_LICENSE "GPL" +static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", + "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; /* * Module parameters. */ @@ -59,6 +61,12 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " " quirks=vendorID:productID:quirks" " where vendorID, productID, and quirks are all in" " 0x-prefixed hex"); +static char *rdesc_quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; +module_param_array_named(rdesc_quirks, rdesc_quirks_param, charp, NULL, 0444); +MODULE_PARM_DESC(rdesc_quirks, "Add/modify report descriptor quirks by specifying " + " rdesc_quirks=vendorID:productID:rdesc_quirks" + " where vendorID, productID, and rdesc_quirks are all in" + " 0x-prefixed hex"); /* * Input submission and I/O error handler. */ @@ -189,32 +197,31 @@ static void hid_irq_in(struct urb *urb) int status; switch (urb->status) { - case 0: /* success */ - usbhid->retry_delay = 0; - hid_input_report(urb->context, HID_INPUT_REPORT, - urb->transfer_buffer, - urb->actual_length, 1); - break; - case -EPIPE: /* stall */ - clear_bit(HID_IN_RUNNING, &usbhid->iofl); - set_bit(HID_CLEAR_HALT, &usbhid->iofl); - schedule_work(&usbhid->reset_work); - return; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: /* unplug */ - clear_bit(HID_IN_RUNNING, &usbhid->iofl); - return; - case -EILSEQ: /* protocol error or unplug */ - case -EPROTO: /* protocol error or unplug */ - case -ETIME: /* protocol error or unplug */ - case -ETIMEDOUT: /* Should never happen, but... */ - clear_bit(HID_IN_RUNNING, &usbhid->iofl); - hid_io_error(hid); - return; - default: /* error */ - dev_warn(&urb->dev->dev, "input irq status %d " - "received\n", urb->status); + case 0: /* success */ + usbhid->retry_delay = 0; + hid_input_report(urb->context, HID_INPUT_REPORT, + urb->transfer_buffer, + urb->actual_length, 1); + break; + case -EPIPE: /* stall */ + clear_bit(HID_IN_RUNNING, &usbhid->iofl); + set_bit(HID_CLEAR_HALT, &usbhid->iofl); + schedule_work(&usbhid->reset_work); + return; + case -ECONNRESET: /* unlink */ + case -ENOENT: + case -ESHUTDOWN: /* unplug */ + clear_bit(HID_IN_RUNNING, &usbhid->iofl); + return; + case -EILSEQ: /* protocol error or unplug */ + case -EPROTO: /* protocol error or unplug */ + case -ETIME: /* protocol error or unplug */ + case -ETIMEDOUT: /* Should never happen, but... */ + clear_bit(HID_IN_RUNNING, &usbhid->iofl); + hid_io_error(hid); + return; + default: /* error */ + warn("input irq status %d received", urb->status); } status = usb_submit_urb(urb, GFP_ATOMIC); @@ -233,16 +240,13 @@ static void hid_irq_in(struct urb *urb) static int hid_submit_out(struct hid_device *hid) { struct hid_report *report; - char *raw_report; struct usbhid_device *usbhid = hid->driver_data; - report = usbhid->out[usbhid->outtail].report; - raw_report = usbhid->out[usbhid->outtail].raw_report; + report = usbhid->out[usbhid->outtail]; + hid_output_report(report, usbhid->outbuf); usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); usbhid->urbout->dev = hid_to_usb_dev(hid); - memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length); - kfree(raw_report); dbg_hid("submitting out urb\n"); @@ -258,20 +262,17 @@ static int hid_submit_ctrl(struct hid_device *hid) { struct hid_report *report; unsigned char dir; - char *raw_report; int len; struct usbhid_device *usbhid = hid->driver_data; report = usbhid->ctrl[usbhid->ctrltail].report; - raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; dir = usbhid->ctrl[usbhid->ctrltail].dir; len = ((report->size - 1) >> 3) + 1 + (report->id > 0); if (dir == USB_DIR_OUT) { + hid_output_report(report, usbhid->ctrlbuf); usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); usbhid->urbctrl->transfer_buffer_length = len; - memcpy(usbhid->ctrlbuf, raw_report, len); - kfree(raw_report); } else { int maxpacket, padlen; @@ -318,18 +319,17 @@ static void hid_irq_out(struct urb *urb) int unplug = 0; switch (urb->status) { - case 0: /* success */ - break; - case -ESHUTDOWN: /* unplug */ - unplug = 1; - case -EILSEQ: /* protocol error or unplug */ - case -EPROTO: /* protocol error or unplug */ - case -ECONNRESET: /* unlink */ - case -ENOENT: - break; - default: /* error */ - dev_warn(&urb->dev->dev, "output irq status %d " - "received\n", urb->status); + case 0: /* success */ + break; + case -ESHUTDOWN: /* unplug */ + unplug = 1; + case -EILSEQ: /* protocol error or unplug */ + case -EPROTO: /* protocol error or unplug */ + case -ECONNRESET: /* unlink */ + case -ENOENT: + break; + default: /* error */ + warn("output irq status %d received", urb->status); } spin_lock_irqsave(&usbhid->outlock, flags); @@ -367,23 +367,21 @@ static void hid_ctrl(struct urb *urb) spin_lock_irqsave(&usbhid->ctrllock, flags); switch (urb->status) { - case 0: /* success */ - if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) - hid_input_report(urb->context, - usbhid->ctrl[usbhid->ctrltail].report->type, - urb->transfer_buffer, urb->actual_length, 0); - break; - case -ESHUTDOWN: /* unplug */ - unplug = 1; - case -EILSEQ: /* protocol error or unplug */ - case -EPROTO: /* protocol error or unplug */ - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPIPE: /* report not available */ - break; - default: /* error */ - dev_warn(&urb->dev->dev, "ctrl urb status %d " - "received\n", urb->status); + case 0: /* success */ + if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) + hid_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type, + urb->transfer_buffer, urb->actual_length, 0); + break; + case -ESHUTDOWN: /* unplug */ + unplug = 1; + case -EILSEQ: /* protocol error or unplug */ + case -EPROTO: /* protocol error or unplug */ + case -ECONNRESET: /* unlink */ + case -ENOENT: + case -EPIPE: /* report not available */ + break; + default: /* error */ + warn("ctrl urb status %d received", urb->status); } if (unplug) @@ -410,7 +408,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns int head; unsigned long flags; struct usbhid_device *usbhid = hid->driver_data; - int len = ((report->size - 1) >> 3) + 1 + (report->id > 0); if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) return; @@ -421,18 +418,11 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { spin_unlock_irqrestore(&usbhid->outlock, flags); - dev_warn(&hid->dev, "output queue full\n"); + warn("output queue full"); return; } - usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); - if (!usbhid->out[usbhid->outhead].raw_report) { - spin_unlock_irqrestore(&usbhid->outlock, flags); - warn("output queueing failed"); - return; - } - hid_output_report(report, usbhid->out[usbhid->outhead].raw_report); - usbhid->out[usbhid->outhead].report = report; + usbhid->out[usbhid->outhead] = report; usbhid->outhead = head; if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) @@ -447,19 +437,10 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { spin_unlock_irqrestore(&usbhid->ctrllock, flags); - dev_warn(&hid->dev, "control queue full\n"); + warn("control queue full"); return; } - if (dir == USB_DIR_OUT) { - usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); - if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { - spin_unlock_irqrestore(&usbhid->ctrllock, flags); - warn("control queueing failed"); - return; - } - hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report); - } usbhid->ctrl[usbhid->ctrlhead].report = report; usbhid->ctrl[usbhid->ctrlhead].dir = dir; usbhid->ctrlhead = head; @@ -470,7 +451,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns spin_unlock_irqrestore(&usbhid->ctrllock, flags); } -EXPORT_SYMBOL_GPL(usbhid_submit_report); static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { @@ -485,7 +465,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un return -1; if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { - dev_warn(&dev->dev, "event field not found\n"); + warn("event field not found"); return -1; } @@ -588,7 +568,7 @@ void usbhid_init_reports(struct hid_device *hid) } if (err) - dev_warn(&hid->dev, "timeout initializing reports\n"); + warn("timeout initializing reports"); } /* @@ -618,7 +598,7 @@ static int hid_find_field_early(struct hid_device *hid, unsigned int page, return -1; } -void usbhid_set_leds(struct hid_device *hid) +static void usbhid_set_leds(struct hid_device *hid) { struct hid_field *field; int offset; @@ -628,7 +608,6 @@ void usbhid_set_leds(struct hid_device *hid) usbhid_submit_report(hid, field->report, USB_DIR_OUT); } } -EXPORT_SYMBOL_GPL(usbhid_set_leds); /* * Traverse the supplied list of reports and find the longest @@ -696,16 +675,43 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); } -static int usbhid_parse(struct hid_device *hid) +/* + * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller + * to "operational". Without this, the ps3 controller will not report any + * events. + */ +static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) +{ + int result; + char *buf = kmalloc(18, GFP_KERNEL); + + if (!buf) + return; + + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + HID_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, + (3 << 8) | 0xf2, ifnum, buf, 17, + USB_CTRL_GET_TIMEOUT); + + if (result < 0) + err_hid("%s failed: %d\n", __func__, result); + + kfree(buf); +} + +static struct hid_device *usb_hid_configure(struct usb_interface *intf) { - struct usb_interface *intf = to_usb_interface(hid->dev.parent); struct usb_host_interface *interface = intf->cur_altsetting; struct usb_device *dev = interface_to_usbdev (intf); struct hid_descriptor *hdesc; + struct hid_device *hid; u32 quirks = 0; - unsigned int rsize = 0; + unsigned int insize = 0, rsize = 0; char *rdesc; - int ret, n; + int n, len; + struct usbhid_device *usbhid; quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); @@ -718,75 +724,63 @@ static int usbhid_parse(struct hid_device *hid) quirks |= HID_QUIRK_NOGET; } + if (quirks & HID_QUIRK_IGNORE) + return NULL; + + if ((quirks & HID_QUIRK_IGNORE_MOUSE) && + (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)) + return NULL; + + if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && (!interface->desc.bNumEndpoints || usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { dbg_hid("class descriptor not present\n"); - return -ENODEV; + return NULL; } - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - for (n = 0; n < hdesc->bNumDescriptors; n++) if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { dbg_hid("weird size of report descriptor (%u)\n", rsize); - return -EINVAL; + return NULL; } if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { dbg_hid("couldn't allocate rdesc memory\n"); - return -ENOMEM; + return NULL; } hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); - ret = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, - HID_DT_REPORT, rdesc, rsize); - if (ret < 0) { + if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { dbg_hid("reading report descriptor failed\n"); kfree(rdesc); - goto err; + return NULL; } + usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct), rdesc, + rsize, rdesc_quirks_param); + dbg_hid("report descriptor (size %u, read %d) = ", rsize, n); for (n = 0; n < rsize; n++) dbg_hid_line(" %02x", (unsigned char) rdesc[n]); dbg_hid_line("\n"); - ret = hid_parse_report(hid, rdesc, rsize); - kfree(rdesc); - if (ret) { + if (!(hid = hid_parse_report(rdesc, n))) { dbg_hid("parsing report descriptor failed\n"); - goto err; + kfree(rdesc); + return NULL; } + kfree(rdesc); hid->quirks = quirks; - return 0; -err: - return ret; -} - -static int usbhid_start(struct hid_device *hid) -{ - struct usb_interface *intf = to_usb_interface(hid->dev.parent); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev(intf); - struct usbhid_device *usbhid; - unsigned int n, insize = 0; - int ret; - - WARN_ON(hid->driver_data); - - usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL); - if (usbhid == NULL) { - ret = -ENOMEM; - goto err; - } + if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL))) + goto fail_no_usbhid; hid->driver_data = usbhid; usbhid->hid = hid; @@ -805,11 +799,28 @@ static int usbhid_start(struct hid_device *hid) insize = HID_MAX_BUFFER_SIZE; if (hid_alloc_buffers(dev, hid)) { - ret = -ENOMEM; + hid_free_buffers(dev, hid); goto fail; } + hid->name[0] = 0; + + if (dev->manufacturer) + strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); + + if (dev->product) { + if (dev->manufacturer) + strlcat(hid->name, " ", sizeof(hid->name)); + strlcat(hid->name, dev->product, sizeof(hid->name)); + } + + if (!strlen(hid->name)) + snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); + for (n = 0; n < interface->desc.bNumEndpoints; n++) { + struct usb_endpoint_descriptor *endpoint; int pipe; int interval; @@ -821,7 +832,7 @@ static int usbhid_start(struct hid_device *hid) interval = endpoint->bInterval; /* Some vendors give fullspeed interval on highspeed devides */ - if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL && + if (quirks & HID_QUIRK_FULLSPEED_INTERVAL && dev->speed == USB_SPEED_HIGH) { interval = fls(endpoint->bInterval*8); printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n", @@ -832,7 +843,6 @@ static int usbhid_start(struct hid_device *hid) if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) interval = hid_mousepoll_interval; - ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { if (usbhid->urbin) continue; @@ -858,7 +868,6 @@ static int usbhid_start(struct hid_device *hid) if (!usbhid->urbin) { err_hid("couldn't find an input interrupt endpoint"); - ret = -ENODEV; goto fail; } @@ -870,25 +879,44 @@ static int usbhid_start(struct hid_device *hid) spin_lock_init(&usbhid->outlock); spin_lock_init(&usbhid->ctrllock); + hid->version = le16_to_cpu(hdesc->bcdHID); + hid->country = hdesc->bCountryCode; + hid->dev = &intf->dev; usbhid->intf = intf; usbhid->ifnum = interface->desc.bInterfaceNumber; + hid->bus = BUS_USB; + hid->vendor = le16_to_cpu(dev->descriptor.idVendor); + hid->product = le16_to_cpu(dev->descriptor.idProduct); + + usb_make_path(dev, hid->phys, sizeof(hid->phys)); + strlcat(hid->phys, "/input", sizeof(hid->phys)); + len = strlen(hid->phys); + if (len < sizeof(hid->phys) - 1) + snprintf(hid->phys + len, sizeof(hid->phys) - len, + "%d", intf->altsetting[0].desc.bInterfaceNumber); + + if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) + hid->uniq[0] = 0; + usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!usbhid->urbctrl) { - ret = -ENOMEM; + if (!usbhid->urbctrl) goto fail; - } usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr, usbhid->ctrlbuf, 1, hid_ctrl, hid); usbhid->urbctrl->setup_dma = usbhid->cr_dma; usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); - - usbhid_init_reports(hid); - hid_dump_device(hid); - - return 0; + hid->hidinput_input_event = usb_hidinput_input_event; + hid->hid_open = usbhid_open; + hid->hid_close = usbhid_close; +#ifdef CONFIG_USB_HIDDEV + hid->hiddev_hid_event = hiddev_hid_event; + hid->hiddev_report_event = hiddev_report_event; +#endif + hid->hid_output_raw_report = usbhid_output_raw_report; + return hid; fail: usb_free_urb(usbhid->urbin); @@ -896,18 +924,24 @@ static int usbhid_start(struct hid_device *hid) usb_free_urb(usbhid->urbctrl); hid_free_buffers(dev, hid); kfree(usbhid); -err: - return ret; +fail_no_usbhid: + hid_free_device(hid); + + return NULL; } -static void usbhid_stop(struct hid_device *hid) +static void hid_disconnect(struct usb_interface *intf) { - struct usbhid_device *usbhid = hid->driver_data; + struct hid_device *hid = usb_get_intfdata (intf); + struct usbhid_device *usbhid; - if (WARN_ON(!usbhid)) + if (!hid) return; + usbhid = hid->driver_data; + spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ + usb_set_intfdata(intf, NULL); set_bit(HID_DISCONNECTED, &usbhid->iofl); spin_unlock_irq(&usbhid->inlock); usb_kill_urb(usbhid->urbin); @@ -924,100 +958,86 @@ static void usbhid_stop(struct hid_device *hid) if (hid->claimed & HID_CLAIMED_HIDRAW) hidraw_disconnect(hid); - hid->claimed = 0; - usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbctrl); usb_free_urb(usbhid->urbout); hid_free_buffers(hid_to_usb_dev(hid), hid); kfree(usbhid); - hid->driver_data = NULL; + hid_free_device(hid); } -static struct hid_ll_driver usb_hid_driver = { - .parse = usbhid_parse, - .start = usbhid_start, - .stop = usbhid_stop, - .open = usbhid_open, - .close = usbhid_close, - .hidinput_input_event = usb_hidinput_input_event, -}; - static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev = interface_to_usbdev(intf); struct hid_device *hid; - size_t len; - int ret; + char path[64]; + int i; + char *c; dbg_hid("HID probe called for ifnum %d\n", intf->altsetting->desc.bInterfaceNumber); - hid = hid_allocate_device(); - if (IS_ERR(hid)) - return PTR_ERR(hid); + if (!(hid = usb_hid_configure(intf))) + return -ENODEV; - usb_set_intfdata(intf, hid); - hid->ll_driver = &usb_hid_driver; - hid->hid_output_raw_report = usbhid_output_raw_report; - hid->ff_init = hid_pidff_init; -#ifdef CONFIG_USB_HIDDEV - hid->hiddev_connect = hiddev_connect; - hid->hiddev_hid_event = hiddev_hid_event; - hid->hiddev_report_event = hiddev_report_event; -#endif - hid->dev.parent = &intf->dev; - hid->bus = BUS_USB; - hid->vendor = le16_to_cpu(dev->descriptor.idVendor); - hid->product = le16_to_cpu(dev->descriptor.idProduct); - hid->name[0] = 0; + usbhid_init_reports(hid); + hid_dump_device(hid); + if (hid->quirks & HID_QUIRK_RESET_LEDS) + usbhid_set_leds(hid); - if (dev->manufacturer) - strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); + if (!hidinput_connect(hid)) + hid->claimed |= HID_CLAIMED_INPUT; + if (!hiddev_connect(hid)) + hid->claimed |= HID_CLAIMED_HIDDEV; + if (!hidraw_connect(hid)) + hid->claimed |= HID_CLAIMED_HIDRAW; - if (dev->product) { - if (dev->manufacturer) - strlcat(hid->name, " ", sizeof(hid->name)); - strlcat(hid->name, dev->product, sizeof(hid->name)); + usb_set_intfdata(intf, hid); + + if (!hid->claimed) { + printk ("HID device claimed by neither input, hiddev nor hidraw\n"); + hid_disconnect(intf); + return -ENODEV; } - if (!strlen(hid->name)) - snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); + if ((hid->claimed & HID_CLAIMED_INPUT)) + hid_ff_init(hid); - usb_make_path(dev, hid->phys, sizeof(hid->phys)); - strlcat(hid->phys, "/input", sizeof(hid->phys)); - len = strlen(hid->phys); - if (len < sizeof(hid->phys) - 1) - snprintf(hid->phys + len, sizeof(hid->phys) - len, - "%d", intf->altsetting[0].desc.bInterfaceNumber); + if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) + hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), + intf->cur_altsetting->desc.bInterfaceNumber); - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; + printk(KERN_INFO); - ret = hid_add_device(hid); - if (ret) { - if (ret != -ENODEV) - dev_err(&intf->dev, "can't add hid device: %d\n", ret); - goto err; + if (hid->claimed & HID_CLAIMED_INPUT) + printk("input"); + if ((hid->claimed & HID_CLAIMED_INPUT) && ((hid->claimed & HID_CLAIMED_HIDDEV) || + hid->claimed & HID_CLAIMED_HIDRAW)) + printk(","); + if (hid->claimed & HID_CLAIMED_HIDDEV) + printk("hiddev%d", hid->minor); + if ((hid->claimed & HID_CLAIMED_INPUT) && (hid->claimed & HID_CLAIMED_HIDDEV) && + (hid->claimed & HID_CLAIMED_HIDRAW)) + printk(","); + if (hid->claimed & HID_CLAIMED_HIDRAW) + printk("hidraw%d", ((struct hidraw*)hid->hidraw)->minor); + + c = "Device"; + for (i = 0; i < hid->maxcollection; i++) { + if (hid->collection[i].type == HID_COLLECTION_APPLICATION && + (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && + (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { + c = hid_types[hid->collection[i].usage & 0xffff]; + break; + } } - return 0; -err: - hid_destroy_device(hid); - return ret; -} + usb_make_path(interface_to_usbdev(intf), path, 63); -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata(intf); + printk(": USB HID v%x.%02x %s [%s] on %s\n", + hid->version >> 8, hid->version & 0xff, c, hid->name, path); - if (WARN_ON(!hid)) - return; - - hid_destroy_device(hid); + return 0; } static int hid_suspend(struct usb_interface *intf, pm_message_t message) @@ -1087,22 +1107,9 @@ static struct usb_driver hid_driver = { .supports_autosuspend = 1, }; -static const struct hid_device_id hid_usb_table[] = { - { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, - { } -}; - -static struct hid_driver hid_usb_driver = { - .name = "generic-usb", - .id_table = hid_usb_table, -}; - static int __init hid_init(void) { int retval; - retval = hid_register_driver(&hid_usb_driver); - if (retval) - goto hid_register_fail; retval = usbhid_quirks_init(quirks_param); if (retval) goto usbhid_quirks_init_fail; @@ -1112,8 +1119,7 @@ static int __init hid_init(void) retval = usb_register(&hid_driver); if (retval) goto usb_register_fail; - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_VERSION ":" DRIVER_DESC); return 0; usb_register_fail: @@ -1121,8 +1127,6 @@ static int __init hid_init(void) hiddev_init_fail: usbhid_quirks_exit(); usbhid_quirks_init_fail: - hid_unregister_driver(&hid_usb_driver); -hid_register_fail: return retval; } @@ -1131,7 +1135,6 @@ static void __exit hid_exit(void) usb_deregister(&hid_driver); hiddev_exit(); usbhid_quirks_exit(); - hid_unregister_driver(&hid_usb_driver); } module_init(hid_init); diff --git a/trunk/drivers/hid/usbhid/hid-ff.c b/trunk/drivers/hid/usbhid/hid-ff.c new file mode 100644 index 000000000000..1d0dac52f166 --- /dev/null +++ b/trunk/drivers/hid/usbhid/hid-ff.c @@ -0,0 +1,95 @@ +/* + * Force feedback support for hid devices. + * Not all hid devices use the same protocol. For example, some use PID, + * other use their own proprietary procotol. + * + * Copyright (c) 2002-2004 Johann Deneux + */ + +/* + * 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 + * + * Should you need to contact me, the author, you can do so by + * e-mail - mail your message to + */ + +#include + +#undef DEBUG +#include + +#include +#include "usbhid.h" + +/* + * This table contains pointers to initializers. To add support for new + * devices, you need to add the USB vendor and product ids here. + */ +struct hid_ff_initializer { + u16 idVendor; + u16 idProduct; + int (*init)(struct hid_device*); +}; + +/* + * We try pidff when no other driver is found because PID is the + * standards compliant way of implementing force feedback in HID. + * pidff_init() will quickly abort if the device doesn't appear to + * be a PID device + */ +static struct hid_ff_initializer inits[] = { +#ifdef CONFIG_LOGITECH_FF + { 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */ + { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ + { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */ + { 0x46d, 0xc286, hid_lgff_init }, /* Logitech Force 3D Pro Joystick */ + { 0x46d, 0xc294, hid_lgff_init }, /* Logitech Formula Force EX */ + { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ + { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */ +#endif +#ifdef CONFIG_LOGIRUMBLEPAD2_FF + { 0x46d, 0xc218, hid_lg2ff_init }, /* Logitech Rumblepad 2 */ +#endif +#ifdef CONFIG_PANTHERLORD_FF + { 0x810, 0x0001, hid_plff_init }, /* "Twin USB Joystick" */ + { 0xe8f, 0x0003, hid_plff_init }, /* "GreenAsia Inc. USB Joystick " */ +#endif +#ifdef CONFIG_THRUSTMASTER_FF + { 0x44f, 0xb300, hid_tmff_init }, + { 0x44f, 0xb304, hid_tmff_init }, + { 0x44f, 0xb651, hid_tmff_init }, /* FGT Rumble Force Wheel */ + { 0x44f, 0xb654, hid_tmff_init }, /* FGT Force Feedback Wheel */ +#endif +#ifdef CONFIG_ZEROPLUS_FF + { 0xc12, 0x0005, hid_zpff_init }, + { 0xc12, 0x0030, hid_zpff_init }, +#endif + { 0, 0, hid_pidff_init} /* Matches anything */ +}; + +int hid_ff_init(struct hid_device* hid) +{ + struct hid_ff_initializer *init; + int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor); + int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct); + + for (init = inits; init->idVendor; init++) + if (init->idVendor == vendor && init->idProduct == product) + break; + + return init->init(hid); +} +EXPORT_SYMBOL_GPL(hid_ff_init); + diff --git a/trunk/drivers/hid/hid-lg2ff.c b/trunk/drivers/hid/usbhid/hid-lg2ff.c similarity index 90% rename from trunk/drivers/hid/hid-lg2ff.c rename to trunk/drivers/hid/usbhid/hid-lg2ff.c index 4e6dc6e26523..d469bd0061c9 100644 --- a/trunk/drivers/hid/hid-lg2ff.c +++ b/trunk/drivers/hid/usbhid/hid-lg2ff.c @@ -24,9 +24,7 @@ #include #include #include - -#include "usbhid/usbhid.h" -#include "hid-lg.h" +#include "usbhid.h" struct lg2ff_device { struct hid_report *report; @@ -59,7 +57,7 @@ static int play_effect(struct input_dev *dev, void *data, return 0; } -int lg2ff_init(struct hid_device *hid) +int hid_lg2ff_init(struct hid_device *hid) { struct lg2ff_device *lg2ff; struct hid_report *report; @@ -71,18 +69,18 @@ int lg2ff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output report found\n"); + printk(KERN_ERR "hid-lg2ff: no output report found\n"); return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "output report is empty\n"); + printk(KERN_ERR "hid-lg2ff: output report is empty\n"); return -ENODEV; } if (report->field[0]->report_count < 7) { - dev_err(&hid->dev, "not enough values in the field\n"); + printk(KERN_ERR "hid-lg2ff: not enough values in the field\n"); return -ENODEV; } @@ -109,7 +107,7 @@ int lg2ff_init(struct hid_device *hid) usbhid_submit_report(hid, report, USB_DIR_OUT); - dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by " + printk(KERN_INFO "Force feedback for Logitech Rumblepad 2 by " "Anssi Hannula \n"); return 0; diff --git a/trunk/drivers/hid/hid-lgff.c b/trunk/drivers/hid/usbhid/hid-lgff.c similarity index 81% rename from trunk/drivers/hid/hid-lgff.c rename to trunk/drivers/hid/usbhid/hid-lgff.c index 51aff08e10ce..4b7ab6a46d93 100644 --- a/trunk/drivers/hid/hid-lgff.c +++ b/trunk/drivers/hid/usbhid/hid-lgff.c @@ -30,9 +30,7 @@ #include #include #include - -#include "usbhid/usbhid.h" -#include "hid-lg.h" +#include "usbhid.h" struct dev_type { u16 idVendor; @@ -50,12 +48,6 @@ static const signed short ff_joystick[] = { -1 }; -static const signed short ff_wheel[] = { - FF_CONSTANT, - FF_AUTOCENTER, - -1 -}; - static const struct dev_type devices[] = { { 0x046d, 0xc211, ff_rumble }, { 0x046d, 0xc219, ff_rumble }, @@ -63,7 +55,7 @@ static const struct dev_type devices[] = { { 0x046d, 0xc286, ff_joystick }, { 0x046d, 0xc294, ff_joystick }, { 0x046d, 0xc295, ff_joystick }, - { 0x046d, 0xca03, ff_wheel }, + { 0x046d, 0xca03, ff_joystick }, }; static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect) @@ -108,24 +100,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef return 0; } -static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) -{ - struct hid_device *hid = input_get_drvdata(dev); - struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct hid_report *report = list_entry(report_list->next, struct hid_report, list); - __s32 *value = report->field[0]->value; - magnitude = (magnitude >> 12) & 0xf; - *value++ = 0xfe; - *value++ = 0x0d; - *value++ = magnitude; /* clockwise strength */ - *value++ = magnitude; /* counter-clockwise strength */ - *value++ = 0x80; - *value++ = 0x00; - *value = 0x00; - usbhid_submit_report(hid, report, USB_DIR_OUT); -} - -int lgff_init(struct hid_device* hid) +int hid_lgff_init(struct hid_device* hid) { struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; @@ -170,9 +145,6 @@ int lgff_init(struct hid_device* hid) if (error) return error; - if ( test_bit(FF_AUTOCENTER, dev->ffbit) ) - dev->ff->set_autocenter = hid_lgff_set_autocenter; - printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux \n"); return 0; diff --git a/trunk/drivers/hid/usbhid/hid-pidff.c b/trunk/drivers/hid/usbhid/hid-pidff.c index 484e3eec2f88..011326178c06 100644 --- a/trunk/drivers/hid/usbhid/hid-pidff.c +++ b/trunk/drivers/hid/usbhid/hid-pidff.c @@ -397,6 +397,7 @@ static void pidff_set_condition_report(struct pidff_device *pidff, effect->u.condition[i].left_saturation); pidff_set(&pidff->set_condition[PID_DEAD_BAND], effect->u.condition[i].deadband); + usbhid_wait_io(pidff->hid); usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], USB_DIR_OUT); } @@ -511,6 +512,7 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n) pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; } + usbhid_wait_io(pidff->hid); usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], USB_DIR_OUT); } @@ -546,9 +548,6 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id) int pid_id = pidff->pid_id[effect_id]; debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]); - /* Wait for the queue to clear. We do not want a full fifo to - prevent the effect removal. */ - usbhid_wait_io(pidff->hid); pidff_playback_pid(pidff, pid_id, 0); pidff_erase_pid(pidff, pid_id); diff --git a/trunk/drivers/hid/hid-pl.c b/trunk/drivers/hid/usbhid/hid-plff.c similarity index 68% rename from trunk/drivers/hid/hid-pl.c rename to trunk/drivers/hid/usbhid/hid-plff.c index acd815586182..9eb83cf9d22b 100644 --- a/trunk/drivers/hid/hid-pl.c +++ b/trunk/drivers/hid/usbhid/hid-plff.c @@ -9,7 +9,7 @@ * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT) * * 0e8f:0003 "GreenAsia Inc. USB Joystick " - * - tested with K??ng Gaming gamepad + * - tested with Köng Gaming gamepad * * Copyright (c) 2007 Anssi Hannula */ @@ -38,11 +38,7 @@ #include #include #include - -#include "hid-ids.h" - -#ifdef CONFIG_PANTHERLORD_FF -#include "usbhid/usbhid.h" +#include "usbhid.h" struct plff_device { struct hid_report *report; @@ -70,7 +66,7 @@ static int hid_plff_play(struct input_dev *dev, void *data, return 0; } -static int plff_init(struct hid_device *hid) +int hid_plff_init(struct hid_device *hid) { struct plff_device *plff; struct hid_report *report; @@ -90,7 +86,7 @@ static int plff_init(struct hid_device *hid) currently unknown. */ if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + printk(KERN_ERR "hid-plff: no output reports found\n"); return -ENODEV; } @@ -99,19 +95,18 @@ static int plff_init(struct hid_device *hid) report_ptr = report_ptr->next; if (report_ptr == report_list) { - dev_err(&hid->dev, "required output report is " - "missing\n"); + printk(KERN_ERR "hid-plff: required output report is missing\n"); return -ENODEV; } report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "no fields in the report\n"); + printk(KERN_ERR "hid-plff: no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 4) { - dev_err(&hid->dev, "not enough values in the field\n"); + printk(KERN_ERR "hid-plff: not enough values in the field\n"); return -ENODEV; } @@ -137,70 +132,8 @@ static int plff_init(struct hid_device *hid) usbhid_submit_report(hid, plff->report, USB_DIR_OUT); } - dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia " + printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia " "devices by Anssi Hannula \n"); return 0; } -#else -static inline int plff_init(struct hid_device *hid) -{ - return 0; -} -#endif - -static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - if (id->driver_data) - hdev->quirks |= HID_QUIRK_MULTI_INPUT; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err; - } - - plff_init(hdev); - - return 0; -err: - return ret; -} - -static const struct hid_device_id pl_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR), - .driver_data = 1 }, /* Twin USB Joystick */ - { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */ - { } -}; -MODULE_DEVICE_TABLE(hid, pl_devices); - -static struct hid_driver pl_driver = { - .name = "pantherlord", - .id_table = pl_devices, - .probe = pl_probe, -}; - -static int pl_init(void) -{ - return hid_register_driver(&pl_driver); -} - -static void pl_exit(void) -{ - hid_unregister_driver(&pl_driver); -} - -module_init(pl_init); -module_exit(pl_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(pantherlord); diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index 47ebe045f9b5..b15f88249639 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -17,7 +17,412 @@ #include -#include "../hid-ids.h" +#define USB_VENDOR_ID_A4TECH 0x09da +#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 +#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a + +#define USB_VENDOR_ID_AASHIMA 0x06d6 +#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 +#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 + +#define USB_VENDOR_ID_ACECAD 0x0460 +#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 +#define USB_DEVICE_ID_ACECAD_302 0x0008 + +#define USB_VENDOR_ID_ADS_TECH 0x06e1 +#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 + +#define USB_VENDOR_ID_AFATECH 0x15a4 +#define USB_DEVICE_ID_AFATECH_AF9016 0x9016 + +#define USB_VENDOR_ID_AIPTEK 0x08ca +#define USB_DEVICE_ID_AIPTEK_01 0x0001 +#define USB_DEVICE_ID_AIPTEK_10 0x0010 +#define USB_DEVICE_ID_AIPTEK_20 0x0020 +#define USB_DEVICE_ID_AIPTEK_21 0x0021 +#define USB_DEVICE_ID_AIPTEK_22 0x0022 +#define USB_DEVICE_ID_AIPTEK_23 0x0023 +#define USB_DEVICE_ID_AIPTEK_24 0x0024 + +#define USB_VENDOR_ID_AIRCABLE 0x16CA +#define USB_DEVICE_ID_AIRCABLE1 0x1502 + +#define USB_VENDOR_ID_ALCOR 0x058f +#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 + +#define USB_VENDOR_ID_ALPS 0x0433 +#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 + +#define USB_VENDOR_ID_APPLE 0x05ac +#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 +#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e +#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f +#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 +#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 +#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 +#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 +#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 +#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 +#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a +#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b +#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c +#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 +#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 +#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 +#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 +#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 +#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 +#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 +#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a +#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b +#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c +#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d +#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e +#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 +#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 +#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 +#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a +#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b +#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 + +#define USB_VENDOR_ID_ASUS 0x0b05 +#define USB_DEVICE_ID_ASUS_LCM 0x1726 + +#define USB_VENDOR_ID_ATEN 0x0557 +#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 +#define USB_DEVICE_ID_ATEN_CS124U 0x2202 +#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 +#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 +#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 + +#define USB_VENDOR_ID_BELKIN 0x050d +#define USB_DEVICE_ID_FLIP_KVM 0x3201 + +#define USB_VENDOR_ID_BERKSHIRE 0x0c98 +#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 + +#define USB_VENDOR_ID_CHERRY 0x046a +#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 + +#define USB_VENDOR_ID_CHIC 0x05fe +#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 + +#define USB_VENDOR_ID_CIDC 0x1677 + +#define USB_VENDOR_ID_CMEDIA 0x0d8c +#define USB_DEVICE_ID_CM109 0x000e + +#define USB_VENDOR_ID_CODEMERCS 0x07c0 +#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 +#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff + +#define USB_VENDOR_ID_CYGNAL 0x10c4 +#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a + +#define USB_VENDOR_ID_CYPRESS 0x04b4 +#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 +#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 +#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 +#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 +#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 + +#define USB_VENDOR_ID_DELL 0x413c +#define USB_DEVICE_ID_DELL_W7658 0x2005 + +#define USB_VENDOR_ID_DELORME 0x1163 +#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 +#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 + +#define USB_VENDOR_ID_DMI 0x0c0b +#define USB_DEVICE_ID_DMI_ENC 0x5fab + +#define USB_VENDOR_ID_ELO 0x04E7 +#define USB_DEVICE_ID_ELO_TS2700 0x0020 + +#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f +#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 + +#define USB_VENDOR_ID_EZKEY 0x0518 +#define USB_DEVICE_ID_BTC_8193 0x0002 + +#define USB_VENDOR_ID_GAMERON 0x0810 +#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 + +#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc + +#define USB_VENDOR_ID_GLAB 0x06c2 +#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 +#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 +#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 +#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044 +#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 +#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051 +#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 +#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 + +#define USB_VENDOR_ID_GOTOP 0x08f2 +#define USB_DEVICE_ID_SUPER_Q2 0x007f +#define USB_DEVICE_ID_GOGOPEN 0x00ce +#define USB_DEVICE_ID_PENPOWER 0x00f4 + +#define USB_VENDOR_ID_GRETAGMACBETH 0x0971 +#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 + +#define USB_VENDOR_ID_GRIFFIN 0x077d +#define USB_DEVICE_ID_POWERMATE 0x0410 +#define USB_DEVICE_ID_SOUNDKNOB 0x04AA + +#define USB_VENDOR_ID_GTCO 0x078c +#define USB_DEVICE_ID_GTCO_90 0x0090 +#define USB_DEVICE_ID_GTCO_100 0x0100 +#define USB_DEVICE_ID_GTCO_101 0x0101 +#define USB_DEVICE_ID_GTCO_103 0x0103 +#define USB_DEVICE_ID_GTCO_104 0x0104 +#define USB_DEVICE_ID_GTCO_105 0x0105 +#define USB_DEVICE_ID_GTCO_106 0x0106 +#define USB_DEVICE_ID_GTCO_107 0x0107 +#define USB_DEVICE_ID_GTCO_108 0x0108 +#define USB_DEVICE_ID_GTCO_200 0x0200 +#define USB_DEVICE_ID_GTCO_201 0x0201 +#define USB_DEVICE_ID_GTCO_202 0x0202 +#define USB_DEVICE_ID_GTCO_203 0x0203 +#define USB_DEVICE_ID_GTCO_204 0x0204 +#define USB_DEVICE_ID_GTCO_205 0x0205 +#define USB_DEVICE_ID_GTCO_206 0x0206 +#define USB_DEVICE_ID_GTCO_207 0x0207 +#define USB_DEVICE_ID_GTCO_300 0x0300 +#define USB_DEVICE_ID_GTCO_301 0x0301 +#define USB_DEVICE_ID_GTCO_302 0x0302 +#define USB_DEVICE_ID_GTCO_303 0x0303 +#define USB_DEVICE_ID_GTCO_304 0x0304 +#define USB_DEVICE_ID_GTCO_305 0x0305 +#define USB_DEVICE_ID_GTCO_306 0x0306 +#define USB_DEVICE_ID_GTCO_307 0x0307 +#define USB_DEVICE_ID_GTCO_308 0x0308 +#define USB_DEVICE_ID_GTCO_309 0x0309 +#define USB_DEVICE_ID_GTCO_400 0x0400 +#define USB_DEVICE_ID_GTCO_401 0x0401 +#define USB_DEVICE_ID_GTCO_402 0x0402 +#define USB_DEVICE_ID_GTCO_403 0x0403 +#define USB_DEVICE_ID_GTCO_404 0x0404 +#define USB_DEVICE_ID_GTCO_405 0x0405 +#define USB_DEVICE_ID_GTCO_500 0x0500 +#define USB_DEVICE_ID_GTCO_501 0x0501 +#define USB_DEVICE_ID_GTCO_502 0x0502 +#define USB_DEVICE_ID_GTCO_503 0x0503 +#define USB_DEVICE_ID_GTCO_504 0x0504 +#define USB_DEVICE_ID_GTCO_1000 0x1000 +#define USB_DEVICE_ID_GTCO_1001 0x1001 +#define USB_DEVICE_ID_GTCO_1002 0x1002 +#define USB_DEVICE_ID_GTCO_1003 0x1003 +#define USB_DEVICE_ID_GTCO_1004 0x1004 +#define USB_DEVICE_ID_GTCO_1005 0x1005 +#define USB_DEVICE_ID_GTCO_1006 0x1006 +#define USB_DEVICE_ID_GTCO_1007 0x1007 +#define USB_VENDOR_ID_HAPP 0x078b +#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 +#define USB_DEVICE_ID_UGCI_FLYING 0x0020 +#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 + +#define USB_VENDOR_ID_IMATION 0x0718 +#define USB_DEVICE_ID_DISC_STAKKA 0xd000 + +#define USB_VENDOR_ID_KBGEAR 0x084e +#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 + +#define USB_VENDOR_ID_LD 0x0f11 +#define USB_DEVICE_ID_LD_CASSY 0x1000 +#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 +#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 +#define USB_DEVICE_ID_LD_JWM 0x1080 +#define USB_DEVICE_ID_LD_DMMP 0x1081 +#define USB_DEVICE_ID_LD_UMIP 0x1090 +#define USB_DEVICE_ID_LD_XRAY1 0x1100 +#define USB_DEVICE_ID_LD_XRAY2 0x1101 +#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 +#define USB_DEVICE_ID_LD_COM3LAB 0x2000 +#define USB_DEVICE_ID_LD_TELEPORT 0x2010 +#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 +#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 +#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 + +#define USB_VENDOR_ID_LOGITECH 0x046d +#define USB_DEVICE_ID_LOGITECH_LX3 0xc044 +#define USB_DEVICE_ID_LOGITECH_V150 0xc047 +#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 +#define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110 +#define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111 +#define USB_DEVICE_ID_LOGITECH_HARMONY_3 0xc112 +#define USB_DEVICE_ID_LOGITECH_HARMONY_4 0xc113 +#define USB_DEVICE_ID_LOGITECH_HARMONY_5 0xc114 +#define USB_DEVICE_ID_LOGITECH_HARMONY_6 0xc115 +#define USB_DEVICE_ID_LOGITECH_HARMONY_7 0xc116 +#define USB_DEVICE_ID_LOGITECH_HARMONY_8 0xc117 +#define USB_DEVICE_ID_LOGITECH_HARMONY_9 0xc118 +#define USB_DEVICE_ID_LOGITECH_HARMONY_10 0xc119 +#define USB_DEVICE_ID_LOGITECH_HARMONY_11 0xc11a +#define USB_DEVICE_ID_LOGITECH_HARMONY_12 0xc11b +#define USB_DEVICE_ID_LOGITECH_HARMONY_13 0xc11c +#define USB_DEVICE_ID_LOGITECH_HARMONY_14 0xc11d +#define USB_DEVICE_ID_LOGITECH_HARMONY_15 0xc11e +#define USB_DEVICE_ID_LOGITECH_HARMONY_16 0xc11f +#define USB_DEVICE_ID_LOGITECH_HARMONY_17 0xc120 +#define USB_DEVICE_ID_LOGITECH_HARMONY_18 0xc121 +#define USB_DEVICE_ID_LOGITECH_HARMONY_19 0xc122 +#define USB_DEVICE_ID_LOGITECH_HARMONY_20 0xc123 +#define USB_DEVICE_ID_LOGITECH_HARMONY_21 0xc124 +#define USB_DEVICE_ID_LOGITECH_HARMONY_22 0xc125 +#define USB_DEVICE_ID_LOGITECH_HARMONY_23 0xc126 +#define USB_DEVICE_ID_LOGITECH_HARMONY_24 0xc127 +#define USB_DEVICE_ID_LOGITECH_HARMONY_25 0xc128 +#define USB_DEVICE_ID_LOGITECH_HARMONY_26 0xc129 +#define USB_DEVICE_ID_LOGITECH_HARMONY_27 0xc12a +#define USB_DEVICE_ID_LOGITECH_HARMONY_28 0xc12b +#define USB_DEVICE_ID_LOGITECH_HARMONY_29 0xc12c +#define USB_DEVICE_ID_LOGITECH_HARMONY_30 0xc12d +#define USB_DEVICE_ID_LOGITECH_HARMONY_31 0xc12e +#define USB_DEVICE_ID_LOGITECH_HARMONY_32 0xc12f +#define USB_DEVICE_ID_LOGITECH_HARMONY_33 0xc130 +#define USB_DEVICE_ID_LOGITECH_HARMONY_34 0xc131 +#define USB_DEVICE_ID_LOGITECH_HARMONY_35 0xc132 +#define USB_DEVICE_ID_LOGITECH_HARMONY_36 0xc133 +#define USB_DEVICE_ID_LOGITECH_HARMONY_37 0xc134 +#define USB_DEVICE_ID_LOGITECH_HARMONY_38 0xc135 +#define USB_DEVICE_ID_LOGITECH_HARMONY_39 0xc136 +#define USB_DEVICE_ID_LOGITECH_HARMONY_40 0xc137 +#define USB_DEVICE_ID_LOGITECH_HARMONY_41 0xc138 +#define USB_DEVICE_ID_LOGITECH_HARMONY_42 0xc139 +#define USB_DEVICE_ID_LOGITECH_HARMONY_43 0xc13a +#define USB_DEVICE_ID_LOGITECH_HARMONY_44 0xc13b +#define USB_DEVICE_ID_LOGITECH_HARMONY_45 0xc13c +#define USB_DEVICE_ID_LOGITECH_HARMONY_46 0xc13d +#define USB_DEVICE_ID_LOGITECH_HARMONY_47 0xc13e +#define USB_DEVICE_ID_LOGITECH_HARMONY_48 0xc13f +#define USB_DEVICE_ID_LOGITECH_HARMONY_49 0xc140 +#define USB_DEVICE_ID_LOGITECH_HARMONY_50 0xc141 +#define USB_DEVICE_ID_LOGITECH_HARMONY_51 0xc142 +#define USB_DEVICE_ID_LOGITECH_HARMONY_52 0xc143 +#define USB_DEVICE_ID_LOGITECH_HARMONY_53 0xc144 +#define USB_DEVICE_ID_LOGITECH_HARMONY_54 0xc145 +#define USB_DEVICE_ID_LOGITECH_HARMONY_55 0xc146 +#define USB_DEVICE_ID_LOGITECH_HARMONY_56 0xc147 +#define USB_DEVICE_ID_LOGITECH_HARMONY_57 0xc148 +#define USB_DEVICE_ID_LOGITECH_HARMONY_58 0xc149 +#define USB_DEVICE_ID_LOGITECH_HARMONY_59 0xc14a +#define USB_DEVICE_ID_LOGITECH_HARMONY_60 0xc14b +#define USB_DEVICE_ID_LOGITECH_HARMONY_61 0xc14c +#define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d +#define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e +#define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f +#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 +#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 +#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a +#define USB_DEVICE_ID_LOGITECH_KBD 0xc311 +#define USB_DEVICE_ID_S510_RECEIVER 0xc50c +#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 +#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 +#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 +#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 +#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 +#define USB_DEVICE_ID_DINOVO_MINI 0xc71f + +#define USB_VENDOR_ID_MCC 0x09db +#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 +#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a + +#define USB_VENDOR_ID_MGE 0x0463 +#define USB_DEVICE_ID_MGE_UPS 0xffff +#define USB_DEVICE_ID_MGE_UPS1 0x0001 + +#define USB_VENDOR_ID_MICROCHIP 0x04d8 +#define USB_DEVICE_ID_PICKIT1 0x0032 +#define USB_DEVICE_ID_PICKIT2 0x0033 + +#define USB_VENDOR_ID_MICROSOFT 0x045e +#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b +#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d +#define USB_DEVICE_ID_DESKTOP_RECV_1028 0x00f9 +#define USB_DEVICE_ID_MS_NE4K 0x00db +#define USB_DEVICE_ID_MS_LK6K 0x00f9 + +#define USB_VENDOR_ID_MONTEREY 0x0566 +#define USB_DEVICE_ID_GENIUS_KB29E 0x3004 + +#define USB_VENDOR_ID_NCR 0x0404 +#define USB_DEVICE_ID_NCR_FIRST 0x0300 +#define USB_DEVICE_ID_NCR_LAST 0x03ff + +#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 +#define USB_DEVICE_ID_N_S_HARMONY 0xc359 + +#define USB_VENDOR_ID_NATSU 0x08b7 +#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 + +#define USB_VENDOR_ID_NEC 0x073e +#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 + +#define USB_VENDOR_ID_ONTRAK 0x0a07 +#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 + +#define USB_VENDOR_ID_PANJIT 0x134c + +#define USB_VENDOR_ID_PANTHERLORD 0x0810 +#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 + +#define USB_VENDOR_ID_PETALYNX 0x18b1 +#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 + +#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 +#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 + +#define USB_VENDOR_ID_SAITEK 0x06a3 +#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 + +#define USB_VENDOR_ID_SAMSUNG 0x0419 +#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 + +#define USB_VENDOR_ID_SONY 0x054c +#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 + +#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 +#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 + +#define USB_VENDOR_ID_SUN 0x0430 +#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab + +#define USB_VENDOR_ID_SUNPLUS 0x04fc +#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 + +#define USB_VENDOR_ID_TOPMAX 0x0663 +#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 + +#define USB_VENDOR_ID_TURBOX 0x062a +#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 + +#define USB_VENDOR_ID_VERNIER 0x08f7 +#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 +#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 +#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 +#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 +#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 + +#define USB_VENDOR_ID_WACOM 0x056a + +#define USB_VENDOR_ID_WISEGROUP 0x0925 +#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 +#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 +#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201 +#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800 +#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 + +#define USB_VENDOR_ID_WISEGROUP_LTD 0x6677 +#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 + +#define USB_VENDOR_ID_YEALINK 0x6993 +#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 + +#define USB_VENDOR_ID_KYE 0x0458 +#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 /* * Alphabetically sorted blacklist by quirk type. @@ -28,10 +433,18 @@ static const struct hid_blacklist { __u16 idProduct; __u32 quirks; } hid_blacklist[] = { + + { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, + { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, + + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, + { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, + { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, @@ -40,11 +453,169 @@ static const struct hid_blacklist { { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP, HID_QUIRK_DUPLICATE_USAGES }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES }, + { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, + { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, + { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, + + { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT }, + + { USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, + { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GENERAL_TOUCH, 0x0001, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GENERAL_TOUCH, 0x0002, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GENERAL_TOUCH, 0x0003, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GENERAL_TOUCH, 0x0004, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE }, + + { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, + + { USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2, HID_QUIRK_IGNORE }, + + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3, HID_QUIRK_INVERT_HWHEEL }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150, HID_QUIRK_INVERT_HWHEEL }, + + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, + + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, + { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER | HID_QUIRK_HIDDEV }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, @@ -52,13 +623,144 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, + + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + + { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_6, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_7, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_8, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_9, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_10, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_11, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_12, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_13, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_14, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_15, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_16, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_17, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_18, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_19, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_21, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_22, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_23, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_25, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_26, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_27, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_28, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_29, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_31, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_32, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_33, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_34, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_35, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_36, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_37, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_38, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_39, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_40, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_41, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_42, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_43, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_44, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_45, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_46, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_47, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_48, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_49, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_50, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_51, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_52, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_53, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_54, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_55, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_56, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_57, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_58, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_59, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_60, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_61, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_62, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560, HID_QUIRK_IGNORE }, + + { 0, 0 } +}; + +/* Quirks for devices which require report descriptor fixup go here */ +static const struct hid_rdesc_blacklist { + __u16 idVendor; + __u16 idProduct; + __u32 quirks; +} hid_rdesc_blacklist[] = { + + { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION }, + + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_DESKTOP_RECV_1028, HID_QUIRK_RDESC_MICROSOFT_RECV_1028 }, + + { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, + + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS }, + + { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, + + { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, + + { USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP, HID_QUIRK_RDESC_SUNPLUS_WDESKTOP }, + + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, { 0, 0 } }; @@ -272,6 +974,16 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) u32 quirks = 0; const struct hid_blacklist *bl_entry = NULL; + /* Ignore all Wacom devices */ + if (idVendor == USB_VENDOR_ID_WACOM) + return HID_QUIRK_IGNORE; + + /* ignore all Code Mercenaries IOWarrior devices */ + if (idVendor == USB_VENDOR_ID_CODEMERCS) + if (idProduct >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && + idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) + return HID_QUIRK_IGNORE; + /* NCR devices must not be queried for reports */ if (idVendor == USB_VENDOR_ID_NCR && idProduct >= USB_DEVICE_ID_NCR_FIRST && @@ -290,3 +1002,221 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) } EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); + +/* + * Cherry Cymotion keyboard have an invalid HID report descriptor, + * that needs fixing before we can parse it. + */ +static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize) +{ + if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { + printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n"); + rdesc[11] = rdesc[16] = 0xff; + rdesc[12] = rdesc[17] = 0x03; + } +} + + +/* + * Certain Logitech keyboards send in report #3 keys which are far + * above the logical maximum described in descriptor. This extends + * the original value of 0x28c of logical maximum to 0x104d + */ +static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 90 && rdesc[83] == 0x26 + && rdesc[84] == 0x8c + && rdesc[85] == 0x02) { + printk(KERN_INFO "Fixing up Logitech keyboard report descriptor\n"); + rdesc[84] = rdesc[89] = 0x4d; + rdesc[85] = rdesc[90] = 0x10; + } +} + +static void usbhid_fixup_sunplus_wdesktop(unsigned char *rdesc, int rsize) +{ + if (rsize >= 107 && rdesc[104] == 0x26 + && rdesc[105] == 0x80 + && rdesc[106] == 0x03) { + printk(KERN_INFO "Fixing up Sunplus Wireless Desktop report descriptor\n"); + rdesc[105] = rdesc[110] = 0x03; + rdesc[106] = rdesc[111] = 0x21; + } +} + +/* + * Samsung IrDA remote controller (reports as Cypress USB Mouse). + * + * Vendor specific report #4 has a size of 48 bit, + * and therefore is not accepted when inspecting the descriptors. + * As a workaround we reinterpret the report as: + * Variable type, count 6, size 8 bit, log. maximum 255 + * The burden to reconstruct the data is moved into user space. + */ +static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc, + int rsize) +{ + if (rsize >= 182 && rdesc[175] == 0x25 + && rdesc[176] == 0x40 + && rdesc[177] == 0x75 + && rdesc[178] == 0x30 + && rdesc[179] == 0x95 + && rdesc[180] == 0x01 + && rdesc[182] == 0x40) { + printk(KERN_INFO "Fixing up Samsung IrDA report descriptor\n"); + rdesc[176] = 0xff; + rdesc[178] = 0x08; + rdesc[180] = 0x06; + rdesc[182] = 0x42; + } +} + +/* Petalynx Maxter Remote has maximum for consumer page set too low */ +static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 60 && rdesc[39] == 0x2a + && rdesc[40] == 0xf5 + && rdesc[41] == 0x00 + && rdesc[59] == 0x26 + && rdesc[60] == 0xf9 + && rdesc[61] == 0x00) { + printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n"); + rdesc[60] = 0xfa; + rdesc[40] = 0xfa; + } +} + +/* + * Some USB barcode readers from cypress have usage min and usage max in + * the wrong order + */ +static void usbhid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize) +{ + short fixed = 0; + int i; + + for (i = 0; i < rsize - 4; i++) { + if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) { + unsigned char tmp; + + rdesc[i] = 0x19; rdesc[i+2] = 0x29; + tmp = rdesc[i+3]; + rdesc[i+3] = rdesc[i+1]; + rdesc[i+1] = tmp; + } + } + + if (fixed) + printk(KERN_INFO "Fixing up Cypress report descriptor\n"); +} + +/* + * MacBook JIS keyboard has wrong logical maximum + */ +static void usbhid_fixup_macbook_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 60 && rdesc[53] == 0x65 + && rdesc[59] == 0x65) { + printk(KERN_INFO "Fixing up MacBook JIS keyboard report descriptor\n"); + rdesc[53] = rdesc[59] = 0xe7; + } +} + +static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 30 && rdesc[29] == 0x05 + && rdesc[30] == 0x09) { + printk(KERN_INFO "Fixing up button/consumer in HID report descriptor\n"); + rdesc[30] = 0x0c; + } +} + +/* + * Microsoft Wireless Desktop Receiver (Model 1028) has several + * 'Usage Min/Max' where it ought to have 'Physical Min/Max' + */ +static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize == 571 && rdesc[284] == 0x19 + && rdesc[286] == 0x2a + && rdesc[304] == 0x19 + && rdesc[306] == 0x29 + && rdesc[352] == 0x1a + && rdesc[355] == 0x2a + && rdesc[557] == 0x19 + && rdesc[559] == 0x29) { + printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); + rdesc[284] = rdesc[304] = rdesc[557] = 0x35; + rdesc[352] = 0x36; + rdesc[286] = rdesc[355] = 0x46; + rdesc[306] = rdesc[559] = 0x45; + } +} + +static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) +{ + if ((quirks & HID_QUIRK_RDESC_CYMOTION)) + usbhid_fixup_cymotion_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_LOGITECH) + usbhid_fixup_logitech_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_SWAPPED_MIN_MAX) + usbhid_fixup_cypress_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_PETALYNX) + usbhid_fixup_petalynx_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS) + usbhid_fixup_macbook_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER) + usbhid_fixup_button_consumer_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) + usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_MICROSOFT_RECV_1028) + usbhid_fixup_microsoft_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP) + usbhid_fixup_sunplus_wdesktop(rdesc, rsize); +} + +/** + * usbhid_fixup_report_descriptor: check if report descriptor needs fixup + * + * Description: + * Walks the hid_rdesc_blacklist[] array and checks whether the device + * is known to have broken report descriptor that needs to be fixed up + * prior to entering the HID parser + * + * Returns: nothing + */ +void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct, + char *rdesc, unsigned rsize, char **quirks_param) +{ + int n, m; + u16 paramVendor, paramProduct; + u32 quirks; + + /* static rdesc quirk entries */ + for (n = 0; hid_rdesc_blacklist[n].idVendor; n++) + if (hid_rdesc_blacklist[n].idVendor == idVendor && + hid_rdesc_blacklist[n].idProduct == idProduct) + __usbhid_fixup_report_descriptor(hid_rdesc_blacklist[n].quirks, + rdesc, rsize); + + /* runtime rdesc quirk entries handling */ + for (n = 0; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) { + m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x", + ¶mVendor, ¶mProduct, &quirks); + + if (m != 3) + printk(KERN_WARNING + "Could not parse HID quirk module param %s\n", + quirks_param[n]); + else if (paramVendor == idVendor && paramProduct == idProduct) + __usbhid_fixup_report_descriptor(quirks, rdesc, rsize); + } +} diff --git a/trunk/drivers/hid/hid-tmff.c b/trunk/drivers/hid/usbhid/hid-tmff.c similarity index 60% rename from trunk/drivers/hid/hid-tmff.c rename to trunk/drivers/hid/usbhid/hid-tmff.c index 1b7cba0f7e1f..144578b1a00c 100644 --- a/trunk/drivers/hid/hid-tmff.c +++ b/trunk/drivers/hid/usbhid/hid-tmff.c @@ -27,17 +27,23 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include -#include -#include "hid-ids.h" +#undef DEBUG +#include -#include "usbhid/usbhid.h" +#include +#include "usbhid.h" /* Usages for thrustmaster devices I know about */ #define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) +struct dev_type { + u16 idVendor; + u16 idProduct; + const signed short *ff; +}; + static const signed short ff_rumble[] = { FF_RUMBLE, -1 @@ -48,13 +54,21 @@ static const signed short ff_joystick[] = { -1 }; +static const struct dev_type devices[] = { + { 0x44f, 0xb300, ff_rumble }, + { 0x44f, 0xb304, ff_rumble }, + { 0x44f, 0xb651, ff_rumble }, /* FGT Rumble Force Wheel */ + { 0x44f, 0xb654, ff_joystick }, /* FGT Force Feedback Wheel */ +}; + struct tmff_device { struct hid_report *report; struct hid_field *ff_field; }; /* Changes values from 0 to 0xffff into values from minimum to maximum */ -static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum) +static inline int hid_tmff_scale_u16(unsigned int in, + int minimum, int maximum) { int ret; @@ -67,7 +81,8 @@ static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum) } /* Changes values from -0x80 to 0x7f into values from minimum to maximum */ -static inline int tmff_scale_s8(int in, int minimum, int maximum) +static inline int hid_tmff_scale_s8(int in, + int minimum, int maximum) { int ret; @@ -79,8 +94,7 @@ static inline int tmff_scale_s8(int in, int minimum, int maximum) return ret; } -static int tmff_play(struct input_dev *dev, void *data, - struct ff_effect *effect) +static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { struct hid_device *hid = input_get_drvdata(dev); struct tmff_device *tmff = data; @@ -90,10 +104,10 @@ static int tmff_play(struct input_dev *dev, void *data, switch (effect->type) { case FF_CONSTANT: - x = tmff_scale_s8(effect->u.ramp.start_level, + x = hid_tmff_scale_s8(effect->u.ramp.start_level, ff_field->logical_minimum, ff_field->logical_maximum); - y = tmff_scale_s8(effect->u.ramp.end_level, + y = hid_tmff_scale_s8(effect->u.ramp.end_level, ff_field->logical_minimum, ff_field->logical_maximum); @@ -104,10 +118,10 @@ static int tmff_play(struct input_dev *dev, void *data, break; case FF_RUMBLE: - left = tmff_scale_u16(effect->u.rumble.weak_magnitude, + left = hid_tmff_scale_u16(effect->u.rumble.weak_magnitude, ff_field->logical_minimum, ff_field->logical_maximum); - right = tmff_scale_u16(effect->u.rumble.strong_magnitude, + right = hid_tmff_scale_u16(effect->u.rumble.strong_magnitude, ff_field->logical_minimum, ff_field->logical_maximum); @@ -120,14 +134,14 @@ static int tmff_play(struct input_dev *dev, void *data, return 0; } -static int tmff_init(struct hid_device *hid, const signed short *ff_bits) +int hid_tmff_init(struct hid_device *hid) { struct tmff_device *tmff; struct hid_report *report; struct list_head *report_list; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); struct input_dev *input_dev = hidinput->input; + const signed short *ff_bits = ff_joystick; int error; int i; @@ -149,121 +163,63 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) switch (field->usage[0].hid) { case THRUSTMASTER_USAGE_FF: if (field->report_count < 2) { - dev_warn(&hid->dev, "ignoring FF field " - "with report_count < 2\n"); + warn("ignoring FF field with report_count < 2"); continue; } - if (field->logical_maximum == - field->logical_minimum) { - dev_warn(&hid->dev, "ignoring FF field " - "with logical_maximum " - "== logical_minimum\n"); + if (field->logical_maximum == field->logical_minimum) { + warn("ignoring FF field with logical_maximum == logical_minimum"); continue; } if (tmff->report && tmff->report != report) { - dev_warn(&hid->dev, "ignoring FF field " - "in other report\n"); + warn("ignoring FF field in other report"); continue; } if (tmff->ff_field && tmff->ff_field != field) { - dev_warn(&hid->dev, "ignoring " - "duplicate FF field\n"); + warn("ignoring duplicate FF field"); continue; } tmff->report = report; tmff->ff_field = field; + for (i = 0; i < ARRAY_SIZE(devices); i++) { + if (input_dev->id.vendor == devices[i].idVendor && + input_dev->id.product == devices[i].idProduct) { + ff_bits = devices[i].ff; + break; + } + } + for (i = 0; ff_bits[i] >= 0; i++) set_bit(ff_bits[i], input_dev->ffbit); break; default: - dev_warn(&hid->dev, "ignoring unknown output " - "usage %08x\n", - field->usage[0].hid); + warn("ignoring unknown output usage %08x", field->usage[0].hid); continue; } } } if (!tmff->report) { - dev_err(&hid->dev, "can't find FF field in output reports\n"); + err("cant find FF field in output reports\n"); error = -ENODEV; goto fail; } - error = input_ff_create_memless(input_dev, tmff, tmff_play); + error = input_ff_create_memless(input_dev, tmff, hid_tmff_play); if (error) goto fail; - dev_info(&hid->dev, "force feedback for ThrustMaster devices by Zinx " - "Verituse "); + info("Force feedback for ThrustMaster devices by Zinx Verituse "); return 0; -fail: + fail: kfree(tmff); return error; } -static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err; - } - - tmff_init(hdev, (void *)id->driver_data); - - return 0; -err: - return ret; -} - -static const struct hid_device_id tm_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300), - .driver_data = (unsigned long)ff_rumble }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), - .driver_data = (unsigned long)ff_rumble }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ - .driver_data = (unsigned long)ff_rumble }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ - .driver_data = (unsigned long)ff_joystick }, - { } -}; -MODULE_DEVICE_TABLE(hid, tm_devices); - -static struct hid_driver tm_driver = { - .name = "thrustmaster", - .id_table = tm_devices, - .probe = tm_probe, -}; - -static int tm_init(void) -{ - return hid_register_driver(&tm_driver); -} - -static void tm_exit(void) -{ - hid_unregister_driver(&tm_driver); -} - -module_init(tm_init); -module_exit(tm_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(thrustmaster); diff --git a/trunk/drivers/hid/hid-zpff.c b/trunk/drivers/hid/usbhid/hid-zpff.c similarity index 67% rename from trunk/drivers/hid/hid-zpff.c rename to trunk/drivers/hid/usbhid/hid-zpff.c index ea82f3718b21..5a688274f6a3 100644 --- a/trunk/drivers/hid/hid-zpff.c +++ b/trunk/drivers/hid/usbhid/hid-zpff.c @@ -21,19 +21,16 @@ */ -#include #include #include - -#include "hid-ids.h" - -#include "usbhid/usbhid.h" +#include +#include "usbhid.h" struct zpff_device { struct hid_report *report; }; -static int zpff_play(struct input_dev *dev, void *data, +static int hid_zpff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { struct hid_device *hid = input_get_drvdata(dev); @@ -61,7 +58,7 @@ static int zpff_play(struct input_dev *dev, void *data, return 0; } -static int zpff_init(struct hid_device *hid) +int hid_zpff_init(struct hid_device *hid) { struct zpff_device *zpff; struct hid_report *report; @@ -73,14 +70,14 @@ static int zpff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output report found\n"); + printk(KERN_ERR "hid-zpff: no output report found\n"); return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 4) { - dev_err(&hid->dev, "not enough fields in report\n"); + printk(KERN_ERR "hid-zpff: not enough fields in report\n"); return -ENODEV; } @@ -90,7 +87,7 @@ static int zpff_init(struct hid_device *hid) set_bit(FF_RUMBLE, dev->ffbit); - error = input_ff_create_memless(dev, zpff, zpff_play); + error = input_ff_create_memless(dev, zpff, hid_zpff_play); if (error) { kfree(zpff); return error; @@ -103,60 +100,8 @@ static int zpff_init(struct hid_device *hid) zpff->report->field[3]->value[0] = 0x00; usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); - dev_info(&hid->dev, "force feedback for Zeroplus based devices by " + printk(KERN_INFO "Force feedback for Zeroplus based devices by " "Anssi Hannula \n"); return 0; } - -static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err; - } - - zpff_init(hdev); - - return 0; -err: - return ret; -} - -static const struct hid_device_id zp_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, - { } -}; -MODULE_DEVICE_TABLE(hid, zp_devices); - -static struct hid_driver zp_driver = { - .name = "zeroplus", - .id_table = zp_devices, - .probe = zp_probe, -}; - -static int zp_init(void) -{ - return hid_register_driver(&zp_driver); -} - -static void zp_exit(void) -{ - hid_unregister_driver(&zp_driver); -} - -module_init(zp_init); -module_exit(zp_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(zeroplus); diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c index babd65dd46ad..842e9edb888e 100644 --- a/trunk/drivers/hid/usbhid/hiddev.c +++ b/trunk/drivers/hid/usbhid/hiddev.c @@ -790,23 +790,21 @@ static struct usb_class_driver hiddev_class = { /* * This is where hid.c calls us to connect a hid device to the hiddev driver */ -int hiddev_connect(struct hid_device *hid, unsigned int force) +int hiddev_connect(struct hid_device *hid) { struct hiddev *hiddev; struct usbhid_device *usbhid = hid->driver_data; + int i; int retval; - if (!force) { - unsigned int i; - for (i = 0; i < hid->maxcollection; i++) - if (hid->collection[i].type == - HID_COLLECTION_APPLICATION && - !IS_INPUT_APPLICATION(hid->collection[i].usage)) - break; + for (i = 0; i < hid->maxcollection; i++) + if (hid->collection[i].type == + HID_COLLECTION_APPLICATION && + !IS_INPUT_APPLICATION(hid->collection[i].usage)) + break; - if (i == hid->maxcollection) - return -1; - } + if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) + return -1; if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) return -1; diff --git a/trunk/drivers/hid/usbhid/usbhid.h b/trunk/drivers/hid/usbhid/usbhid.h index abedb13c623e..62d2d7c925bd 100644 --- a/trunk/drivers/hid/usbhid/usbhid.h +++ b/trunk/drivers/hid/usbhid/usbhid.h @@ -67,7 +67,7 @@ struct usbhid_device { spinlock_t ctrllock; /* Control fifo spinlock */ struct urb *urbout; /* Output URB */ - struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ + struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ unsigned char outhead, outtail; /* Output pipe fifo head & tail */ char *outbuf; /* Output buffer */ dma_addr_t outbuf_dma; /* Output buffer dma */ @@ -82,7 +82,7 @@ struct usbhid_device { }; #define hid_to_usb_dev(hid_dev) \ - container_of(hid_dev->dev.parent->parent, struct usb_device, dev) + container_of(hid_dev->dev->parent, struct usb_device, dev) #endif diff --git a/trunk/drivers/hid/usbhid/usbkbd.c b/trunk/drivers/hid/usbhid/usbkbd.c index b342926dd7fc..0caaafe01843 100644 --- a/trunk/drivers/hid/usbhid/usbkbd.c +++ b/trunk/drivers/hid/usbhid/usbkbd.c @@ -105,16 +105,14 @@ static void usb_kbd_irq(struct urb *urb) if (usb_kbd_keycode[kbd->old[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); else - dev_info(&urb->dev->dev, - "Unknown key (scancode %#x) released.\n", kbd->old[i]); + info("Unknown key (scancode %#x) released.", kbd->old[i]); } if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { if (usb_kbd_keycode[kbd->new[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); else - dev_info(&urb->dev->dev, - "Unknown key (scancode %#x) released.\n", kbd->new[i]); + info("Unknown key (scancode %#x) pressed.", kbd->new[i]); } } @@ -161,8 +159,7 @@ static void usb_kbd_led(struct urb *urb) struct usb_kbd *kbd = urb->context; if (urb->status) - dev_warn(&urb->dev->dev, "led urb status %d received\n", - urb->status); + warn("led urb status %d received", urb->status); if (*(kbd->leds) == kbd->newleds) return; @@ -355,8 +352,7 @@ static int __init usb_kbd_init(void) { int result = usb_register(&usb_kbd_driver); if (result == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_VERSION ":" DRIVER_DESC); return result; } diff --git a/trunk/drivers/hid/usbhid/usbmouse.c b/trunk/drivers/hid/usbhid/usbmouse.c index 72ab4b268096..35689ef172cc 100644 --- a/trunk/drivers/hid/usbhid/usbmouse.c +++ b/trunk/drivers/hid/usbhid/usbmouse.c @@ -31,11 +31,6 @@ #include #include -/* for apple IDs */ -#ifdef CONFIG_USB_HID_MODULE -#include "../hid-ids.h" -#endif - /* * Version Information */ @@ -245,8 +240,7 @@ static int __init usb_mouse_init(void) { int retval = usb_register(&usb_mouse_driver); if (retval == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_VERSION ":" DRIVER_DESC); return retval; } diff --git a/trunk/drivers/hwmon/ams/ams.h b/trunk/drivers/hwmon/ams/ams.h index 221ef6915a5f..a6221e5dd984 100644 --- a/trunk/drivers/hwmon/ams/ams.h +++ b/trunk/drivers/hwmon/ams/ams.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include enum ams_irq { AMS_IRQ_FREEFALL = 0x01, diff --git a/trunk/drivers/hwmon/dme1737.c b/trunk/drivers/hwmon/dme1737.c index 27a5d397f9a1..cdb8311e4ef7 100644 --- a/trunk/drivers/hwmon/dme1737.c +++ b/trunk/drivers/hwmon/dme1737.c @@ -175,11 +175,11 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; * Data structures and manipulation thereof * --------------------------------------------------------------------- */ +/* For ISA chips, we abuse the i2c_client addr and name fields. We also use + the driver field to differentiate between I2C and ISA chips. */ struct dme1737_data { - struct i2c_client *client; /* for I2C devices only */ + struct i2c_client client; struct device *hwmon_dev; - const char *name; - unsigned int addr; /* for ISA devices only */ struct mutex update_lock; int valid; /* !=0 if following fields are valid */ @@ -512,12 +512,11 @@ static inline int PWM_OFF_TO_REG(int val, int ix, int reg) * before calling dme1737_read or dme1737_write. * --------------------------------------------------------------------- */ -static u8 dme1737_read(const struct dme1737_data *data, u8 reg) +static u8 dme1737_read(struct i2c_client *client, u8 reg) { - struct i2c_client *client = data->client; s32 val; - if (client) { /* I2C device */ + if (client->driver) { /* I2C device */ val = i2c_smbus_read_byte_data(client, reg); if (val < 0) { @@ -526,19 +525,18 @@ static u8 dme1737_read(const struct dme1737_data *data, u8 reg) "maintainer.\n", reg); } } else { /* ISA device */ - outb(reg, data->addr); - val = inb(data->addr + 1); + outb(reg, client->addr); + val = inb(client->addr + 1); } return val; } -static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val) +static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 val) { - struct i2c_client *client = data->client; s32 res = 0; - if (client) { /* I2C device */ + if (client->driver) { /* I2C device */ res = i2c_smbus_write_byte_data(client, reg, val); if (res < 0) { @@ -547,8 +545,8 @@ static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val) "maintainer.\n", reg); } } else { /* ISA device */ - outb(reg, data->addr); - outb(val, data->addr + 1); + outb(reg, client->addr); + outb(val, client->addr + 1); } return res; @@ -557,6 +555,7 @@ static s32 dme1737_write(const struct dme1737_data *data, u8 reg, u8 val) static struct dme1737_data *dme1737_update_device(struct device *dev) { struct dme1737_data *data = dev_get_drvdata(dev); + struct i2c_client *client = &data->client; int ix; u8 lsb[5]; @@ -564,7 +563,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Enable a Vbat monitoring cycle every 10 mins */ if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) { - dme1737_write(data, DME1737_REG_CONFIG, dme1737_read(data, + dme1737_write(client, DME1737_REG_CONFIG, dme1737_read(client, DME1737_REG_CONFIG) | 0x10); data->last_vbat = jiffies; } @@ -572,7 +571,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Sample register contents every 1 sec */ if (time_after(jiffies, data->last_update + HZ) || !data->valid) { if (data->type != sch5027) { - data->vid = dme1737_read(data, DME1737_REG_VID) & + data->vid = dme1737_read(client, DME1737_REG_VID) & 0x3f; } @@ -581,11 +580,11 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Voltage inputs are stored as 16 bit values even * though they have only 12 bits resolution. This is * to make it consistent with the temp inputs. */ - data->in[ix] = dme1737_read(data, + data->in[ix] = dme1737_read(client, DME1737_REG_IN(ix)) << 8; - data->in_min[ix] = dme1737_read(data, + data->in_min[ix] = dme1737_read(client, DME1737_REG_IN_MIN(ix)); - data->in_max[ix] = dme1737_read(data, + data->in_max[ix] = dme1737_read(client, DME1737_REG_IN_MAX(ix)); } @@ -596,14 +595,14 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) * to take advantage of implicit conversions between * register values (2's complement) and temp values * (signed decimal). */ - data->temp[ix] = dme1737_read(data, + data->temp[ix] = dme1737_read(client, DME1737_REG_TEMP(ix)) << 8; - data->temp_min[ix] = dme1737_read(data, + data->temp_min[ix] = dme1737_read(client, DME1737_REG_TEMP_MIN(ix)); - data->temp_max[ix] = dme1737_read(data, + data->temp_max[ix] = dme1737_read(client, DME1737_REG_TEMP_MAX(ix)); if (data->type != sch5027) { - data->temp_offset[ix] = dme1737_read(data, + data->temp_offset[ix] = dme1737_read(client, DME1737_REG_TEMP_OFFSET(ix)); } } @@ -613,7 +612,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) * which the registers are read (MSB first, then LSB) is * important! */ for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { - lsb[ix] = dme1737_read(data, + lsb[ix] = dme1737_read(client, DME1737_REG_IN_TEMP_LSB(ix)); } for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { @@ -632,19 +631,19 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) if (!(data->has_fan & (1 << ix))) { continue; } - data->fan[ix] = dme1737_read(data, + data->fan[ix] = dme1737_read(client, DME1737_REG_FAN(ix)); - data->fan[ix] |= dme1737_read(data, + data->fan[ix] |= dme1737_read(client, DME1737_REG_FAN(ix) + 1) << 8; - data->fan_min[ix] = dme1737_read(data, + data->fan_min[ix] = dme1737_read(client, DME1737_REG_FAN_MIN(ix)); - data->fan_min[ix] |= dme1737_read(data, + data->fan_min[ix] |= dme1737_read(client, DME1737_REG_FAN_MIN(ix) + 1) << 8; - data->fan_opt[ix] = dme1737_read(data, + data->fan_opt[ix] = dme1737_read(client, DME1737_REG_FAN_OPT(ix)); /* fan_max exists only for fan[5-6] */ if (ix > 3) { - data->fan_max[ix - 4] = dme1737_read(data, + data->fan_max[ix - 4] = dme1737_read(client, DME1737_REG_FAN_MAX(ix)); } } @@ -656,63 +655,63 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) if (!(data->has_pwm & (1 << ix))) { continue; } - data->pwm[ix] = dme1737_read(data, + data->pwm[ix] = dme1737_read(client, DME1737_REG_PWM(ix)); - data->pwm_freq[ix] = dme1737_read(data, + data->pwm_freq[ix] = dme1737_read(client, DME1737_REG_PWM_FREQ(ix)); /* pwm_config and pwm_min exist only for pwm[1-3] */ if (ix < 3) { - data->pwm_config[ix] = dme1737_read(data, + data->pwm_config[ix] = dme1737_read(client, DME1737_REG_PWM_CONFIG(ix)); - data->pwm_min[ix] = dme1737_read(data, + data->pwm_min[ix] = dme1737_read(client, DME1737_REG_PWM_MIN(ix)); } } for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) { - data->pwm_rr[ix] = dme1737_read(data, + data->pwm_rr[ix] = dme1737_read(client, DME1737_REG_PWM_RR(ix)); } /* Thermal zone registers */ for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { - data->zone_low[ix] = dme1737_read(data, + data->zone_low[ix] = dme1737_read(client, DME1737_REG_ZONE_LOW(ix)); - data->zone_abs[ix] = dme1737_read(data, + data->zone_abs[ix] = dme1737_read(client, DME1737_REG_ZONE_ABS(ix)); } if (data->type != sch5027) { for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { - data->zone_hyst[ix] = dme1737_read(data, + data->zone_hyst[ix] = dme1737_read(client, DME1737_REG_ZONE_HYST(ix)); } } /* Alarm registers */ - data->alarms = dme1737_read(data, + data->alarms = dme1737_read(client, DME1737_REG_ALARM1); /* Bit 7 tells us if the other alarm registers are non-zero and * therefore also need to be read */ if (data->alarms & 0x80) { - data->alarms |= dme1737_read(data, + data->alarms |= dme1737_read(client, DME1737_REG_ALARM2) << 8; - data->alarms |= dme1737_read(data, + data->alarms |= dme1737_read(client, DME1737_REG_ALARM3) << 16; } /* The ISA chips require explicit clearing of alarm bits. * Don't worry, an alarm will come back if the condition * that causes it still exists */ - if (!data->client) { + if (!client->driver) { if (data->alarms & 0xff0000) { - dme1737_write(data, DME1737_REG_ALARM3, + dme1737_write(client, DME1737_REG_ALARM3, 0xff); } if (data->alarms & 0xff00) { - dme1737_write(data, DME1737_REG_ALARM2, + dme1737_write(client, DME1737_REG_ALARM2, 0xff); } if (data->alarms & 0xff) { - dme1737_write(data, DME1737_REG_ALARM1, + dme1737_write(client, DME1737_REG_ALARM1, 0xff); } } @@ -771,6 +770,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dme1737_data *data = dev_get_drvdata(dev); + struct i2c_client *client = &data->client; struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; @@ -781,12 +781,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, switch (fn) { case SYS_IN_MIN: data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]); - dme1737_write(data, DME1737_REG_IN_MIN(ix), + dme1737_write(client, DME1737_REG_IN_MIN(ix), data->in_min[ix]); break; case SYS_IN_MAX: data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]); - dme1737_write(data, DME1737_REG_IN_MAX(ix), + dme1737_write(client, DME1737_REG_IN_MAX(ix), data->in_max[ix]); break; default: @@ -850,6 +850,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dme1737_data *data = dev_get_drvdata(dev); + struct i2c_client *client = &data->client; struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; @@ -860,17 +861,17 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, switch (fn) { case SYS_TEMP_MIN: data->temp_min[ix] = TEMP_TO_REG(val); - dme1737_write(data, DME1737_REG_TEMP_MIN(ix), + dme1737_write(client, DME1737_REG_TEMP_MIN(ix), data->temp_min[ix]); break; case SYS_TEMP_MAX: data->temp_max[ix] = TEMP_TO_REG(val); - dme1737_write(data, DME1737_REG_TEMP_MAX(ix), + dme1737_write(client, DME1737_REG_TEMP_MAX(ix), data->temp_max[ix]); break; case SYS_TEMP_OFFSET: data->temp_offset[ix] = TEMP_TO_REG(val); - dme1737_write(data, DME1737_REG_TEMP_OFFSET(ix), + dme1737_write(client, DME1737_REG_TEMP_OFFSET(ix), data->temp_offset[ix]); break; default: @@ -938,6 +939,7 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dme1737_data *data = dev_get_drvdata(dev); + struct i2c_client *client = &data->client; struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; @@ -948,37 +950,37 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, switch (fn) { case SYS_ZONE_AUTO_POINT1_TEMP_HYST: /* Refresh the cache */ - data->zone_low[ix] = dme1737_read(data, + data->zone_low[ix] = dme1737_read(client, DME1737_REG_ZONE_LOW(ix)); /* Modify the temp hyst value */ data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG( TEMP_FROM_REG(data->zone_low[ix], 8) - - val, ix, dme1737_read(data, + val, ix, dme1737_read(client, DME1737_REG_ZONE_HYST(ix == 2))); - dme1737_write(data, DME1737_REG_ZONE_HYST(ix == 2), + dme1737_write(client, DME1737_REG_ZONE_HYST(ix == 2), data->zone_hyst[ix == 2]); break; case SYS_ZONE_AUTO_POINT1_TEMP: data->zone_low[ix] = TEMP_TO_REG(val); - dme1737_write(data, DME1737_REG_ZONE_LOW(ix), + dme1737_write(client, DME1737_REG_ZONE_LOW(ix), data->zone_low[ix]); break; case SYS_ZONE_AUTO_POINT2_TEMP: /* Refresh the cache */ - data->zone_low[ix] = dme1737_read(data, + data->zone_low[ix] = dme1737_read(client, DME1737_REG_ZONE_LOW(ix)); /* Modify the temp range value (which is stored in the upper * nibble of the pwm_freq register) */ data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - TEMP_FROM_REG(data->zone_low[ix], 8), - dme1737_read(data, + dme1737_read(client, DME1737_REG_PWM_FREQ(ix))); - dme1737_write(data, DME1737_REG_PWM_FREQ(ix), + dme1737_write(client, DME1737_REG_PWM_FREQ(ix), data->pwm_freq[ix]); break; case SYS_ZONE_AUTO_POINT3_TEMP: data->zone_abs[ix] = TEMP_TO_REG(val); - dme1737_write(data, DME1737_REG_ZONE_ABS(ix), + dme1737_write(client, DME1737_REG_ZONE_ABS(ix), data->zone_abs[ix]); break; default: @@ -1044,6 +1046,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dme1737_data *data = dev_get_drvdata(dev); + struct i2c_client *client = &data->client; struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; @@ -1057,21 +1060,21 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, data->fan_min[ix] = FAN_TO_REG(val, 0); } else { /* Refresh the cache */ - data->fan_opt[ix] = dme1737_read(data, + data->fan_opt[ix] = dme1737_read(client, DME1737_REG_FAN_OPT(ix)); /* Modify the fan min value */ data->fan_min[ix] = FAN_TO_REG(val, FAN_TPC_FROM_REG(data->fan_opt[ix])); } - dme1737_write(data, DME1737_REG_FAN_MIN(ix), + dme1737_write(client, DME1737_REG_FAN_MIN(ix), data->fan_min[ix] & 0xff); - dme1737_write(data, DME1737_REG_FAN_MIN(ix) + 1, + dme1737_write(client, DME1737_REG_FAN_MIN(ix) + 1, data->fan_min[ix] >> 8); break; case SYS_FAN_MAX: /* Only valid for fan[5-6] */ data->fan_max[ix - 4] = FAN_MAX_TO_REG(val); - dme1737_write(data, DME1737_REG_FAN_MAX(ix), + dme1737_write(client, DME1737_REG_FAN_MAX(ix), data->fan_max[ix - 4]); break; case SYS_FAN_TYPE: @@ -1083,9 +1086,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, val); goto exit; } - data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(data, + data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(client, DME1737_REG_FAN_OPT(ix))); - dme1737_write(data, DME1737_REG_FAN_OPT(ix), + dme1737_write(client, DME1737_REG_FAN_OPT(ix), data->fan_opt[ix]); break; default: @@ -1182,6 +1185,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dme1737_data *data = dev_get_drvdata(dev); + struct i2c_client *client = &data->client; struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; @@ -1192,12 +1196,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, switch (fn) { case SYS_PWM: data->pwm[ix] = SENSORS_LIMIT(val, 0, 255); - dme1737_write(data, DME1737_REG_PWM(ix), data->pwm[ix]); + dme1737_write(client, DME1737_REG_PWM(ix), data->pwm[ix]); break; case SYS_PWM_FREQ: - data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(data, + data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(client, DME1737_REG_PWM_FREQ(ix))); - dme1737_write(data, DME1737_REG_PWM_FREQ(ix), + dme1737_write(client, DME1737_REG_PWM_FREQ(ix), data->pwm_freq[ix]); break; case SYS_PWM_ENABLE: @@ -1210,7 +1214,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, goto exit; } /* Refresh the cache */ - data->pwm_config[ix] = dme1737_read(data, + data->pwm_config[ix] = dme1737_read(client, DME1737_REG_PWM_CONFIG(ix)); if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) { /* Bail out if no change */ @@ -1222,14 +1226,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm_acz[ix] = PWM_ACZ_FROM_REG( data->pwm_config[ix]); /* Save the current ramp rate state and disable it */ - data->pwm_rr[ix > 0] = dme1737_read(data, + data->pwm_rr[ix > 0] = dme1737_read(client, DME1737_REG_PWM_RR(ix > 0)); data->pwm_rr_en &= ~(1 << ix); if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) { data->pwm_rr_en |= (1 << ix); data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix, data->pwm_rr[ix > 0]); - dme1737_write(data, + dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), data->pwm_rr[ix > 0]); } @@ -1243,14 +1247,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, /* Turn fan fully on */ data->pwm_config[ix] = PWM_EN_TO_REG(0, data->pwm_config[ix]); - dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), + dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), data->pwm_config[ix]); break; case 1: /* Turn on manual mode */ data->pwm_config[ix] = PWM_EN_TO_REG(1, data->pwm_config[ix]); - dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), + dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), data->pwm_config[ix]); /* Change permissions of pwm[ix] to read-writeable */ dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], @@ -1265,14 +1269,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm_config[ix] = PWM_ACZ_TO_REG( data->pwm_acz[ix], data->pwm_config[ix]); - dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), + dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), data->pwm_config[ix]); /* Enable PWM ramp rate if previously enabled */ if (data->pwm_rr_en & (1 << ix)) { data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix, - dme1737_read(data, + dme1737_read(client, DME1737_REG_PWM_RR(ix > 0))); - dme1737_write(data, + dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), data->pwm_rr[ix > 0]); } @@ -1282,9 +1286,9 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, case SYS_PWM_RAMP_RATE: /* Only valid for pwm[1-3] */ /* Refresh the cache */ - data->pwm_config[ix] = dme1737_read(data, + data->pwm_config[ix] = dme1737_read(client, DME1737_REG_PWM_CONFIG(ix)); - data->pwm_rr[ix > 0] = dme1737_read(data, + data->pwm_rr[ix > 0] = dme1737_read(client, DME1737_REG_PWM_RR(ix > 0)); /* Set the ramp rate value */ if (val > 0) { @@ -1297,7 +1301,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, data->pwm_rr[ix > 0]); } - dme1737_write(data, DME1737_REG_PWM_RR(ix > 0), + dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), data->pwm_rr[ix > 0]); break; case SYS_PWM_AUTO_CHANNELS_ZONE: @@ -1311,14 +1315,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, goto exit; } /* Refresh the cache */ - data->pwm_config[ix] = dme1737_read(data, + data->pwm_config[ix] = dme1737_read(client, DME1737_REG_PWM_CONFIG(ix)); if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { /* PWM is already in auto mode so update the temp * channel assignment */ data->pwm_config[ix] = PWM_ACZ_TO_REG(val, data->pwm_config[ix]); - dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), + dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), data->pwm_config[ix]); } else { /* PWM is not in auto mode so we save the temp @@ -1329,7 +1333,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, case SYS_PWM_AUTO_PWM_MIN: /* Only valid for pwm[1-3] */ /* Refresh the cache */ - data->pwm_min[ix] = dme1737_read(data, + data->pwm_min[ix] = dme1737_read(client, DME1737_REG_PWM_MIN(ix)); /* There are only 2 values supported for the auto_pwm_min * value: 0 or auto_point1_pwm. So if the temperature drops @@ -1337,20 +1341,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, * off or runs at auto_point1_pwm duty-cycle. */ if (val > ((data->pwm_min[ix] + 1) / 2)) { data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, - dme1737_read(data, + dme1737_read(client, DME1737_REG_PWM_RR(0))); } else { data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, - dme1737_read(data, + dme1737_read(client, DME1737_REG_PWM_RR(0))); } - dme1737_write(data, DME1737_REG_PWM_RR(0), + dme1737_write(client, DME1737_REG_PWM_RR(0), data->pwm_rr[0]); break; case SYS_PWM_AUTO_POINT1_PWM: /* Only valid for pwm[1-3] */ data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255); - dme1737_write(data, DME1737_REG_PWM_MIN(ix), + dme1737_write(client, DME1737_REG_PWM_MIN(ix), data->pwm_min[ix]); break; default: @@ -1398,7 +1402,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, { struct dme1737_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", data->name); + return sprintf(buf, "%s\n", data->client.name); } /* --------------------------------------------------------------------- @@ -1904,7 +1908,7 @@ static void dme1737_remove_files(struct device *dev) sysfs_remove_group(&dev->kobj, &dme1737_group); - if (!data->client) { + if (!data->client.driver) { sysfs_remove_file(&dev->kobj, &dev_attr_name.attr); } } @@ -1915,7 +1919,7 @@ static int dme1737_create_files(struct device *dev) int err, ix; /* Create a name attribute for ISA devices */ - if (!data->client && + if (!data->client.driver && (err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr))) { goto exit; } @@ -2009,14 +2013,14 @@ static int dme1737_create_files(struct device *dev) static int dme1737_init_device(struct device *dev) { struct dme1737_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; + struct i2c_client *client = &data->client; int ix; u8 reg; /* Point to the right nominal voltages array */ data->in_nominal = IN_NOMINAL(data->type); - data->config = dme1737_read(data, DME1737_REG_CONFIG); + data->config = dme1737_read(client, DME1737_REG_CONFIG); /* Inform if part is not monitoring/started */ if (!(data->config & 0x01)) { if (!force_start) { @@ -2028,7 +2032,7 @@ static int dme1737_init_device(struct device *dev) /* Force monitoring */ data->config |= 0x01; - dme1737_write(data, DME1737_REG_CONFIG, data->config); + dme1737_write(client, DME1737_REG_CONFIG, data->config); } /* Inform if part is not ready */ if (!(data->config & 0x04)) { @@ -2037,8 +2041,8 @@ static int dme1737_init_device(struct device *dev) } /* Determine which optional fan and pwm features are enabled/present */ - if (client) { /* I2C chip */ - data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); + if (client->driver) { /* I2C chip */ + data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); /* Check if optional fan3 input is enabled */ if (data->config2 & 0x04) { data->has_fan |= (1 << 2); @@ -2047,7 +2051,7 @@ static int dme1737_init_device(struct device *dev) /* Fan4 and pwm3 are only available if the client's I2C address * is the default 0x2e. Otherwise the I/Os associated with * these functions are used for addr enable/select. */ - if (client->addr == 0x2e) { + if (data->client.addr == 0x2e) { data->has_fan |= (1 << 3); data->has_pwm |= (1 << 2); } @@ -2082,16 +2086,16 @@ static int dme1737_init_device(struct device *dev) (data->has_fan & (1 << 4)) ? "yes" : "no", (data->has_fan & (1 << 5)) ? "yes" : "no"); - reg = dme1737_read(data, DME1737_REG_TACH_PWM); + reg = dme1737_read(client, DME1737_REG_TACH_PWM); /* Inform if fan-to-pwm mapping differs from the default */ - if (client && reg != 0xa4) { /* I2C chip */ + if (client->driver && reg != 0xa4) { /* I2C chip */ dev_warn(dev, "Non-standard fan to pwm mapping: " "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " "fan4->pwm%d. Please report to the driver " "maintainer.\n", (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); - } else if (!client && reg != 0x24) { /* ISA chip */ + } else if (!client->driver && reg != 0x24) { /* ISA chip */ dev_warn(dev, "Non-standard fan to pwm mapping: " "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d. " "Please report to the driver maintainer.\n", @@ -2104,7 +2108,7 @@ static int dme1737_init_device(struct device *dev) * disabled). */ if (!(data->config & 0x02)) { for (ix = 0; ix < 3; ix++) { - data->pwm_config[ix] = dme1737_read(data, + data->pwm_config[ix] = dme1737_read(client, DME1737_REG_PWM_CONFIG(ix)); if ((data->has_pwm & (1 << ix)) && (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { @@ -2112,8 +2116,8 @@ static int dme1737_init_device(struct device *dev) "manual mode.\n", ix + 1); data->pwm_config[ix] = PWM_EN_TO_REG(1, data->pwm_config[ix]); - dme1737_write(data, DME1737_REG_PWM(ix), 0); - dme1737_write(data, + dme1737_write(client, DME1737_REG_PWM(ix), 0); + dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), data->pwm_config[ix]); } @@ -2187,24 +2191,37 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) return err; } -/* Return 0 if detection is successful, -ENODEV otherwise */ -static int dme1737_i2c_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address, + int kind) { - struct i2c_adapter *adapter = client->adapter; - struct device *dev = &adapter->dev; u8 company, verstep = 0; + struct i2c_client *client; + struct dme1737_data *data; + struct device *dev; + int err = 0; const char *name; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - return -ENODEV; + goto exit; + } + + if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; } + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; + client->adapter = adapter; + client->driver = &dme1737_i2c_driver; + dev = &client->dev; + /* A negative kind means that the driver was loaded with no force * parameter (default), so we must identify the chip. */ if (kind < 0) { - company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY); - verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP); + company = dme1737_read(client, DME1737_REG_COMPANY); + verstep = dme1737_read(client, DME1737_REG_VERSTEP); if (company == DME1737_COMPANY_SMSC && (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { @@ -2213,7 +2230,8 @@ static int dme1737_i2c_detect(struct i2c_client *client, int kind, verstep == SCH5027_VERSTEP) { kind = sch5027; } else { - return -ENODEV; + err = -ENODEV; + goto exit_kfree; } } @@ -2223,44 +2241,32 @@ static int dme1737_i2c_detect(struct i2c_client *client, int kind, kind = dme1737; name = "dme1737"; } + data->type = kind; - dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", - kind == sch5027 ? "SCH5027" : "DME1737", client->addr, - verstep); - strlcpy(info->type, name, I2C_NAME_SIZE); - - return 0; -} - -static int dme1737_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct dme1737_data *data; - struct device *dev = &client->dev; - int err; + /* Fill in the remaining client fields and put it into the global + * list */ + strlcpy(client->name, name, I2C_NAME_SIZE); + mutex_init(&data->update_lock); - data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(client))) { + goto exit_kfree; } - i2c_set_clientdata(client, data); - data->type = id->driver_data; - data->client = client; - data->name = client->name; - mutex_init(&data->update_lock); + dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n", + kind == sch5027 ? "SCH5027" : "DME1737", client->addr, + verstep); /* Initialize the DME1737 chip */ if ((err = dme1737_init_device(dev))) { dev_err(dev, "Failed to initialize device.\n"); - goto exit_kfree; + goto exit_detach; } /* Create sysfs files */ if ((err = dme1737_create_files(dev))) { dev_err(dev, "Failed to create sysfs files.\n"); - goto exit_kfree; + goto exit_detach; } /* Register device */ @@ -2275,40 +2281,45 @@ static int dme1737_i2c_probe(struct i2c_client *client, exit_remove: dme1737_remove_files(dev); +exit_detach: + i2c_detach_client(client); exit_kfree: kfree(data); exit: return err; } -static int dme1737_i2c_remove(struct i2c_client *client) +static int dme1737_i2c_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_CLASS_HWMON)) { + return 0; + } + + return i2c_probe(adapter, &addr_data, dme1737_i2c_detect); +} + +static int dme1737_i2c_detach_client(struct i2c_client *client) { struct dme1737_data *data = i2c_get_clientdata(client); + int err; hwmon_device_unregister(data->hwmon_dev); dme1737_remove_files(&client->dev); + if ((err = i2c_detach_client(client))) { + return err; + } + kfree(data); return 0; } -static const struct i2c_device_id dme1737_id[] = { - { "dme1737", dme1737 }, - { "sch5027", sch5027 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, dme1737_id); - static struct i2c_driver dme1737_i2c_driver = { - .class = I2C_CLASS_HWMON, .driver = { .name = "dme1737", }, - .probe = dme1737_i2c_probe, - .remove = dme1737_i2c_remove, - .id_table = dme1737_id, - .detect = dme1737_i2c_detect, - .address_data = &addr_data, + .attach_adapter = dme1737_i2c_attach_adapter, + .detach_client = dme1737_i2c_detach_client, }; /* --------------------------------------------------------------------- @@ -2392,6 +2403,7 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) { u8 company, device; struct resource *res; + struct i2c_client *client; struct dme1737_data *data; struct device *dev = &pdev->dev; int err; @@ -2410,13 +2422,15 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) goto exit_release_region; } - data->addr = res->start; + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = res->start; platform_set_drvdata(pdev, data); /* Skip chip detection if module is loaded with force_id parameter */ if (!force_id) { - company = dme1737_read(data, DME1737_REG_COMPANY); - device = dme1737_read(data, DME1737_REG_DEVICE); + company = dme1737_read(client, DME1737_REG_COMPANY); + device = dme1737_read(client, DME1737_REG_DEVICE); if (!((company == DME1737_COMPANY_SMSC) && (device == SCH311X_DEVICE))) { @@ -2427,10 +2441,10 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) data->type = sch311x; /* Fill in the remaining client fields and initialize the mutex */ - data->name = "sch311x"; + strlcpy(client->name, "sch311x", I2C_NAME_SIZE); mutex_init(&data->update_lock); - dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr); + dev_info(dev, "Found a SCH311x chip at 0x%04x\n", client->addr); /* Initialize the chip */ if ((err = dme1737_init_device(dev))) { @@ -2471,7 +2485,7 @@ static int __devexit dme1737_isa_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); dme1737_remove_files(&pdev->dev); - release_region(data->addr, DME1737_EXTENT); + release_region(data->client.addr, DME1737_EXTENT); platform_set_drvdata(pdev, NULL); kfree(data); diff --git a/trunk/drivers/hwmon/hwmon.c b/trunk/drivers/hwmon/hwmon.c index 076a59cdabe9..7321a88a5112 100644 --- a/trunk/drivers/hwmon/hwmon.c +++ b/trunk/drivers/hwmon/hwmon.c @@ -55,8 +55,8 @@ struct device *hwmon_device_register(struct device *dev) return ERR_PTR(err); id = id & MAX_ID_MASK; - hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, - HWMON_ID_FORMAT, id); + hwdev = device_create_drvdata(hwmon_class, dev, MKDEV(0, 0), NULL, + HWMON_ID_FORMAT, id); if (IS_ERR(hwdev)) { spin_lock(&idr_lock); diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index acadbc51fc0f..6ee997b2817c 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -55,7 +55,7 @@ config I2C_AMD756 config I2C_AMD756_S4882 tristate "SMBus multiplexing on the Tyan S4882" - depends on I2C_AMD756 && X86 && EXPERIMENTAL + depends on I2C_AMD756 && EXPERIMENTAL help Enabling this option will add specific SMBus support for the Tyan S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed @@ -148,7 +148,7 @@ config I2C_NFORCE2 config I2C_NFORCE2_S4985 tristate "SMBus multiplexing on the Tyan S4985" - depends on I2C_NFORCE2 && X86 && EXPERIMENTAL + depends on I2C_NFORCE2 && EXPERIMENTAL help Enabling this option will add specific SMBus support for the Tyan S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed @@ -209,7 +209,7 @@ config I2C_VIA will be called i2c-via. config I2C_VIAPRO - tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820" + tristate "VIA VT82C596/82C686/82xx and CX700" depends on PCI help If you say yes to this option, support will be included for the VIA @@ -223,8 +223,6 @@ config I2C_VIAPRO VT8237R/A/S VT8251 CX700 - VX800 - VX820 This driver can also be built as a module. If so, the module will be called i2c-viapro. @@ -332,18 +330,6 @@ config I2C_GPIO This is a very simple bitbanging I2C driver utilizing the arch-neutral GPIO API to control the SCL and SDA lines. -config I2C_HIGHLANDER - tristate "Highlander FPGA SMBus interface" - depends on SH_HIGHLANDER - help - If you say yes to this option, support will be included for - the SMBus interface located in the FPGA on various Highlander - boards, particularly the R0P7780LC0011RL and R0P7785LC0011RL - FPGAs. This is wholly unrelated to the SoC I2C. - - This driver can also be built as a module. If so, the module - will be called i2c-highlander. - config I2C_IBM_IIC tristate "IBM PPC 4xx on-chip I2C interface" depends on 4xx diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index 0c2c4b26cdf1..97dbfa2107fe 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o -obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o diff --git a/trunk/drivers/i2c/busses/i2c-highlander.c b/trunk/drivers/i2c/busses/i2c-highlander.c deleted file mode 100644 index f4d22ae9d294..000000000000 --- a/trunk/drivers/i2c/busses/i2c-highlander.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Renesas Solutions Highlander FPGA I2C/SMBus support. - * - * Supported devices: R0P7780LC0011RL, R0P7785LC0011RL - * - * Copyright (C) 2008 Paul Mundt - * Copyright (C) 2008 Renesas Solutions Corp. - * Copyright (C) 2008 Atom Create Engineering Co., Ltd. - * - * This file is subject to the terms and conditions of the GNU General - * Public License version 2. See the file "COPYING" in the main directory - * of this archive for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define SMCR 0x00 -#define SMCR_START (1 << 0) -#define SMCR_IRIC (1 << 1) -#define SMCR_BBSY (1 << 2) -#define SMCR_ACKE (1 << 3) -#define SMCR_RST (1 << 4) -#define SMCR_IEIC (1 << 6) - -#define SMSMADR 0x02 - -#define SMMR 0x04 -#define SMMR_MODE0 (1 << 0) -#define SMMR_MODE1 (1 << 1) -#define SMMR_CAP (1 << 3) -#define SMMR_TMMD (1 << 4) -#define SMMR_SP (1 << 7) - -#define SMSADR 0x06 -#define SMTRDR 0x46 - -struct highlander_i2c_dev { - struct device *dev; - void __iomem *base; - struct i2c_adapter adapter; - struct completion cmd_complete; - unsigned long last_read_time; - int irq; - u8 *buf; - size_t buf_len; -}; - -static int iic_force_poll, iic_force_normal; -static int iic_timeout = 1000, iic_read_delay; - -static inline void highlander_i2c_irq_enable(struct highlander_i2c_dev *dev) -{ - iowrite16(ioread16(dev->base + SMCR) | SMCR_IEIC, dev->base + SMCR); -} - -static inline void highlander_i2c_irq_disable(struct highlander_i2c_dev *dev) -{ - iowrite16(ioread16(dev->base + SMCR) & ~SMCR_IEIC, dev->base + SMCR); -} - -static inline void highlander_i2c_start(struct highlander_i2c_dev *dev) -{ - iowrite16(ioread16(dev->base + SMCR) | SMCR_START, dev->base + SMCR); -} - -static inline void highlander_i2c_done(struct highlander_i2c_dev *dev) -{ - iowrite16(ioread16(dev->base + SMCR) | SMCR_IRIC, dev->base + SMCR); -} - -static void highlander_i2c_setup(struct highlander_i2c_dev *dev) -{ - u16 smmr; - - smmr = ioread16(dev->base + SMMR); - smmr |= SMMR_TMMD; - - if (iic_force_normal) - smmr &= ~SMMR_SP; - else - smmr |= SMMR_SP; - - iowrite16(smmr, dev->base + SMMR); -} - -static void smbus_write_data(u8 *src, u16 *dst, int len) -{ - for (; len > 1; len -= 2) { - *dst++ = be16_to_cpup((u16 *)src); - src += 2; - } - - if (len) - *dst = *src << 8; -} - -static void smbus_read_data(u16 *src, u8 *dst, int len) -{ - for (; len > 1; len -= 2) { - *(u16 *)dst = cpu_to_be16p(src++); - dst += 2; - } - - if (len) - *dst = *src >> 8; -} - -static void highlander_i2c_command(struct highlander_i2c_dev *dev, - u8 command, int len) -{ - unsigned int i; - u16 cmd = (command << 8) | command; - - for (i = 0; i < len; i += 2) { - if (len - i == 1) - cmd = command << 8; - iowrite16(cmd, dev->base + SMSADR + i); - dev_dbg(dev->dev, "command data[%x] 0x%04x\n", i/2, cmd); - } -} - -static int highlander_i2c_wait_for_bbsy(struct highlander_i2c_dev *dev) -{ - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(iic_timeout); - while (ioread16(dev->base + SMCR) & SMCR_BBSY) { - if (time_after(jiffies, timeout)) { - dev_warn(dev->dev, "timeout waiting for bus ready\n"); - return -ETIMEDOUT; - } - - msleep(1); - } - - return 0; -} - -static int highlander_i2c_reset(struct highlander_i2c_dev *dev) -{ - iowrite16(ioread16(dev->base + SMCR) | SMCR_RST, dev->base + SMCR); - return highlander_i2c_wait_for_bbsy(dev); -} - -static int highlander_i2c_wait_for_ack(struct highlander_i2c_dev *dev) -{ - u16 tmp = ioread16(dev->base + SMCR); - - if ((tmp & (SMCR_IRIC | SMCR_ACKE)) == SMCR_ACKE) { - dev_warn(dev->dev, "ack abnormality\n"); - return highlander_i2c_reset(dev); - } - - return 0; -} - -static irqreturn_t highlander_i2c_irq(int irq, void *dev_id) -{ - struct highlander_i2c_dev *dev = dev_id; - - highlander_i2c_done(dev); - complete(&dev->cmd_complete); - - return IRQ_HANDLED; -} - -static void highlander_i2c_poll(struct highlander_i2c_dev *dev) -{ - unsigned long timeout; - u16 smcr; - - timeout = jiffies + msecs_to_jiffies(iic_timeout); - for (;;) { - smcr = ioread16(dev->base + SMCR); - - /* - * Don't bother checking ACKE here, this and the reset - * are handled in highlander_i2c_wait_xfer_done() when - * waiting for the ACK. - */ - - if (smcr & SMCR_IRIC) - return; - if (time_after(jiffies, timeout)) - break; - - cpu_relax(); - cond_resched(); - } - - dev_err(dev->dev, "polling timed out\n"); -} - -static inline int highlander_i2c_wait_xfer_done(struct highlander_i2c_dev *dev) -{ - if (dev->irq) - wait_for_completion_timeout(&dev->cmd_complete, - msecs_to_jiffies(iic_timeout)); - else - /* busy looping, the IRQ of champions */ - highlander_i2c_poll(dev); - - return highlander_i2c_wait_for_ack(dev); -} - -static int highlander_i2c_read(struct highlander_i2c_dev *dev) -{ - int i, cnt; - u16 data[16]; - - if (highlander_i2c_wait_for_bbsy(dev)) - return -EAGAIN; - - highlander_i2c_start(dev); - - if (highlander_i2c_wait_xfer_done(dev)) { - dev_err(dev->dev, "Arbitration loss\n"); - return -EAGAIN; - } - - /* - * The R0P7780LC0011RL FPGA needs a significant delay between - * data read cycles, otherwise the transciever gets confused and - * garbage is returned when the read is subsequently aborted. - * - * It is not sufficient to wait for BBSY. - * - * While this generally only applies to the older SH7780-based - * Highlanders, the same issue can be observed on SH7785 ones, - * albeit less frequently. SH7780-based Highlanders may need - * this to be as high as 1000 ms. - */ - if (iic_read_delay && time_before(jiffies, dev->last_read_time + - msecs_to_jiffies(iic_read_delay))) - msleep(jiffies_to_msecs((dev->last_read_time + - msecs_to_jiffies(iic_read_delay)) - jiffies)); - - cnt = (dev->buf_len + 1) >> 1; - for (i = 0; i < cnt; i++) { - data[i] = ioread16(dev->base + SMTRDR + (i * sizeof(u16))); - dev_dbg(dev->dev, "read data[%x] 0x%04x\n", i, data[i]); - } - - smbus_read_data(data, dev->buf, dev->buf_len); - - dev->last_read_time = jiffies; - - return 0; -} - -static int highlander_i2c_write(struct highlander_i2c_dev *dev) -{ - int i, cnt; - u16 data[16]; - - smbus_write_data(dev->buf, data, dev->buf_len); - - cnt = (dev->buf_len + 1) >> 1; - for (i = 0; i < cnt; i++) { - iowrite16(data[i], dev->base + SMTRDR + (i * sizeof(u16))); - dev_dbg(dev->dev, "write data[%x] 0x%04x\n", i, data[i]); - } - - if (highlander_i2c_wait_for_bbsy(dev)) - return -EAGAIN; - - highlander_i2c_start(dev); - - return highlander_i2c_wait_xfer_done(dev); -} - -static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, - union i2c_smbus_data *data) -{ - struct highlander_i2c_dev *dev = i2c_get_adapdata(adap); - int read = read_write & I2C_SMBUS_READ; - u16 tmp; - - init_completion(&dev->cmd_complete); - - dev_dbg(dev->dev, "addr %04x, command %02x, read_write %d, size %d\n", - addr, command, read_write, size); - - /* - * Set up the buffer and transfer size - */ - switch (size) { - case I2C_SMBUS_BYTE_DATA: - dev->buf = &data->byte; - dev->buf_len = 1; - break; - case I2C_SMBUS_I2C_BLOCK_DATA: - dev->buf = &data->block[1]; - dev->buf_len = data->block[0]; - break; - default: - dev_err(dev->dev, "unsupported command %d\n", size); - return -EINVAL; - } - - /* - * Encode the mode setting - */ - tmp = ioread16(dev->base + SMMR); - tmp &= ~(SMMR_MODE0 | SMMR_MODE1); - - switch (dev->buf_len) { - case 1: - /* default */ - break; - case 8: - tmp |= SMMR_MODE0; - break; - case 16: - tmp |= SMMR_MODE1; - break; - case 32: - tmp |= (SMMR_MODE0 | SMMR_MODE1); - break; - default: - dev_err(dev->dev, "unsupported xfer size %d\n", dev->buf_len); - return -EINVAL; - } - - iowrite16(tmp, dev->base + SMMR); - - /* Ensure we're in a sane state */ - highlander_i2c_done(dev); - - /* Set slave address */ - iowrite16((addr << 1) | read, dev->base + SMSMADR); - - highlander_i2c_command(dev, command, dev->buf_len); - - if (read) - return highlander_i2c_read(dev); - else - return highlander_i2c_write(dev); -} - -static u32 highlander_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK; -} - -static const struct i2c_algorithm highlander_i2c_algo = { - .smbus_xfer = highlander_i2c_smbus_xfer, - .functionality = highlander_i2c_func, -}; - -static int __devinit highlander_i2c_probe(struct platform_device *pdev) -{ - struct highlander_i2c_dev *dev; - struct i2c_adapter *adap; - struct resource *res; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(!res)) { - dev_err(&pdev->dev, "no mem resource\n"); - return -ENODEV; - } - - dev = kzalloc(sizeof(struct highlander_i2c_dev), GFP_KERNEL); - if (unlikely(!dev)) - return -ENOMEM; - - dev->base = ioremap_nocache(res->start, res->end - res->start + 1); - if (unlikely(!dev->base)) { - ret = -ENXIO; - goto err; - } - - dev->dev = &pdev->dev; - platform_set_drvdata(pdev, dev); - - dev->irq = platform_get_irq(pdev, 0); - if (iic_force_poll) - dev->irq = 0; - - if (dev->irq) { - ret = request_irq(dev->irq, highlander_i2c_irq, IRQF_DISABLED, - pdev->name, dev); - if (unlikely(ret)) - goto err_unmap; - - highlander_i2c_irq_enable(dev); - } else { - dev_notice(&pdev->dev, "no IRQ, using polling mode\n"); - highlander_i2c_irq_disable(dev); - } - - dev->last_read_time = jiffies; /* initial read jiffies */ - - highlander_i2c_setup(dev); - - adap = &dev->adapter; - i2c_set_adapdata(adap, dev); - adap->owner = THIS_MODULE; - adap->class = I2C_CLASS_HWMON; - strlcpy(adap->name, "HL FPGA I2C adapter", sizeof(adap->name)); - adap->algo = &highlander_i2c_algo; - adap->dev.parent = &pdev->dev; - adap->nr = pdev->id; - - /* - * Reset the adapter - */ - ret = highlander_i2c_reset(dev); - if (unlikely(ret)) { - dev_err(&pdev->dev, "controller didn't come up\n"); - goto err_free_irq; - } - - ret = i2c_add_numbered_adapter(adap); - if (unlikely(ret)) { - dev_err(&pdev->dev, "failure adding adapter\n"); - goto err_free_irq; - } - - return 0; - -err_free_irq: - if (dev->irq) - free_irq(dev->irq, dev); -err_unmap: - iounmap(dev->base); -err: - kfree(dev); - - platform_set_drvdata(pdev, NULL); - - return ret; -} - -static int __devexit highlander_i2c_remove(struct platform_device *pdev) -{ - struct highlander_i2c_dev *dev = platform_get_drvdata(pdev); - - i2c_del_adapter(&dev->adapter); - - if (dev->irq) - free_irq(dev->irq, dev); - - iounmap(dev->base); - kfree(dev); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver highlander_i2c_driver = { - .driver = { - .name = "i2c-highlander", - .owner = THIS_MODULE, - }, - - .probe = highlander_i2c_probe, - .remove = __devexit_p(highlander_i2c_remove), -}; - -static int __init highlander_i2c_init(void) -{ - return platform_driver_register(&highlander_i2c_driver); -} - -static void __exit highlander_i2c_exit(void) -{ - platform_driver_unregister(&highlander_i2c_driver); -} - -module_init(highlander_i2c_init); -module_exit(highlander_i2c_exit); - -MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter"); -MODULE_LICENSE("GPL v2"); - -module_param(iic_force_poll, bool, 0); -module_param(iic_force_normal, bool, 0); -module_param(iic_timeout, int, 0); -module_param(iic_read_delay, int, 0); - -MODULE_PARM_DESC(iic_force_poll, "Force polling mode"); -MODULE_PARM_DESC(iic_force_normal, - "Force normal mode (100 kHz), default is fast mode (400 kHz)"); -MODULE_PARM_DESC(iic_timeout, "Set timeout value in msecs (default 1000 ms)"); -MODULE_PARM_DESC(iic_read_delay, - "Delay between data read cycles (default 0 ms)"); diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index a9a45fcc8544..27443f073bc9 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -312,6 +312,7 @@ static struct i2c_adapter mpc_ops = { .name = "MPC adapter", .id = I2C_HW_MPC107, .algo = &mpc_algo, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .timeout = 1, }; diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c index 608038d64f81..e7eb7bf9ddec 100644 --- a/trunk/drivers/i2c/busses/i2c-omap.c +++ b/trunk/drivers/i2c/busses/i2c-omap.c @@ -589,16 +589,11 @@ omap_i2c_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev->irq = irq->start; - dev->base = ioremap(mem->start, mem->end - mem->start + 1); - if (!dev->base) { - r = -ENOMEM; - goto err_free_mem; - } - + dev->base = (void __iomem *) IO_ADDRESS(mem->start); platform_set_drvdata(pdev, dev); if ((r = omap_i2c_get_clocks(dev)) != 0) - goto err_iounmap; + goto err_free_mem; omap_i2c_unidle(dev); @@ -645,8 +640,6 @@ omap_i2c_probe(struct platform_device *pdev) omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_idle(dev); omap_i2c_put_clocks(dev); -err_iounmap: - iounmap(dev->base); err_free_mem: platform_set_drvdata(pdev, NULL); kfree(dev); @@ -668,7 +661,6 @@ omap_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_put_clocks(dev); - iounmap(dev->base); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, (mem->end - mem->start) + 1); diff --git a/trunk/drivers/i2c/busses/i2c-parport-light.c b/trunk/drivers/i2c/busses/i2c-parport-light.c index b2b8380f6602..c6faf9bdad18 100644 --- a/trunk/drivers/i2c/busses/i2c-parport-light.c +++ b/trunk/drivers/i2c/busses/i2c-parport-light.c @@ -123,6 +123,11 @@ static struct i2c_adapter parport_adapter = { static int __devinit i2c_parport_probe(struct platform_device *pdev) { int err; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) + return -EBUSY; /* Reset hardware to a sane state (SCL and SDA high) */ parport_setsda(NULL, 1); @@ -133,19 +138,29 @@ static int __devinit i2c_parport_probe(struct platform_device *pdev) parport_adapter.dev.parent = &pdev->dev; err = i2c_bit_add_bus(&parport_adapter); - if (err) + if (err) { dev_err(&pdev->dev, "Unable to register with I2C\n"); + goto exit_region; + } + return 0; + +exit_region: + release_region(res->start, res->end - res->start + 1); return err; } static int __devexit i2c_parport_remove(struct platform_device *pdev) { + struct resource *res; + i2c_del_adapter(&parport_adapter); /* Un-init if needed (power off...) */ if (adapter_parm[type].init.val) line_set(0, &adapter_parm[type].init); + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + release_region(res->start, res->end - res->start + 1); return 0; } @@ -160,6 +175,12 @@ static struct platform_driver i2c_parport_driver = { static int __init i2c_parport_device_add(u16 address) { + struct resource res = { + .start = address, + .end = address + 2, + .name = DRVNAME, + .flags = IORESOURCE_IO, + }; int err; pdev = platform_device_alloc(DRVNAME, -1); @@ -169,6 +190,13 @@ static int __init i2c_parport_device_add(u16 address) goto exit; } + err = platform_device_add_resources(pdev, &res, 1); + if (err) { + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); + goto exit_device_put; + } + err = platform_device_add(pdev); if (err) { printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", @@ -203,16 +231,13 @@ static int __init i2c_parport_init(void) base = DEFAULT_BASE; } - if (!request_region(base, 3, DRVNAME)) - return -EBUSY; - if (!adapter_parm[type].getscl.val) parport_algo_data.getscl = NULL; /* Sets global pdev as a side effect */ err = i2c_parport_device_add(base); if (err) - goto exit_release; + goto exit; err = platform_driver_register(&i2c_parport_driver); if (err) @@ -222,8 +247,7 @@ static int __init i2c_parport_init(void) exit_device: platform_device_unregister(pdev); -exit_release: - release_region(base, 3); +exit: return err; } @@ -231,7 +255,6 @@ static void __exit i2c_parport_exit(void) { platform_driver_unregister(&i2c_parport_driver); platform_device_unregister(pdev); - release_region(base, 3); } MODULE_AUTHOR("Jean Delvare "); diff --git a/trunk/drivers/i2c/busses/i2c-pca-isa.c b/trunk/drivers/i2c/busses/i2c-pca-isa.c index 9eb76268ec78..a119784bae10 100644 --- a/trunk/drivers/i2c/busses/i2c-pca-isa.c +++ b/trunk/drivers/i2c/busses/i2c-pca-isa.c @@ -36,8 +36,8 @@ #define DRIVER "i2c-pca-isa" #define IO_SIZE 4 -static unsigned long base; -static int irq = -1; +static unsigned long base = 0x330; +static int irq = 10; /* Data sheet recommends 59kHz for 100kHz operation due to variation * in the actual clock rate */ @@ -107,26 +107,13 @@ static struct i2c_adapter pca_isa_ops = { .timeout = 100, }; -static int __devinit pca_isa_match(struct device *dev, unsigned int id) -{ - int match = base != 0; - - if (match) { - if (irq <= -1) - dev_warn(dev, "Using polling mode (specify irq)\n"); - } else - dev_err(dev, "Please specify I/O base\n"); - - return match; -} - static int __devinit pca_isa_probe(struct device *dev, unsigned int id) { init_waitqueue_head(&pca_wait); dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq); -#ifdef CONFIG_PPC +#ifdef CONFIG_PPC_MERGE if (check_legacy_ioport(base)) { dev_err(dev, "I/O address %#08lx is not available\n", base); goto out; @@ -166,7 +153,7 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) { i2c_del_adapter(&pca_isa_ops); - if (irq > -1) { + if (irq > 0) { disable_irq(irq); free_irq(irq, &pca_isa_ops); } @@ -176,7 +163,6 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) } static struct isa_driver pca_isa_driver = { - .match = pca_isa_match, .probe = pca_isa_probe, .remove = __devexit_p(pca_isa_remove), .driver = { diff --git a/trunk/drivers/i2c/busses/i2c-viapro.c b/trunk/drivers/i2c/busses/i2c-viapro.c index 73dc52e114eb..862eb352a2d9 100644 --- a/trunk/drivers/i2c/busses/i2c-viapro.c +++ b/trunk/drivers/i2c/busses/i2c-viapro.c @@ -36,7 +36,6 @@ VT8237S 0x3372 yes VT8251 0x3287 yes CX700 0x8324 yes - VX800/VX820 0x8353 yes Note: we assume there can only be one device, with one SMBus interface. */ @@ -83,7 +82,6 @@ static unsigned short SMBHSTCFG = 0xD2; #define VT596_BYTE 0x04 #define VT596_BYTE_DATA 0x08 #define VT596_WORD_DATA 0x0C -#define VT596_PROC_CALL 0x10 #define VT596_BLOCK_DATA 0x14 #define VT596_I2C_BLOCK_DATA 0x34 @@ -234,12 +232,6 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, } size = VT596_WORD_DATA; break; - case I2C_SMBUS_PROC_CALL: - outb_p(command, SMBHSTCMD); - outb_p(data->word & 0xff, SMBHSTDAT0); - outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); - size = VT596_PROC_CALL; - break; case I2C_SMBUS_I2C_BLOCK_DATA: if (!(vt596_features & FEATURE_I2CBLOCK)) goto exit_unsupported; @@ -270,9 +262,6 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, if (status) return status; - if (size == VT596_PROC_CALL) - read_write = I2C_SMBUS_READ; - if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) return 0; @@ -282,7 +271,6 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, data->byte = inb_p(SMBHSTDAT0); break; case VT596_WORD_DATA: - case VT596_PROC_CALL: data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); break; case VT596_I2C_BLOCK_DATA: @@ -307,7 +295,7 @@ static u32 vt596_func(struct i2c_adapter *adapter) { u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA; + I2C_FUNC_SMBUS_BLOCK_DATA; if (vt596_features & FEATURE_I2CBLOCK) func |= I2C_FUNC_SMBUS_I2C_BLOCK; @@ -408,7 +396,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev, switch (pdev->device) { case PCI_DEVICE_ID_VIA_CX700: - case PCI_DEVICE_ID_VIA_VX800: case PCI_DEVICE_ID_VIA_8251: case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237A: @@ -472,8 +459,6 @@ static struct pci_device_id vt596_ids[] = { .driver_data = SMBBA3 }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700), .driver_data = SMBBA3 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800), - .driver_data = SMBBA3 }, { 0, } }; diff --git a/trunk/drivers/i2c/chips/Kconfig b/trunk/drivers/i2c/chips/Kconfig index 17356827b93d..a95cb9465d65 100644 --- a/trunk/drivers/i2c/chips/Kconfig +++ b/trunk/drivers/i2c/chips/Kconfig @@ -172,15 +172,4 @@ config MENELAUS and other features that are often used in portable devices like cell phones and PDAs. -config MCU_MPC8349EMITX - tristate "MPC8349E-mITX MCU driver" - depends on I2C && PPC_83xx - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Say Y here to enable soft power-off functionality on the Freescale - boards with the MPC8349E-mITX-compatible MCU chips. This driver will - also register MCU GPIOs with the generic GPIO API, so you'll able - to use MCU pins as GPIOs. - endmenu diff --git a/trunk/drivers/i2c/chips/Makefile b/trunk/drivers/i2c/chips/Makefile index ca520fa143d6..39e3e69ed125 100644 --- a/trunk/drivers/i2c/chips/Makefile +++ b/trunk/drivers/i2c/chips/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TPS65010) += tps65010.o obj-$(CONFIG_MENELAUS) += menelaus.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o -obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/trunk/drivers/i2c/chips/isp1301_omap.c b/trunk/drivers/i2c/chips/isp1301_omap.c index 28902ebd5539..4655b794ebe3 100644 --- a/trunk/drivers/i2c/chips/isp1301_omap.c +++ b/trunk/drivers/i2c/chips/isp1301_omap.c @@ -49,9 +49,10 @@ MODULE_LICENSE("GPL"); struct isp1301 { struct otg_transceiver otg; - struct i2c_client *client; + struct i2c_client client; void (*i2c_release)(struct device *dev); + int irq; int irq_type; u32 last_otg_ctrl; @@ -137,6 +138,14 @@ static inline void notresponding(struct isp1301 *isp) /*-------------------------------------------------------------------------*/ +/* only two addresses possible */ +#define ISP_BASE 0x2c +static unsigned short normal_i2c[] = { + ISP_BASE, ISP_BASE + 1, + I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + static struct i2c_driver isp1301_driver; /* smbus apis are used for portability */ @@ -144,25 +153,25 @@ static struct i2c_driver isp1301_driver; static inline u8 isp1301_get_u8(struct isp1301 *isp, u8 reg) { - return i2c_smbus_read_byte_data(isp->client, reg + 0); + return i2c_smbus_read_byte_data(&isp->client, reg + 0); } static inline int isp1301_get_u16(struct isp1301 *isp, u8 reg) { - return i2c_smbus_read_word_data(isp->client, reg); + return i2c_smbus_read_word_data(&isp->client, reg); } static inline int isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits) { - return i2c_smbus_write_byte_data(isp->client, reg + 0, bits); + return i2c_smbus_write_byte_data(&isp->client, reg + 0, bits); } static inline int isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) { - return i2c_smbus_write_byte_data(isp->client, reg + 1, bits); + return i2c_smbus_write_byte_data(&isp->client, reg + 1, bits); } /*-------------------------------------------------------------------------*/ @@ -340,10 +349,10 @@ isp1301_defer_work(struct isp1301 *isp, int work) int status; if (isp && !test_and_set_bit(work, &isp->todo)) { - (void) get_device(&isp->client->dev); + (void) get_device(&isp->client.dev); status = schedule_work(&isp->work); if (!status && !isp->working) - dev_vdbg(&isp->client->dev, + dev_vdbg(&isp->client.dev, "work item %d may be lost\n", work); } } @@ -1126,7 +1135,7 @@ isp1301_work(struct work_struct *work) /* transfer state from otg engine to isp1301 */ if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { otg_update_isp(isp); - put_device(&isp->client->dev); + put_device(&isp->client.dev); } #endif /* transfer state from isp1301 to otg engine */ @@ -1134,7 +1143,7 @@ isp1301_work(struct work_struct *work) u8 stat = isp1301_clear_latch(isp); isp_update_otg(isp, stat); - put_device(&isp->client->dev); + put_device(&isp->client.dev); } if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { @@ -1169,7 +1178,7 @@ isp1301_work(struct work_struct *work) } host_resume(isp); // mdelay(10); - put_device(&isp->client->dev); + put_device(&isp->client.dev); } if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { @@ -1178,15 +1187,15 @@ isp1301_work(struct work_struct *work) if (!stop) mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); #endif - put_device(&isp->client->dev); + put_device(&isp->client.dev); } if (isp->todo) - dev_vdbg(&isp->client->dev, + dev_vdbg(&isp->client.dev, "work done, todo = 0x%lx\n", isp->todo); if (stop) { - dev_dbg(&isp->client->dev, "stop\n"); + dev_dbg(&isp->client.dev, "stop\n"); break; } } while (isp->todo); @@ -1210,7 +1219,7 @@ static void isp1301_release(struct device *dev) { struct isp1301 *isp; - isp = dev_get_drvdata(dev); + isp = container_of(dev, struct isp1301, client.dev); /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ if (isp->i2c_release) @@ -1220,15 +1229,15 @@ static void isp1301_release(struct device *dev) static struct isp1301 *the_transceiver; -static int __exit isp1301_remove(struct i2c_client *i2c) +static int isp1301_detach_client(struct i2c_client *i2c) { struct isp1301 *isp; - isp = i2c_get_clientdata(i2c); + isp = container_of(i2c, struct isp1301, client); isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0); isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0); - free_irq(i2c->irq, isp); + free_irq(isp->irq, isp); #ifdef CONFIG_USB_OTG otg_unbind(isp); #endif @@ -1243,7 +1252,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c) put_device(&i2c->dev); the_transceiver = 0; - return 0; + return i2c_detach_client(i2c); } /*-------------------------------------------------------------------------*/ @@ -1276,7 +1285,7 @@ static int isp1301_otg_enable(struct isp1301 *isp) isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND); - dev_info(&isp->client->dev, "ready for dual-role USB ...\n"); + dev_info(&isp->client.dev, "ready for dual-role USB ...\n"); return 0; } @@ -1301,7 +1310,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) #ifdef CONFIG_USB_OTG isp->otg.host = host; - dev_dbg(&isp->client->dev, "registered host\n"); + dev_dbg(&isp->client.dev, "registered host\n"); host_suspend(isp); if (isp->otg.gadget) return isp1301_otg_enable(isp); @@ -1316,7 +1325,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) if (machine_is_omap_h2()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); - dev_info(&isp->client->dev, "A-Host sessions ok\n"); + dev_info(&isp->client.dev, "A-Host sessions ok\n"); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, INTR_ID_GND); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, @@ -1334,7 +1343,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) return 0; #else - dev_dbg(&isp->client->dev, "host sessions not allowed\n"); + dev_dbg(&isp->client.dev, "host sessions not allowed\n"); return -EINVAL; #endif @@ -1361,7 +1370,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) #ifdef CONFIG_USB_OTG isp->otg.gadget = gadget; - dev_dbg(&isp->client->dev, "registered gadget\n"); + dev_dbg(&isp->client.dev, "registered gadget\n"); /* gadget driver may be suspended until vbus_connect () */ if (isp->otg.host) return isp1301_otg_enable(isp); @@ -1386,7 +1395,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) INTR_SESS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_VBUS_VLD); - dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); + dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __func__); /* If this has a Mini-AB connector, this mode is highly @@ -1399,7 +1408,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) return 0; #else - dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); + dev_dbg(&isp->client.dev, "peripheral sessions not allowed\n"); return -EINVAL; #endif } @@ -1499,10 +1508,12 @@ isp1301_start_hnp(struct otg_transceiver *dev) /*-------------------------------------------------------------------------*/ -static int __init isp1301_probe(struct i2c_client *i2c) +/* no error returns, they'd just make bus scanning stop */ +static int isp1301_probe(struct i2c_adapter *bus, int address, int kind) { int status; struct isp1301 *isp; + struct i2c_client *i2c; if (the_transceiver) return 0; @@ -1516,19 +1527,37 @@ static int __init isp1301_probe(struct i2c_client *i2c) isp->timer.function = isp1301_timer; isp->timer.data = (unsigned long) isp; - i2c_set_clientdata(i2c, isp); - isp->client = i2c; - - /* verify the chip (shouldn't be necesary) */ - status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); - if (status != I2C_VENDOR_ID_PHILIPS) { - dev_dbg(&i2c->dev, "not philips id: %d\n", status); - goto fail; + isp->irq = -1; + isp->client.addr = address; + i2c_set_clientdata(&isp->client, isp); + isp->client.adapter = bus; + isp->client.driver = &isp1301_driver; + strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE); + i2c = &isp->client; + + /* if this is a true probe, verify the chip ... */ + if (kind < 0) { + status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); + if (status != I2C_VENDOR_ID_PHILIPS) { + dev_dbg(&bus->dev, "addr %d not philips id: %d\n", + address, status); + goto fail1; + } + status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); + if (status != I2C_PRODUCT_ID_PHILIPS_1301) { + dev_dbg(&bus->dev, "%d not isp1301, %d\n", + address, status); + goto fail1; + } } - status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID); - if (status != I2C_PRODUCT_ID_PHILIPS_1301) { - dev_dbg(&i2c->dev, "not isp1301, %d\n", status); - goto fail; + + status = i2c_attach_client(i2c); + if (status < 0) { + dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n", + DRIVER_NAME, address, status); +fail1: + kfree(isp); + return 0; } isp->i2c_release = i2c->dev.release; i2c->dev.release = isp1301_release; @@ -1557,7 +1586,7 @@ static int __init isp1301_probe(struct i2c_client *i2c) status = otg_bind(isp); if (status < 0) { dev_dbg(&i2c->dev, "can't bind OTG\n"); - goto fail; + goto fail2; } #endif @@ -1570,21 +1599,26 @@ static int __init isp1301_probe(struct i2c_client *i2c) /* IRQ wired at M14 */ omap_cfg_reg(M14_1510_GPIO2); + isp->irq = OMAP_GPIO_IRQ(2); if (gpio_request(2, "isp1301") == 0) gpio_direction_input(2); isp->irq_type = IRQF_TRIGGER_FALLING; } isp->irq_type |= IRQF_SAMPLE_RANDOM; - status = request_irq(i2c->irq, isp1301_irq, + status = request_irq(isp->irq, isp1301_irq, isp->irq_type, DRIVER_NAME, isp); if (status < 0) { dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n", - i2c->irq, status); - goto fail; + isp->irq, status); +#ifdef CONFIG_USB_OTG +fail2: +#endif + i2c_detach_client(i2c); + goto fail1; } - isp->otg.dev = &i2c->dev; + isp->otg.dev = &isp->client.dev; isp->otg.label = DRIVER_NAME; isp->otg.set_host = isp1301_set_host, @@ -1615,25 +1649,22 @@ static int __init isp1301_probe(struct i2c_client *i2c) status); return 0; - -fail: - kfree(isp); - return -ENODEV; } -static const struct i2c_device_id isp1301_id[] = { - { "isp1301_omap", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, isp1301_id); +static int isp1301_scan_bus(struct i2c_adapter *bus) +{ + if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -EINVAL; + return i2c_probe(bus, &addr_data, isp1301_probe); +} static struct i2c_driver isp1301_driver = { .driver = { .name = "isp1301_omap", }, - .probe = isp1301_probe, - .remove = __exit_p(isp1301_remove), - .id_table = isp1301_id, + .attach_adapter = isp1301_scan_bus, + .detach_client = isp1301_detach_client, }; /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/i2c/chips/mcu_mpc8349emitx.c b/trunk/drivers/i2c/chips/mcu_mpc8349emitx.c deleted file mode 100644 index 82a9bcb858b6..000000000000 --- a/trunk/drivers/i2c/chips/mcu_mpc8349emitx.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU - * - * Copyright (c) 2008 MontaVista Software, Inc. - * - * Author: Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * I don't have specifications for the MCU firmware, I found this register - * and bits positions by the trial&error method. - */ -#define MCU_REG_CTRL 0x20 -#define MCU_CTRL_POFF 0x40 - -#define MCU_NUM_GPIO 2 - -struct mcu { - struct mutex lock; - struct device_node *np; - struct i2c_client *client; - struct of_gpio_chip of_gc; - u8 reg_ctrl; -}; - -static struct mcu *glob_mcu; - -static void mcu_power_off(void) -{ - struct mcu *mcu = glob_mcu; - - pr_info("Sending power-off request to the MCU...\n"); - mutex_lock(&mcu->lock); - i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, - mcu->reg_ctrl | MCU_CTRL_POFF); - mutex_unlock(&mcu->lock); -} - -static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); - struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); - u8 bit = 1 << (4 + gpio); - - mutex_lock(&mcu->lock); - if (val) - mcu->reg_ctrl &= ~bit; - else - mcu->reg_ctrl |= bit; - - i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); - mutex_unlock(&mcu->lock); -} - -static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - mcu_gpio_set(gc, gpio, val); - return 0; -} - -static int mcu_gpiochip_add(struct mcu *mcu) -{ - struct device_node *np; - struct of_gpio_chip *of_gc = &mcu->of_gc; - struct gpio_chip *gc = &of_gc->gc; - int ret; - - np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); - if (!np) - return -ENODEV; - - gc->owner = THIS_MODULE; - gc->label = np->full_name; - gc->can_sleep = 1; - gc->ngpio = MCU_NUM_GPIO; - gc->base = -1; - gc->set = mcu_gpio_set; - gc->direction_output = mcu_gpio_dir_out; - of_gc->gpio_cells = 2; - of_gc->xlate = of_gpio_simple_xlate; - - np->data = of_gc; - mcu->np = np; - - /* - * We don't want to lose the node, its ->data and ->full_name... - * So, if succeeded, we don't put the node here. - */ - ret = gpiochip_add(gc); - if (ret) - of_node_put(np); - return ret; -} - -static int mcu_gpiochip_remove(struct mcu *mcu) -{ - int ret; - - ret = gpiochip_remove(&mcu->of_gc.gc); - if (ret) - return ret; - of_node_put(mcu->np); - - return 0; -} - -static int __devinit mcu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct mcu *mcu; - int ret; - - mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); - if (!mcu) - return -ENOMEM; - - mutex_init(&mcu->lock); - mcu->client = client; - i2c_set_clientdata(client, mcu); - - ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); - if (ret < 0) - goto err; - mcu->reg_ctrl = ret; - - ret = mcu_gpiochip_add(mcu); - if (ret) - goto err; - - /* XXX: this is potentially racy, but there is no lock for ppc_md */ - if (!ppc_md.power_off) { - glob_mcu = mcu; - ppc_md.power_off = mcu_power_off; - dev_info(&client->dev, "will provide power-off service\n"); - } - - return 0; -err: - kfree(mcu); - return ret; -} - -static int __devexit mcu_remove(struct i2c_client *client) -{ - struct mcu *mcu = i2c_get_clientdata(client); - int ret; - - if (glob_mcu == mcu) { - ppc_md.power_off = NULL; - glob_mcu = NULL; - } - - ret = mcu_gpiochip_remove(mcu); - if (ret) - return ret; - i2c_set_clientdata(client, NULL); - kfree(mcu); - return 0; -} - -static const struct i2c_device_id mcu_ids[] = { - { "mcu-mpc8349emitx", }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, mcu_ids); - -static struct i2c_driver mcu_driver = { - .driver = { - .name = "mcu-mpc8349emitx", - .owner = THIS_MODULE, - }, - .probe = mcu_probe, - .remove = __devexit_p(mcu_remove), - .id_table = mcu_ids, -}; - -static int __init mcu_init(void) -{ - return i2c_add_driver(&mcu_driver); -} -module_init(mcu_init); - -static void __exit mcu_exit(void) -{ - i2c_del_driver(&mcu_driver); -} -module_exit(mcu_exit); - -MODULE_DESCRIPTION("Power Management and GPIO expander driver for " - "MPC8349E-mITX-compatible MCU"); -MODULE_AUTHOR("Anton Vorontsov "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/i2c/chips/tps65010.c b/trunk/drivers/i2c/chips/tps65010.c index acf8b9d5f575..cf02e8fceb42 100644 --- a/trunk/drivers/i2c/chips/tps65010.c +++ b/trunk/drivers/i2c/chips/tps65010.c @@ -456,17 +456,14 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) /* offsets 0..3 == GPIO1..GPIO4 * offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes) - * offset 6 == vibrator motor driver */ static void tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { if (offset < 4) tps65010_set_gpio_out_value(offset + 1, value); - else if (offset < 6) - tps65010_set_led(offset - 3, value ? ON : OFF); else - tps65010_set_vib(value); + tps65010_set_led(offset - 3, value ? ON : OFF); } static int @@ -480,10 +477,8 @@ tps65010_output(struct gpio_chip *chip, unsigned offset, int value) if (!(tps->outmask & (1 << offset))) return -EINVAL; tps65010_set_gpio_out_value(offset + 1, value); - } else if (offset < 6) + } else tps65010_set_led(offset - 3, value ? ON : OFF); - else - tps65010_set_vib(value); return 0; } @@ -651,7 +646,7 @@ static int tps65010_probe(struct i2c_client *client, tps->chip.get = tps65010_gpio_get; tps->chip.base = board->base; - tps->chip.ngpio = 7; + tps->chip.ngpio = 6; tps->chip.can_sleep = 1; status = gpiochip_add(&tps->chip); @@ -680,7 +675,6 @@ static const struct i2c_device_id tps65010_id[] = { { "tps65011", TPS65011 }, { "tps65012", TPS65012 }, { "tps65013", TPS65013 }, - { "tps65014", TPS65011 }, /* tps65011 charging at 6.5V max */ { } }; MODULE_DEVICE_TABLE(i2c, tps65010_id); diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index 42e852d79ffa..b346a687ab59 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -437,10 +437,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) { int res = 0, dummy; - /* Can't register until after driver model init */ - if (unlikely(WARN_ON(!i2c_bus_type.p))) - return -EAGAIN; - mutex_init(&adap->bus_lock); mutex_init(&adap->clist_lock); INIT_LIST_HEAD(&adap->clients); @@ -700,10 +696,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) { int res; - /* Can't register until after driver model init */ - if (unlikely(WARN_ON(!i2c_bus_type.p))) - return -EAGAIN; - /* new style driver methods can't mix with legacy ones */ if (is_newstyle_driver(driver)) { if (driver->attach_adapter || driver->detach_adapter @@ -986,10 +978,7 @@ static void __exit i2c_exit(void) bus_unregister(&i2c_bus_type); } -/* We must initialize early, because some subsystems register i2c drivers - * in subsys_initcall() code, but are linked (and initialized) before i2c. - */ -postcore_initcall(i2c_init); +subsys_initcall(i2c_init); module_exit(i2c_exit); /* ---------------------------------------------------- @@ -1687,28 +1676,6 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) } EXPORT_SYMBOL(i2c_smbus_write_word_data); -/** - * i2c_smbus_process_call - SMBus "process call" protocol - * @client: Handle to slave device - * @command: Byte interpreted by slave - * @value: 16-bit "word" being written - * - * This executes the SMBus "process call" protocol, returning negative errno - * else a 16-bit unsigned "word" received from the device. - */ -s32 i2c_smbus_process_call(struct i2c_client *client, u8 command, u16 value) -{ - union i2c_smbus_data data; - int status; - data.word = value; - - status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_WRITE, command, - I2C_SMBUS_PROC_CALL, &data); - return (status < 0) ? status : data.word; -} -EXPORT_SYMBOL(i2c_smbus_process_call); - /** * i2c_smbus_read_block_data - SMBus "block read" protocol * @client: Handle to slave device diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index c171988a9f51..307d976c9b69 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -521,9 +521,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) return PTR_ERR(i2c_dev); /* register this i2c device with the driver core */ - i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, - MKDEV(I2C_MAJOR, adap->nr), NULL, - "i2c-%d", adap->nr); + i2c_dev->dev = device_create_drvdata(i2c_dev_class, &adap->dev, + MKDEV(I2C_MAJOR, adap->nr), + NULL, "i2c-%d", adap->nr); if (IS_ERR(i2c_dev->dev)) { res = PTR_ERR(i2c_dev->dev); goto error; diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index 74a369a6116f..b50b5dac95b0 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -4,7 +4,7 @@ # Select HAVE_IDE if IDE is supported config HAVE_IDE - bool + def_bool n menuconfig IDE tristate "ATA/ATAPI/MFM/RLL support" @@ -54,6 +54,38 @@ menuconfig IDE if IDE +config BLK_DEV_IDE + tristate "Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support" + ---help--- + If you say Y here, you will use the full-featured IDE driver to + control up to ten ATA/IDE interfaces, each being able to serve a + "master" and a "slave" device, for a total of up to twenty ATA/IDE + disk/cdrom/tape/floppy drives. + + Useful information about large (>540 MB) IDE disks, multiple + interfaces, what to do if ATA/IDE devices are not automatically + detected, sound card ATA/IDE ports, module support, and other + topics, is contained in . For detailed + information about hard drives, consult the Disk-HOWTO and the + Multi-Disk-HOWTO, available from + . + + To fine-tune ATA/IDE drive/interface parameters for improved + performance, look for the hdparm package at + . + + To compile this driver as a module, choose M here and read + . The module will be called ide-mod. + Do not compile this driver as a module if your root file system (the + one containing the directory /) is located on an IDE device. + + If you have one or more IDE drives, say Y or M here. If your system + has no IDE drives, or if memory requirements are really tight, you + could say N here, and select the "Old hard disk driver" below + instead to save about 13 KB of memory in the kernel. + +if BLK_DEV_IDE + comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" config IDE_TIMINGS @@ -316,7 +348,7 @@ config BLK_DEV_IDEPCI config IDEPCI_PCIBUS_ORDER bool "Probe IDE PCI devices in the PCI bus order (DEPRECATED)" - depends on IDE=y && BLK_DEV_IDEPCI + depends on BLK_DEV_IDE=y && BLK_DEV_IDEPCI default y help Probe IDE PCI devices in the order in which they appear on the @@ -697,7 +729,7 @@ endif config BLK_DEV_IDE_PMAC tristate "PowerMac on-board IDE support" - depends on PPC_PMAC && IDE=y + depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y select IDE_TIMINGS help This driver provides support for the on-board IDE controller on @@ -931,4 +963,6 @@ config BLK_DEV_IDEDMA def_bool BLK_DEV_IDEDMA_SFF || BLK_DEV_IDEDMA_PMAC || \ BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA +endif + endif # IDE diff --git a/trunk/drivers/ide/Makefile b/trunk/drivers/ide/Makefile index ceaf779054ea..308b8a12f314 100644 --- a/trunk/drivers/ide/Makefile +++ b/trunk/drivers/ide/Makefile @@ -5,25 +5,24 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o ide-park.o ide-pio-blacklist.o + ide-taskfile.o ide-pio-blacklist.o # core IDE code ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o -ide-core-$(CONFIG_BLK_DEV_IDEDMA_SFF) += ide-dma-sff.o ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o -obj-$(CONFIG_IDE) += ide-core.o +obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o ifeq ($(CONFIG_IDE_ARM), y) ide-arm-core-y += arm/ide_arm.o obj-y += ide-arm-core.o endif -obj-$(CONFIG_IDE) += legacy/ pci/ +obj-$(CONFIG_BLK_DEV_IDE) += legacy/ pci/ obj-$(CONFIG_IDEPCI_PCIBUS_ORDER) += ide-scan-pci.o @@ -32,21 +31,15 @@ ifeq ($(CONFIG_BLK_DEV_CMD640), y) obj-y += cmd640-core.o endif -obj-$(CONFIG_IDE) += ppc/ +obj-$(CONFIG_BLK_DEV_IDE) += ppc/ obj-$(CONFIG_IDE_H8300) += h8300/ obj-$(CONFIG_IDE_GENERIC) += ide-generic.o obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o -ide-disk_mod-y += ide-disk.o ide-disk_ioctl.o ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o -ifeq ($(CONFIG_IDE_PROC_FS), y) - ide-disk_mod-y += ide-disk_proc.o - ide-floppy_mod-y += ide-floppy_proc.o -endif - -obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o +obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o @@ -61,4 +54,4 @@ ifeq ($(CONFIG_BLK_DEV_PLATFORM), y) obj-y += ide-platform-core.o endif -obj-$(CONFIG_IDE) += arm/ mips/ +obj-$(CONFIG_BLK_DEV_IDE) += arm/ mips/ diff --git a/trunk/drivers/ide/arm/icside.c b/trunk/drivers/ide/arm/icside.c index 76bdc9a27f6f..70f5b164828b 100644 --- a/trunk/drivers/ide/arm/icside.c +++ b/trunk/drivers/ide/arm/icside.c @@ -372,6 +372,25 @@ static int icside_dma_test_irq(ide_drive_t *drive) ICS_ARCIN_V6_INTRSTAT_1)) & 1; } +static void icside_dma_timeout(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + + printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); + + if (icside_dma_test_irq(drive)) + return; + + ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif)); + + icside_dma_end(drive); +} + +static void icside_dma_lost_irq(ide_drive_t *drive) +{ + printk(KERN_ERR "%s: IRQ lost\n", drive->name); +} + static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d) { hwif->dmatable_cpu = NULL; @@ -387,8 +406,8 @@ static const struct ide_dma_ops icside_v6_dma_ops = { .dma_start = icside_dma_start, .dma_end = icside_dma_end, .dma_test_irq = icside_dma_test_irq, - .dma_timeout = ide_dma_timeout, - .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = icside_dma_timeout, + .dma_lost_irq = icside_dma_lost_irq, }; #else #define icside_v6_dma_ops NULL diff --git a/trunk/drivers/ide/h8300/ide-h8300.c b/trunk/drivers/ide/h8300/ide-h8300.c index e2cdd2e9cdec..bde7a585f198 100644 --- a/trunk/drivers/ide/h8300/ide-h8300.c +++ b/trunk/drivers/ide/h8300/ide-h8300.c @@ -80,7 +80,7 @@ static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - outb((tf->device & HIHI) | drive->select, + outb((tf->device & HIHI) | drive->select.all, io_ports->device_addr); } diff --git a/trunk/drivers/ide/ide-acpi.c b/trunk/drivers/ide/ide-acpi.c index 244a8a052ce8..2427c380b3dc 100644 --- a/trunk/drivers/ide/ide-acpi.c +++ b/trunk/drivers/ide/ide-acpi.c @@ -290,7 +290,7 @@ static int do_drive_get_GTF(ide_drive_t *drive, DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", hwif->name, dev->bus_id, port, hwif->channel); - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) { + if (!drive->present) { DEBPRINT("%s drive %d:%d not present\n", hwif->name, hwif->channel, port); goto out; @@ -420,9 +420,8 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn); - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (!drive->present) goto out; - if (!gtf_count) /* shouldn't be here */ goto out; @@ -661,8 +660,7 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) if (!drive->acpidata->obj_handle) drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); - if (drive->acpidata->obj_handle && - (drive->dev_flags & IDE_DFLAG_PRESENT)) { + if (drive->acpidata->obj_handle && drive->present) { acpi_bus_set_power(drive->acpidata->obj_handle, on? ACPI_STATE_D0: ACPI_STATE_D3); } @@ -722,7 +720,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) memset(drive->acpidata, 0, sizeof(*drive->acpidata)); - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (!drive->present) continue; err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); @@ -747,7 +745,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) for (i = 0; i < MAX_DRIVES; i++) { drive = &hwif->drives[i]; - if (drive->dev_flags & IDE_DFLAG_PRESENT) + if (drive->present) /* Execute ACPI startup code */ ide_acpi_exec_tfs(drive); } diff --git a/trunk/drivers/ide/ide-atapi.c b/trunk/drivers/ide/ide-atapi.c index 2e305714c209..608c5bade929 100644 --- a/trunk/drivers/ide/ide-atapi.c +++ b/trunk/drivers/ide/ide-atapi.c @@ -124,8 +124,8 @@ EXPORT_SYMBOL_GPL(ide_init_pc); * the current request, so that it will be processed immediately, on the next * pass through the driver. */ -static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, - struct ide_atapi_pc *pc, struct request *rq) +void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, + struct ide_atapi_pc *pc, struct request *rq) { blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_SPECIAL; @@ -137,6 +137,7 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, rq->cmd[13] = REQ_IDETAPE_PC1; ide_do_drive_cmd(drive, rq); } +EXPORT_SYMBOL_GPL(ide_queue_pc_head); /* * Add a special packet command request to the tail of the request queue, @@ -202,80 +203,25 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) } EXPORT_SYMBOL_GPL(ide_set_media_lock); -void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) +/* TODO: unify the code thus making some arguments go away */ +ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, + void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), + void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), + int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int)) { - ide_init_pc(pc); - pc->c[0] = REQUEST_SENSE; - if (drive->media == ide_floppy) { - pc->c[4] = 255; - pc->req_xfer = 18; - } else { - pc->c[4] = 20; - pc->req_xfer = 20; - } -} -EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); - -/* - * Called when an error was detected during the last packet command. - * We queue a request sense packet command in the head of the request list. - */ -void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) -{ - struct request *rq = &drive->request_sense_rq; - struct ide_atapi_pc *pc = &drive->request_sense_pc; - - (void)ide_read_error(drive); - ide_create_request_sense_cmd(drive, pc); - if (drive->media == ide_tape) - set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_pc_head(drive, disk, pc, rq); -} -EXPORT_SYMBOL_GPL(ide_retry_pc); - -int ide_scsi_expiry(ide_drive_t *drive) -{ - struct ide_atapi_pc *pc = drive->pc; - - debug_log("%s called for %lu at %lu\n", __func__, - pc->scsi_cmd->serial_number, jiffies); - - pc->flags |= PC_FLAG_TIMEDOUT; - - return 0; /* we do not want the IDE subsystem to retry */ -} -EXPORT_SYMBOL_GPL(ide_scsi_expiry); - -/* - * This is the usual interrupt handler which will be called during a packet - * command. We will transfer some of the data (as requested by the drive) - * and will re-point interrupt handler to us. - */ -static ide_startstop_t ide_pc_intr(ide_drive_t *drive) -{ - struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; xfer_func_t *xferfunc; - ide_expiry_t *expiry; - unsigned int timeout, temp; + unsigned int temp; u16 bcount; - u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0; + u8 stat, ireason, scsi = drive->scsi; debug_log("Enter %s - interrupt handler\n", __func__); - if (scsi) { - timeout = ide_scsi_get_timeout(pc); - expiry = ide_scsi_expiry; - } else { - timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD - : WAIT_TAPE_CMD; - expiry = NULL; - } - if (pc->flags & PC_FLAG_TIMEDOUT) { - drive->pc_callback(drive, 0); + drive->pc_callback(drive); return ide_stopped; } @@ -292,8 +238,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) pc->flags |= PC_FLAG_DMA_ERROR; } else { pc->xferred = pc->req_xfer; - if (drive->pc_update_buffers) - drive->pc_update_buffers(drive, pc); + if (update_buffers) + update_buffers(drive, pc); } debug_log("%s: DMA finished\n", drive->name); } @@ -330,19 +276,21 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) debug_log("[cmd %x]: check condition\n", rq->cmd[0]); /* Retry operation */ - ide_retry_pc(drive, rq->rq_disk); + retry_pc(drive); /* queued, but not started */ return ide_stopped; } cmd_finished: pc->error = 0; - - if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) - dsc = 1; + if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && + (stat & ATA_DSC) == 0) { + dsc_handle(drive); + return ide_stopped; + } /* Command finished - Call the callback function */ - drive->pc_callback(drive, dsc); + drive->pc_callback(drive); return ide_stopped; } @@ -388,8 +336,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) temp = 0; if (temp) { if (pc->sg) - drive->pc_io_buffers(drive, pc, - temp, 0); + io_buffers(drive, pc, temp, 0); else tp_ops->input_data(drive, NULL, pc->cur_pos, temp); @@ -401,7 +348,9 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) pc->xferred += temp; pc->cur_pos += temp; ide_pad_transfer(drive, 0, bcount - temp); - goto next_irq; + ide_set_handler(drive, handler, timeout, + expiry); + return ide_started; } debug_log("The device wants to send us more data than " "expected - allowing transfer\n"); @@ -413,7 +362,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if ((drive->media == ide_floppy && !scsi && !pc->buf) || (drive->media == ide_tape && !scsi && pc->bh) || (scsi && pc->sg)) { - int done = drive->pc_io_buffers(drive, pc, bcount, + int done = io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING)); /* FIXME: don't do partial completions */ @@ -428,11 +377,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) debug_log("[cmd %x] transferred %d bytes on that intr.\n", rq->cmd[0], bcount); -next_irq: + /* And set the interrupt handler again */ - ide_set_handler(drive, ide_pc_intr, timeout, expiry); + ide_set_handler(drive, handler, timeout, expiry); return ide_started; } +EXPORT_SYMBOL_GPL(ide_pc_intr); static u8 ide_read_ireason(ide_drive_t *drive) { @@ -468,22 +418,12 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) return ireason; } -static int ide_delayed_transfer_pc(ide_drive_t *drive) +ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, + ide_expiry_t *expiry) { - /* Send the actual packet */ - drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12); - - /* Timeout for the packet command */ - return WAIT_FLOPPY_CMD; -} - -static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) -{ - struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; - ide_expiry_t *expiry; - unsigned int timeout; ide_startstop_t startstop; u8 ireason; @@ -494,8 +434,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } ireason = ide_read_ireason(drive); - if (drive->media == ide_tape && - (drive->dev_flags & IDE_DFLAG_SCSI) == 0) + if (drive->media == ide_tape && !drive->scsi) ireason = ide_wait_ireason(drive, ireason); if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { @@ -504,27 +443,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return ide_do_reset(drive); } - /* - * If necessary schedule the packet transfer to occur 'timeout' - * miliseconds later in ide_delayed_transfer_pc() after the device - * says it's ready for a packet. - */ - if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { - timeout = drive->pc_delay; - expiry = &ide_delayed_transfer_pc; - } else { - if (drive->dev_flags & IDE_DFLAG_SCSI) { - timeout = ide_scsi_get_timeout(pc); - expiry = ide_scsi_expiry; - } else { - timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD - : WAIT_TAPE_CMD; - expiry = NULL; - } - } - /* Set the interrupt routine */ - ide_set_handler(drive, ide_pc_intr, timeout, expiry); + ide_set_handler(drive, handler, timeout, expiry); /* Begin DMA, if necessary */ if (pc->flags & PC_FLAG_DMA_OK) { @@ -538,22 +458,22 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return ide_started; } +EXPORT_SYMBOL_GPL(ide_transfer_pc); -ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, +ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) { - struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; - u32 tf_flags; u16 bcount; - u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); + u8 dma = 0; /* We haven't transferred any data yet */ pc->xferred = 0; pc->cur_pos = pc->buf; /* Request to transfer the entire buffer at once */ - if (drive->media == ide_tape && scsi == 0) + if (drive->media == ide_tape && !drive->scsi) bcount = pc->req_xfer; else bcount = min(pc->req_xfer, 63 * 1024); @@ -563,35 +483,28 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, ide_dma_off(drive); } - if ((pc->flags & PC_FLAG_DMA_OK) && - (drive->dev_flags & IDE_DFLAG_USING_DMA)) { - if (scsi) + if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { + if (drive->scsi) hwif->sg_mapped = 1; - drive->dma = !hwif->dma_ops->dma_setup(drive); - if (scsi) + dma = !hwif->dma_ops->dma_setup(drive); + if (drive->scsi) hwif->sg_mapped = 0; } - if (!drive->dma) + if (!dma) pc->flags &= ~PC_FLAG_DMA_OK; - if (scsi) - tf_flags = 0; - else if (drive->media == ide_cdrom || drive->media == ide_optical) - tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; - else - tf_flags = IDE_TFLAG_OUT_DEVICE; - - ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); + ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, + bcount, dma); /* Issue the packet command */ if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { - ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, + ide_execute_command(drive, ATA_CMD_PACKET, handler, timeout, NULL); return ide_started; } else { ide_execute_pkt_cmd(drive); - return ide_transfer_pc(drive); + return (*handler)(drive); } } EXPORT_SYMBOL_GPL(ide_issue_pc); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 3308b1cd3a33..465a92ca0179 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -23,9 +23,6 @@ * Documentation/ide/ChangeLog.ide-cd.1994-2004 */ -#define DRV_NAME "ide-cd" -#define PFX DRV_NAME ": " - #define IDECD_VERSION "5.00" #include @@ -53,15 +50,12 @@ #include "ide-cd.h" -#define IDECD_DEBUG_LOG 1 +static DEFINE_MUTEX(idecd_ref_mutex); -#if IDECD_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) -#else -#define ide_debug_log(lvl, fmt, args...) do {} while (0) -#endif +#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) -static DEFINE_MUTEX(idecd_ref_mutex); +#define ide_cd_g(disk) \ + container_of((disk)->private_data, struct cdrom_info, driver) static void ide_cd_release(struct kref *); @@ -70,7 +64,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) struct cdrom_info *cd = NULL; mutex_lock(&idecd_ref_mutex); - cd = ide_drv_g(disk, cdrom_info); + cd = ide_cd_g(disk); if (cd) { if (ide_device_get(cd->drive)) cd = NULL; @@ -108,9 +102,6 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, { int log = 0; - ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__, - sense->sense_key); - if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; @@ -159,14 +150,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, unsigned long bio_sectors; struct cdrom_info *info = drive->driver_data; - ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, " - "sense_key: 0x%x\n", __func__, sense->error_code, - sense->sense_key); - - if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n", - __func__, failed_command->cmd[0]); - if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -217,8 +200,6 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct cdrom_info *info = drive->driver_data; struct request *rq = &info->request_sense_request; - ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__); - if (sense == NULL) sense = &info->sense_data; @@ -238,10 +219,6 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; - if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", - failed_command->cmd[0]); - ide_do_drive_cmd(drive, rq); } @@ -250,10 +227,6 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) struct request *rq = HWGROUP(drive)->rq; int nsectors = rq->hard_cur_sectors; - ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " - "nsectors: %d\n", __func__, rq->cmd[0], uptodate, - nsectors); - if (blk_sense_request(rq) && uptodate) { /* * For REQ_TYPE_SENSE, "rq->buffer" points to the original @@ -296,9 +269,6 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) if (!nsectors) nsectors = 1; - ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n", - __func__, uptodate, nsectors); - ide_end_request(drive, uptodate, nsectors); } @@ -334,15 +304,11 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) sense_key = err >> 4; if (rq == NULL) { - printk(KERN_ERR PFX "%s: missing rq in %s\n", + printk(KERN_ERR "%s: missing rq in %s\n", drive->name, __func__); return 1; } - ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " - "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat, - good_stat, rq->cmd_type, err); - if (blk_sense_request(rq)) { /* * We got an error trying to get sense info from the drive @@ -408,8 +374,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) cdrom_saw_media_change(drive); /* fail the request */ - printk(KERN_ERR PFX "%s: tray open\n", - drive->name); + printk(KERN_ERR "%s: tray open\n", drive->name); do_end_request = 1; } else { struct cdrom_info *info = drive->driver_data; @@ -495,7 +460,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) if (stat & ATA_ERR) cdrom_queue_request_sense(drive, NULL, NULL); } else { - blk_dump_rq_flags(rq, PFX "bad rq"); + blk_dump_rq_flags(rq, "ide-cd: bad rq"); cdrom_end_request(drive, 0); } @@ -523,9 +488,6 @@ static int cdrom_timer_expiry(ide_drive_t *drive) struct request *rq = HWGROUP(drive)->rq; unsigned long wait = 0; - ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__, - rq->cmd[0]); - /* * Some commands are *slow* and normally take a long time to complete. * Usually we can use the ATAPI "disconnect" to bypass this, but not all @@ -542,7 +504,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive) break; default: if (!(rq->cmd_flags & REQ_QUIET)) - printk(KERN_INFO PFX "cmd 0x%x timed out\n", + printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]); wait = 0; break; @@ -562,21 +524,20 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, int xferlen, ide_handler_t *handler) { + struct cdrom_info *info = drive->driver_data; ide_hwif_t *hwif = drive->hwif; - ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); - /* FIXME: for Virtual DMA we must check harder */ - if (drive->dma) - drive->dma = !hwif->dma_ops->dma_setup(drive); + if (info->dma) + info->dma = !hwif->dma_ops->dma_setup(drive); /* set up the controller registers */ ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL, - xferlen, drive->dma); + xferlen, info->dma); if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { /* waiting for CDB interrupt, not DMA yet. */ - if (drive->dma) + if (info->dma) drive->waiting_for_dma = 0; /* packet command */ @@ -603,10 +564,9 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, { ide_hwif_t *hwif = drive->hwif; int cmd_len; + struct cdrom_info *info = drive->driver_data; ide_startstop_t startstop; - ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__); - if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { /* * Here we should have been called after receiving an interrupt @@ -618,7 +578,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, return ide_stopped; /* ok, next interrupt will be DMA interrupt */ - if (drive->dma) + if (info->dma) drive->waiting_for_dma = 1; } else { /* otherwise, we must wait for DRQ to get set */ @@ -639,7 +599,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); /* start the DMA if need be */ - if (drive->dma) + if (info->dma) hwif->dma_ops->dma_start(drive); return ide_started; @@ -655,9 +615,6 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = drive->hwif; - ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n", - __func__, ireason, rw); - /* * ireason == 0: the drive wants to receive data from us * ireason == 2: the drive is expecting to transfer data to us @@ -667,7 +624,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, else if (ireason == (rw << 1)) { /* whoops... */ - printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", + printk(KERN_ERR "%s: %s: wrong transfer direction!\n", drive->name, __func__); ide_pad_transfer(drive, rw, len); @@ -680,7 +637,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, return 0; } else { /* drive wants a command packet, or invalid ireason... */ - printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", + printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", drive->name, __func__, ireason); } @@ -697,19 +654,17 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, */ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) { - ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len); - if ((len % SECTOR_SIZE) == 0) return 0; - printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name, - __func__, len); + printk(KERN_ERR "%s: %s: Bad transfer size %d\n", + drive->name, __func__, len); if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES) - printk(KERN_ERR PFX "This drive is not supported by this " - "version of the driver\n"); + printk(KERN_ERR " This drive is not supported by " + "this version of the driver\n"); else { - printk(KERN_ERR PFX "Trying to limit transfer sizes\n"); + printk(KERN_ERR " Trying to limit transfer sizes\n"); drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES; } @@ -721,9 +676,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__, - rq->cmd_flags); - if (rq_data_dir(rq) == READ) { unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; @@ -743,7 +695,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, /* sanity check... */ if (rq->current_nr_sectors != bio_cur_sectors(rq->bio)) { - printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n", + printk(KERN_ERR "%s: %s: buffer botch (%u)\n", drive->name, __func__, rq->current_nr_sectors); cdrom_end_request(drive, 0); @@ -752,7 +704,11 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, rq->current_nr_sectors += nskip; } } - +#if 0 + else + /* the immediate bit */ + rq->cmd[1] = 1 << 3; +#endif /* set up the command */ rq->timeout = ATAPI_WAIT_PC; @@ -783,8 +739,6 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) int stat; static int retry = 10; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if (cdrom_decode_status(drive, 0, &stat)) return ide_stopped; @@ -792,7 +746,7 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { if (--retry == 0) - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + drive->dsc_overlap = 0; } return ide_stopped; } @@ -801,8 +755,6 @@ static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq) { sector_t frame = rq->sector; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS); memset(rq->cmd, 0, BLK_MAX_CDB); @@ -823,11 +775,8 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) * Fix up a possibly partially-processed request so that we can start it over * entirely, or even put it back on the request queue. */ -static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) +static void restore_request(struct request *rq) { - - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if (rq->buffer != bio_data(rq->bio)) { sector_t n = (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE; @@ -846,11 +795,8 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) /* * All other packet commands. */ -static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) +static void ide_cd_request_sense_fixup(struct request *rq) { - - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - /* * Some of the trailing request sense fields are optional, * and some drives don't send them. Sigh. @@ -876,10 +822,6 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, if (!sense) sense = &local_sense; - ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " - "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, - timeout, cmd_flags); - /* start of retry loop */ do { struct request *rq; @@ -953,6 +895,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq) static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; xfer_func_t *xferfunc; ide_expiry_t *expiry = NULL; @@ -962,16 +905,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) u16 len; u8 ireason; - ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n", - __func__, rq->cmd[0], write); - /* check for errors */ - dma = drive->dma; + dma = info->dma; if (dma) { - drive->dma = 0; + info->dma = 0; dma_error = hwif->dma_ops->dma_end(drive); if (dma_error) { - printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, + printk(KERN_ERR "%s: DMA %s error\n", drive->name, write ? "write" : "read"); ide_dma_off(drive); } @@ -997,9 +937,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (thislen > len) thislen = len; - ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n", - __func__, stat, thislen); - /* If DRQ is clear, the command has completed. */ if ((stat & ATA_DRQ) == 0) { if (blk_fs_request(rq)) { @@ -1009,7 +946,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) */ uptodate = 1; if (rq->current_nr_sectors > 0) { - printk(KERN_ERR PFX "%s: %s: data underrun " + printk(KERN_ERR "%s: %s: data underrun " "(%d blocks)\n", drive->name, __func__, rq->current_nr_sectors); @@ -1020,7 +957,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) cdrom_end_request(drive, uptodate); return ide_stopped; } else if (!blk_pc_request(rq)) { - ide_cd_request_sense_fixup(drive, rq); + ide_cd_request_sense_fixup(rq); /* complain if we still have data left to transfer */ uptodate = rq->data_len ? 0 : 1; } @@ -1063,9 +1000,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) xferfunc = hwif->tp_ops->input_data; } - ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, " - "ireason: 0x%x\n", __func__, rq->cmd_type, ireason); - /* transfer data */ while (thislen > 0) { u8 *ptr = blk_fs_request(rq) ? NULL : rq->data; @@ -1090,7 +1024,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) */ ide_pad_transfer(drive, 0, thislen); else { - printk(KERN_ERR PFX "%s: confused, missing data\n", + printk(KERN_ERR "%s: confused, missing data\n", drive->name); blk_dump_rq_flags(rq, rq_data_dir(rq) ? "cdrom_newpc_intr, write" @@ -1177,9 +1111,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; - ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n", - __func__, write, sectors_per_frame); - if (write) { /* disk has become write protected */ if (get_disk_ro(cd->disk)) { @@ -1191,7 +1122,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) * We may be retrying this request after an error. Fix up any * weirdness which might be present in the request packet. */ - ide_cd_restore_request(drive, rq); + restore_request(rq); } /* use DMA, if possible / writes *must* be hardware frame aligned */ @@ -1201,9 +1132,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) cdrom_end_request(drive, 0); return ide_stopped; } - drive->dma = 0; + cd->dma = 0; } else - drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); + cd->dma = drive->using_dma; if (write) cd->devinfo.media_written = 1; @@ -1220,16 +1151,14 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { - - ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__, - rq->cmd_type); + struct cdrom_info *info = drive->driver_data; if (blk_pc_request(rq)) rq->cmd_flags |= REQ_QUIET; else rq->cmd_flags &= ~REQ_FAILED; - drive->dma = 0; + info->dma = 0; /* sg request */ if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { @@ -1242,7 +1171,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) else buf = rq->data; - drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); + info->dma = drive->using_dma; /* * check if dma is safe @@ -1253,7 +1182,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) alignment = queue_dma_alignment(q) | q->dma_pad_mask; if ((unsigned long)buf & alignment || rq->data_len & alignment || object_is_on_stack(buf)) - drive->dma = 0; + info->dma = 0; } } @@ -1267,9 +1196,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, ide_handler_t *fn; int xferlen; - ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n", - __func__, rq->cmd_type, (unsigned long long)block); - if (blk_fs_request(rq)) { if (drive->atapi_flags & IDE_AFLAG_SEEKING) { ide_hwif_t *hwif = drive->hwif; @@ -1282,7 +1208,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, IDECD_SEEK_TIMER); return ide_stopped; } - printk(KERN_ERR PFX "%s: DSC timeout\n", + printk(KERN_ERR "%s: DSC timeout\n", drive->name); } drive->atapi_flags &= ~IDE_AFLAG_SEEKING; @@ -1290,11 +1216,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, if (rq_data_dir(rq) == READ && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && - (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)) { + drive->dsc_overlap) { xferlen = 0; fn = cdrom_start_seek_continuation; - drive->dma = 0; + info->dma = 0; info->start_seek = jiffies; ide_cd_prepare_seek_request(drive, rq); @@ -1323,7 +1249,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, cdrom_end_request(drive, 1); return ide_stopped; } else { - blk_dump_rq_flags(rq, DRV_NAME " bad flags"); + blk_dump_rq_flags(rq, "ide-cd bad flags"); cdrom_end_request(drive, 0); return ide_stopped; } @@ -1353,8 +1279,6 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_device_info *cdi = &info->devinfo; unsigned char cmd[BLK_MAX_CDB]; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; @@ -1381,8 +1305,6 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, unsigned len = sizeof(capbuf); u32 blocklen; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1402,10 +1324,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, case 4096: break; default: - printk(KERN_ERR PFX "%s: weird block size %u\n", - drive->name, blocklen); - printk(KERN_ERR PFX "%s: default to 2kb block size\n", - drive->name); + printk(KERN_ERR "%s: weird block size %u\n", + drive->name, blocklen); + printk(KERN_ERR "%s: default to 2kb block size\n", + drive->name); blocklen = 2048; break; } @@ -1421,8 +1343,6 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { unsigned char cmd[BLK_MAX_CDB]; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_TOC_PMA_ATIP; @@ -1451,13 +1371,11 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) long last_written; unsigned long sectors_per_frame = SECTORS_PER_FRAME; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if (toc == NULL) { /* try to allocate space */ toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); if (toc == NULL) { - printk(KERN_ERR PFX "%s: No cdrom TOC buffer!\n", + printk(KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name); return -ENOMEM; } @@ -1613,8 +1531,6 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) struct packet_command cgc; int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; @@ -1633,8 +1549,6 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) struct cdrom_info *cd = drive->driver_data; u16 curspeed, maxspeed; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]); @@ -1675,8 +1589,6 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *devinfo = &info->devinfo; - ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots); - devinfo->ops = &ide_cdrom_dops; devinfo->speed = info->current_speed; devinfo->capacity = nslots; @@ -1698,17 +1610,13 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) mechtype_t mechtype; int nslots = 1; - ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, " - "drive->atapi_flags: 0x%lx\n", __func__, drive->media, - drive->atapi_flags); - cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | CDC_MO_DRIVE | CDC_RAM); if (drive->media == ide_optical) { cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM); - printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive\n", + printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name); return nslots; } @@ -1766,7 +1674,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) ide_cdrom_update_speed(drive, buf); - printk(KERN_INFO PFX "%s: ATAPI", drive->name); + printk(KERN_INFO "%s: ATAPI", drive->name); /* don't print speed if the drive reported 0 */ if (cd->max_speed) @@ -1789,8 +1697,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) else printk(KERN_CONT " drive"); - printk(KERN_CONT ", %dkB Cache\n", - be16_to_cpup((__be16 *)&buf[8 + 12])); + printk(KERN_CONT ", %dkB Cache\n", be16_to_cpup((__be16 *)&buf[8 + 12])); return nslots; } @@ -1902,7 +1809,7 @@ static ide_proc_entry_t idecd_proc[] = { { NULL, 0, NULL, NULL } }; -ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); +ide_devset_rw_field(dsc_overlap, dsc_overlap); static const struct ide_proc_devset idecd_settings[] = { IDE_PROC_DEVSET(dsc_overlap, 0, 1), @@ -1977,8 +1884,6 @@ static int ide_cdrom_setup(ide_drive_t *drive) char *fw_rev = (char *)&id[ATA_ID_FW_REV]; int nslots; - ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__); - blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); blk_queue_dma_alignment(drive->queue, 31); blk_queue_update_dma_pad(drive->queue, 15); @@ -1986,9 +1891,14 @@ static int ide_cdrom_setup(ide_drive_t *drive) if (!drive->queue->unplug_delay) drive->queue->unplug_delay = 1; + drive->special.all = 0; + drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT | ide_cd_flags(id); + if ((id[ATA_ID_CONFIG] & 0x0060) == 0x20) + drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; + if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && fw_rev[4] == '1' && fw_rev[6] <= '2') drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD | @@ -2005,13 +1915,10 @@ static int ide_cdrom_setup(ide_drive_t *drive) /* set correct block size */ blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); - if (drive->next != drive) - drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; - else - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + drive->dsc_overlap = (drive->next != drive); if (ide_cdrom_register(drive, nslots)) { - printk(KERN_ERR PFX "%s: %s failed to register device with the" + printk(KERN_ERR "%s: %s failed to register device with the" " cdrom driver.\n", drive->name, __func__); cd->devinfo.handle = NULL; return 1; @@ -2025,8 +1932,6 @@ static void ide_cd_remove(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - ide_proc_unregister_driver(drive, info->driver); del_gendisk(info->disk); @@ -2036,17 +1941,15 @@ static void ide_cd_remove(ide_drive_t *drive) static void ide_cd_release(struct kref *kref) { - struct cdrom_info *info = to_ide_drv(kref, cdrom_info); + struct cdrom_info *info = to_ide_cd(kref); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - kfree(info->toc); if (devinfo->handle == drive) unregister_cdrom(devinfo); - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + drive->dsc_overlap = 0; drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; @@ -2065,6 +1968,7 @@ static ide_driver_t ide_cdrom_driver = { .probe = ide_cd_probe, .remove = ide_cd_remove, .version = IDECD_VERSION, + .media = ide_cdrom, .do_request = ide_cd_do_request, .end_request = ide_end_request, .error = __ide_error, @@ -2095,7 +1999,7 @@ static int idecd_open(struct inode *inode, struct file *file) static int idecd_release(struct inode *inode, struct file *file) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct cdrom_info *info = ide_drv_g(disk, cdrom_info); + struct cdrom_info *info = ide_cd_g(disk); cdrom_release(&info->devinfo, file); @@ -2147,7 +2051,7 @@ static int idecd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); + struct cdrom_info *info = ide_cd_g(bdev->bd_disk); int err; switch (cmd) { @@ -2168,13 +2072,13 @@ static int idecd_ioctl(struct inode *inode, struct file *file, static int idecd_media_changed(struct gendisk *disk) { - struct cdrom_info *info = ide_drv_g(disk, cdrom_info); + struct cdrom_info *info = ide_cd_g(disk); return cdrom_media_changed(&info->devinfo); } static int idecd_revalidate_disk(struct gendisk *disk) { - struct cdrom_info *info = ide_drv_g(disk, cdrom_info); + struct cdrom_info *info = ide_cd_g(disk); struct request_sense sense; ide_cd_read_toc(info->drive, &sense); @@ -2193,11 +2097,8 @@ static struct block_device_operations idecd_ops = { /* module options */ static char *ignore; -module_param(ignore, charp, 0400); - -static unsigned long debug_mask; -module_param(debug_mask, ulong, 0644); +module_param(ignore, charp, 0400); MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); static int ide_cd_probe(ide_drive_t *drive) @@ -2206,10 +2107,6 @@ static int ide_cd_probe(ide_drive_t *drive) struct gendisk *g; struct request_sense sense; - ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, " - "drive->media: 0x%x\n", __func__, drive->driver_req, - drive->media); - if (!strstr("ide-cdrom", drive->driver_req)) goto failed; @@ -2219,17 +2116,14 @@ static int ide_cd_probe(ide_drive_t *drive) /* skip drives that we were told to ignore */ if (ignore != NULL) { if (strstr(ignore, drive->name)) { - printk(KERN_INFO PFX "ignoring drive %s\n", + printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name); goto failed; } } - - drive->debug_mask = debug_mask; - info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); if (info == NULL) { - printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n", + printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name); goto failed; } @@ -2277,7 +2171,6 @@ static void __exit ide_cdrom_exit(void) static int __init ide_cdrom_init(void) { - printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "\n"); return driver_register(&ide_cdrom_driver.gen_driver); } diff --git a/trunk/drivers/ide/ide-cd.h b/trunk/drivers/ide/ide-cd.h index 5882b9a9ea8b..61a4599b77db 100644 --- a/trunk/drivers/ide/ide-cd.h +++ b/trunk/drivers/ide/ide-cd.h @@ -88,6 +88,7 @@ struct cdrom_info { struct request_sense sense_data; struct request request_sense_request; + int dma; unsigned long last_block; unsigned long start_seek; diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index 3853bde8eedc..01846f244b40 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -45,12 +45,21 @@ #define IDE_DISK_MINORS 0 #endif -#include "ide-disk.h" +struct ide_disk_obj { + ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; + struct kref kref; + unsigned int openers; /* protected by BKL for now */ +}; static DEFINE_MUTEX(idedisk_ref_mutex); #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) +#define ide_disk_g(disk) \ + container_of((disk)->private_data, struct ide_disk_obj, driver) + static void ide_disk_release(struct kref *); static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) @@ -131,9 +140,9 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block) { ide_hwif_t *hwif = HWIF(drive); + unsigned int dma = drive->using_dma; u16 nsectors = (u16)rq->nr_sectors; - u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); - u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); + u8 lba48 = (drive->addressing == 1) ? 1 : 0; ide_task_t task; struct ide_taskfile *tf = &task.tf; ide_startstop_t rc; @@ -153,7 +162,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, memset(&task, 0, sizeof(task)); task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - if (drive->dev_flags & IDE_DFLAG_LBA) { + if (drive->select.b.lba) { if (lba48) { pr_debug("%s: LBA=0x%012llx\n", drive->name, (unsigned long long)block); @@ -178,8 +187,6 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, tf->lbah = block >>= 8; tf->device = (block >> 8) & 0xf; } - - tf->device |= ATA_LBA; } else { unsigned int sect, head, cyl, track; @@ -230,7 +237,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = HWIF(drive); - BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); + BUG_ON(drive->blocked); if (!blk_fs_request(rq)) { blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); @@ -377,39 +384,139 @@ static void idedisk_check_hpa(ide_drive_t *drive) static void init_idedisk_capacity(ide_drive_t *drive) { u16 *id = drive->id; - int lba; + /* + * If this drive supports the Host Protected Area feature set, + * then we may need to change our opinion about the drive's capacity. + */ + int hpa = ata_id_hpa_enabled(id); if (ata_id_lba48_enabled(id)) { /* drive speaks 48-bit LBA */ - lba = 1; + drive->select.b.lba = 1; drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); + if (hpa) + idedisk_check_hpa(drive); } else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) { /* drive speaks 28-bit LBA */ - lba = 1; + drive->select.b.lba = 1; drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY); + if (hpa) + idedisk_check_hpa(drive); } else { /* drive speaks boring old 28-bit CHS */ - lba = 0; drive->capacity64 = drive->cyl * drive->head * drive->sect; } +} - if (lba) { - drive->dev_flags |= IDE_DFLAG_LBA; +static sector_t idedisk_capacity(ide_drive_t *drive) +{ + return drive->capacity64; +} - /* - * If this device supports the Host Protected Area feature set, - * then we may need to change our opinion about its capacity. - */ - if (ata_id_hpa_enabled(id)) - idedisk_check_hpa(drive); +#ifdef CONFIG_IDE_PROC_FS +static int smart_enable(ide_drive_t *drive) +{ + ide_task_t args; + struct ide_taskfile *tf = &args.tf; + + memset(&args, 0, sizeof(ide_task_t)); + tf->feature = ATA_SMART_ENABLE; + tf->lbam = ATA_SMART_LBAM_PASS; + tf->lbah = ATA_SMART_LBAH_PASS; + tf->command = ATA_CMD_SMART; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + return ide_no_data_taskfile(drive, &args); +} + +static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) +{ + ide_task_t args; + struct ide_taskfile *tf = &args.tf; + + memset(&args, 0, sizeof(ide_task_t)); + tf->feature = sub_cmd; + tf->nsect = 0x01; + tf->lbam = ATA_SMART_LBAM_PASS; + tf->lbah = ATA_SMART_LBAH_PASS; + tf->command = ATA_CMD_SMART; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.data_phase = TASKFILE_IN; + (void) smart_enable(drive); + return ide_raw_taskfile(drive, &args, buf, 1); +} + +static int proc_idedisk_read_cache + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + ide_drive_t *drive = (ide_drive_t *) data; + char *out = page; + int len; + + if (drive->id_read) + len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); + else + len = sprintf(out, "(none)\n"); + + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +static int proc_idedisk_read_capacity + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + ide_drive_t*drive = (ide_drive_t *)data; + int len; + + len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive)); + + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +static int proc_idedisk_read_smart(char *page, char **start, off_t off, + int count, int *eof, void *data, u8 sub_cmd) +{ + ide_drive_t *drive = (ide_drive_t *)data; + int len = 0, i = 0; + + if (get_smart_data(drive, page, sub_cmd) == 0) { + unsigned short *val = (unsigned short *) page; + char *out = (char *)val + SECTOR_SIZE; + + page = out; + do { + out += sprintf(out, "%04x%c", le16_to_cpu(*val), + (++i & 7) ? ' ' : '\n'); + val += 1; + } while (i < SECTOR_SIZE / 2); + len = out - page; } + + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); } -sector_t ide_disk_capacity(ide_drive_t *drive) +static int proc_idedisk_read_sv + (char *page, char **start, off_t off, int count, int *eof, void *data) { - return drive->capacity64; + return proc_idedisk_read_smart(page, start, off, count, eof, data, + ATA_SMART_READ_VALUES); } +static int proc_idedisk_read_st + (char *page, char **start, off_t off, int count, int *eof, void *data) +{ + return proc_idedisk_read_smart(page, start, off, count, eof, data, + ATA_SMART_READ_THRESHOLDS); +} + +static ide_proc_entry_t idedisk_proc[] = { + { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, + { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, + { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, + { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL }, + { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL }, + { NULL, 0, NULL, NULL } +}; +#endif /* CONFIG_IDE_PROC_FS */ + static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) { ide_drive_t *drive = q->queuedata; @@ -461,43 +568,25 @@ static int set_multcount(ide_drive_t *drive, int arg) return (drive->mult_count == arg) ? 0 : -EIO; } -ide_devset_get_flag(nowerr, IDE_DFLAG_NOWERR); +ide_devset_get(nowerr, nowerr); static int set_nowerr(ide_drive_t *drive, int arg) { if (arg < 0 || arg > 1) return -EINVAL; - if (arg) - drive->dev_flags |= IDE_DFLAG_NOWERR; - else - drive->dev_flags &= ~IDE_DFLAG_NOWERR; - + drive->nowerr = arg; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; - return 0; } -static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect) -{ - ide_task_t task; - - memset(&task, 0, sizeof(task)); - task.tf.feature = feature; - task.tf.nsect = nsect; - task.tf.command = ATA_CMD_SET_FEATURES; - task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - - return ide_no_data_taskfile(drive, &task); -} - static void update_ordered(ide_drive_t *drive) { u16 *id = drive->id; unsigned ordered = QUEUE_ORDERED_NONE; prepare_flush_fn *prep_fn = NULL; - if (drive->dev_flags & IDE_DFLAG_WCACHE) { + if (drive->wcache) { unsigned long long capacity; int barrier; /* @@ -508,11 +597,9 @@ static void update_ordered(ide_drive_t *drive) * time we have trimmed the drive capacity if LBA48 is * not available so we don't need to recheck that. */ - capacity = ide_disk_capacity(drive); - barrier = ata_id_flush_enabled(id) && - (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 && - ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 || - capacity <= (1ULL << 28) || + capacity = idedisk_capacity(drive); + barrier = ata_id_flush_enabled(id) && !drive->noflush && + (drive->addressing == 0 || capacity <= (1ULL << 28) || ata_id_flush_ext_enabled(id)); printk(KERN_INFO "%s: cache flushes %ssupported\n", @@ -528,24 +615,25 @@ static void update_ordered(ide_drive_t *drive) blk_queue_ordered(drive->queue, ordered, prep_fn); } -ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE); +ide_devset_get(wcache, wcache); static int set_wcache(ide_drive_t *drive, int arg) { + ide_task_t args; int err = 1; if (arg < 0 || arg > 1) return -EINVAL; if (ata_id_flush_enabled(drive->id)) { - err = ide_do_setfeature(drive, - arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF, 0); - if (err == 0) { - if (arg) - drive->dev_flags |= IDE_DFLAG_WCACHE; - else - drive->dev_flags &= ~IDE_DFLAG_WCACHE; - } + memset(&args, 0, sizeof(ide_task_t)); + args.tf.feature = arg ? + SETFEATURES_WC_ON : SETFEATURES_WC_OFF; + args.tf.command = ATA_CMD_SET_FEATURES; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + err = ide_no_data_taskfile(drive, &args); + if (err == 0) + drive->wcache = arg; } update_ordered(drive); @@ -570,18 +658,22 @@ ide_devset_get(acoustic, acoustic); static int set_acoustic(ide_drive_t *drive, int arg) { + ide_task_t args; + if (arg < 0 || arg > 254) return -EINVAL; - ide_do_setfeature(drive, - arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF, arg); - + memset(&args, 0, sizeof(ide_task_t)); + args.tf.feature = arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF; + args.tf.nsect = arg; + args.tf.command = ATA_CMD_SET_FEATURES; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + ide_no_data_taskfile(drive, &args); drive->acoustic = arg; - return 0; } -ide_devset_get_flag(addressing, IDE_DFLAG_LBA48); +ide_devset_get(addressing, addressing); /* * drive->addressing: @@ -594,27 +686,49 @@ static int set_addressing(ide_drive_t *drive, int arg) if (arg < 0 || arg > 2) return -EINVAL; - if (arg && ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) || - ata_id_lba48_enabled(drive->id) == 0)) - return -EIO; + drive->addressing = 0; - if (arg == 2) - arg = 0; + if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) + return 0; - if (arg) - drive->dev_flags |= IDE_DFLAG_LBA48; - else - drive->dev_flags &= ~IDE_DFLAG_LBA48; + if (ata_id_lba48_enabled(drive->id) == 0) + return -EIO; + + drive->addressing = arg; return 0; } -ide_ext_devset_rw(acoustic, acoustic); -ide_ext_devset_rw(address, addressing); -ide_ext_devset_rw(multcount, multcount); -ide_ext_devset_rw(wcache, wcache); +ide_devset_rw(acoustic, acoustic); +ide_devset_rw(address, addressing); +ide_devset_rw(multcount, multcount); +ide_devset_rw(wcache, wcache); + +ide_devset_rw_sync(nowerr, nowerr); -ide_ext_devset_rw_sync(nowerr, nowerr); +#ifdef CONFIG_IDE_PROC_FS +ide_devset_rw_field(bios_cyl, bios_cyl); +ide_devset_rw_field(bios_head, bios_head); +ide_devset_rw_field(bios_sect, bios_sect); +ide_devset_rw_field(failures, failures); +ide_devset_rw_field(lun, lun); +ide_devset_rw_field(max_failures, max_failures); + +static const struct ide_proc_devset idedisk_settings[] = { + IDE_PROC_DEVSET(acoustic, 0, 254), + IDE_PROC_DEVSET(address, 0, 2), + IDE_PROC_DEVSET(bios_cyl, 0, 65535), + IDE_PROC_DEVSET(bios_head, 0, 255), + IDE_PROC_DEVSET(bios_sect, 0, 63), + IDE_PROC_DEVSET(failures, 0, 65535), + IDE_PROC_DEVSET(lun, 0, 7), + IDE_PROC_DEVSET(max_failures, 0, 65535), + IDE_PROC_DEVSET(multcount, 0, 16), + IDE_PROC_DEVSET(nowerr, 0, 1), + IDE_PROC_DEVSET(wcache, 0, 1), + { 0 }, +}; +#endif static void idedisk_setup(ide_drive_t *drive) { @@ -626,20 +740,20 @@ static void idedisk_setup(ide_drive_t *drive) ide_proc_register_driver(drive, idkp->driver); - if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) + if (drive->id_read == 0) return; - if (drive->dev_flags & IDE_DFLAG_REMOVABLE) { + if (drive->removable) { /* * Removable disks (eg. SYQUEST); ignore 'WD' drives */ if (m[0] != 'W' || m[1] != 'D') - drive->dev_flags |= IDE_DFLAG_DOORLOCKING; + drive->doorlocking = 1; } (void)set_addressing(drive, 1); - if (drive->dev_flags & IDE_DFLAG_LBA48) { + if (drive->addressing == 1) { int max_s = 2048; if (max_s > hwif->rqsize) @@ -655,8 +769,7 @@ static void idedisk_setup(ide_drive_t *drive) init_idedisk_capacity(drive); /* limit drive capacity to 137GB if LBA48 cannot be used */ - if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 && - drive->capacity64 > 1ULL << 28) { + if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) { printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " "%llu sectors (%llu MB)\n", drive->name, (unsigned long long)drive->capacity64, @@ -664,23 +777,22 @@ static void idedisk_setup(ide_drive_t *drive) drive->capacity64 = 1ULL << 28; } - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && - (drive->dev_flags & IDE_DFLAG_LBA48)) { + if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) { if (drive->capacity64 > 1ULL << 28) { printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" " will be used for accessing sectors " "> %u\n", drive->name, 1 << 28); } else - drive->dev_flags &= ~IDE_DFLAG_LBA48; + drive->addressing = 0; } /* * if possible, give fdisk access to more of the drive, * by correcting bios_cyls: */ - capacity = ide_disk_capacity(drive); + capacity = idedisk_capacity(drive); - if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { + if (!drive->forced_geom) { if (ata_id_lba48_enabled(drive->id)) { /* compatibility */ drive->bios_sect = 63; @@ -715,15 +827,14 @@ static void idedisk_setup(ide_drive_t *drive) /* write cache enabled? */ if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id)) - drive->dev_flags |= IDE_DFLAG_WCACHE; + drive->wcache = 1; set_wcache(drive, 1); } static void ide_cacheflush_p(ide_drive_t *drive) { - if (ata_id_flush_enabled(drive->id) == 0 || - (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) + if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) return; if (do_idedisk_flushcache(drive)) @@ -807,12 +918,13 @@ static ide_driver_t idedisk_driver = { .resume = ide_disk_resume, .shutdown = ide_device_shutdown, .version = IDEDISK_VERSION, + .media = ide_disk, .do_request = ide_do_rw_disk, .end_request = ide_end_request, .error = __ide_error, #ifdef CONFIG_IDE_PROC_FS - .proc = ide_disk_proc, - .settings = ide_disk_settings, + .proc = idedisk_proc, + .settings = idedisk_settings, #endif }; @@ -841,16 +953,15 @@ static int idedisk_open(struct inode *inode, struct file *filp) idkp->openers++; - if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { + if (drive->removable && idkp->openers == 1) { check_disk_change(inode->i_bdev); /* * Ignore the return code from door_lock, * since the open() has already succeeded, * and the door_lock is irrelevant at this point. */ - if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && - idedisk_set_doorlock(drive, 1)) - drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; + if (drive->doorlocking && idedisk_set_doorlock(drive, 1)) + drive->doorlocking = 0; } return 0; } @@ -864,10 +975,9 @@ static int idedisk_release(struct inode *inode, struct file *filp) if (idkp->openers == 1) ide_cacheflush_p(drive); - if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { - if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && - idedisk_set_doorlock(drive, 0)) - drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; + if (drive->removable && idkp->openers == 1) { + if (drive->doorlocking && idedisk_set_doorlock(drive, 0)) + drive->doorlocking = 0; } idkp->openers--; @@ -888,25 +998,48 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } +static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { +{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address }, +{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount }, +{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr }, +{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache }, +{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic }, +{ 0 } +}; + +static int idedisk_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); + ide_drive_t *drive = idkp->drive; + int err; + + err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); + if (err != -EOPNOTSUPP) + return err; + + return generic_ide_ioctl(drive, file, bdev, cmd, arg); +} + static int idedisk_media_changed(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_disk_g(disk); ide_drive_t *drive = idkp->drive; /* do not scan partitions twice if this is a removable device */ - if (drive->dev_flags & IDE_DFLAG_ATTACH) { - drive->dev_flags &= ~IDE_DFLAG_ATTACH; + if (drive->attach) { + drive->attach = 0; return 0; } - /* if removable, always assume it was changed */ - return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE); + return drive->removable; } static int idedisk_revalidate_disk(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_disk_g(disk); - set_capacity(disk, ide_disk_capacity(idkp->drive)); + set_capacity(disk, idedisk_capacity(idkp->drive)); return 0; } @@ -914,7 +1047,7 @@ static struct block_device_operations idedisk_ops = { .owner = THIS_MODULE, .open = idedisk_open, .release = idedisk_release, - .ioctl = ide_disk_ioctl, + .ioctl = idedisk_ioctl, .getgeo = idedisk_getgeo, .media_changed = idedisk_media_changed, .revalidate_disk = idedisk_revalidate_disk @@ -955,20 +1088,19 @@ static int ide_disk_probe(ide_drive_t *drive) drive->driver_data = idkp; idedisk_setup(drive); - if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && - (drive->head == 0 || drive->head > 16)) { + if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head); - drive->dev_flags &= ~IDE_DFLAG_ATTACH; + drive->attach = 0; } else - drive->dev_flags |= IDE_DFLAG_ATTACH; + drive->attach = 1; g->minors = IDE_DISK_MINORS; g->driverfs_dev = &drive->gendev; g->flags |= GENHD_FL_EXT_DEVT; - if (drive->dev_flags & IDE_DFLAG_REMOVABLE) - g->flags = GENHD_FL_REMOVABLE; - set_capacity(g, ide_disk_capacity(drive)); + if (drive->removable) + g->flags |= GENHD_FL_REMOVABLE; + set_capacity(g, idedisk_capacity(drive)); g->fops = &idedisk_ops; add_disk(g); return 0; @@ -990,7 +1122,6 @@ static int __init idedisk_init(void) } MODULE_ALIAS("ide:*m-disk*"); -MODULE_ALIAS("ide-disk"); module_init(idedisk_init); module_exit(idedisk_exit); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/ide/ide-disk.h b/trunk/drivers/ide/ide-disk.h deleted file mode 100644 index a82fa4355665..000000000000 --- a/trunk/drivers/ide/ide-disk.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __IDE_DISK_H -#define __IDE_DISK_H - -struct ide_disk_obj { - ide_drive_t *drive; - ide_driver_t *driver; - struct gendisk *disk; - struct kref kref; - unsigned int openers; /* protected by BKL for now */ -}; - -#define ide_disk_g(disk) \ - container_of((disk)->private_data, struct ide_disk_obj, driver) - -/* ide-disk.c */ -sector_t ide_disk_capacity(ide_drive_t *); -ide_decl_devset(address); -ide_decl_devset(multcount); -ide_decl_devset(nowerr); -ide_decl_devset(wcache); -ide_decl_devset(acoustic); - -/* ide-disk_ioctl.c */ -int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - -#ifdef CONFIG_IDE_PROC_FS -/* ide-disk_proc.c */ -extern ide_proc_entry_t ide_disk_proc[]; -extern const struct ide_proc_devset ide_disk_settings[]; -#endif - -#endif /* __IDE_DISK_H */ diff --git a/trunk/drivers/ide/ide-disk_ioctl.c b/trunk/drivers/ide/ide-disk_ioctl.c deleted file mode 100644 index a6cf1a03a806..000000000000 --- a/trunk/drivers/ide/ide-disk_ioctl.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -#include "ide-disk.h" - -static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { -{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address }, -{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount }, -{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr }, -{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache }, -{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic }, -{ 0 } -}; - -int ide_disk_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct block_device *bdev = inode->i_bdev; - struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); - ide_drive_t *drive = idkp->drive; - int err; - - err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); - if (err != -EOPNOTSUPP) - return err; - - return generic_ide_ioctl(drive, file, bdev, cmd, arg); -} diff --git a/trunk/drivers/ide/ide-disk_proc.c b/trunk/drivers/ide/ide-disk_proc.c deleted file mode 100644 index 4724976afe71..000000000000 --- a/trunk/drivers/ide/ide-disk_proc.c +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include - -#include "ide-disk.h" - -static int smart_enable(ide_drive_t *drive) -{ - ide_task_t args; - struct ide_taskfile *tf = &args.tf; - - memset(&args, 0, sizeof(ide_task_t)); - tf->feature = ATA_SMART_ENABLE; - tf->lbam = ATA_SMART_LBAM_PASS; - tf->lbah = ATA_SMART_LBAH_PASS; - tf->command = ATA_CMD_SMART; - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - return ide_no_data_taskfile(drive, &args); -} - -static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) -{ - ide_task_t args; - struct ide_taskfile *tf = &args.tf; - - memset(&args, 0, sizeof(ide_task_t)); - tf->feature = sub_cmd; - tf->nsect = 0x01; - tf->lbam = ATA_SMART_LBAM_PASS; - tf->lbah = ATA_SMART_LBAH_PASS; - tf->command = ATA_CMD_SMART; - args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - args.data_phase = TASKFILE_IN; - (void) smart_enable(drive); - return ide_raw_taskfile(drive, &args, buf, 1); -} - -static int proc_idedisk_read_cache - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - ide_drive_t *drive = (ide_drive_t *) data; - char *out = page; - int len; - - if (drive->dev_flags & IDE_DFLAG_ID_READ) - len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); - else - len = sprintf(out, "(none)\n"); - - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -static int proc_idedisk_read_capacity - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - ide_drive_t*drive = (ide_drive_t *)data; - int len; - - len = sprintf(page, "%llu\n", (long long)ide_disk_capacity(drive)); - - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -static int proc_idedisk_read_smart(char *page, char **start, off_t off, - int count, int *eof, void *data, u8 sub_cmd) -{ - ide_drive_t *drive = (ide_drive_t *)data; - int len = 0, i = 0; - - if (get_smart_data(drive, page, sub_cmd) == 0) { - unsigned short *val = (unsigned short *) page; - char *out = (char *)val + SECTOR_SIZE; - - page = out; - do { - out += sprintf(out, "%04x%c", le16_to_cpu(*val), - (++i & 7) ? ' ' : '\n'); - val += 1; - } while (i < SECTOR_SIZE / 2); - len = out - page; - } - - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -static int proc_idedisk_read_sv - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - return proc_idedisk_read_smart(page, start, off, count, eof, data, - ATA_SMART_READ_VALUES); -} - -static int proc_idedisk_read_st - (char *page, char **start, off_t off, int count, int *eof, void *data) -{ - return proc_idedisk_read_smart(page, start, off, count, eof, data, - ATA_SMART_READ_THRESHOLDS); -} - -ide_proc_entry_t ide_disk_proc[] = { - { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, - { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, - { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, - { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL }, - { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL }, - { NULL, 0, NULL, NULL } -}; - -ide_devset_rw_field(bios_cyl, bios_cyl); -ide_devset_rw_field(bios_head, bios_head); -ide_devset_rw_field(bios_sect, bios_sect); -ide_devset_rw_field(failures, failures); -ide_devset_rw_field(lun, lun); -ide_devset_rw_field(max_failures, max_failures); - -const struct ide_proc_devset ide_disk_settings[] = { - IDE_PROC_DEVSET(acoustic, 0, 254), - IDE_PROC_DEVSET(address, 0, 2), - IDE_PROC_DEVSET(bios_cyl, 0, 65535), - IDE_PROC_DEVSET(bios_head, 0, 255), - IDE_PROC_DEVSET(bios_sect, 0, 63), - IDE_PROC_DEVSET(failures, 0, 65535), - IDE_PROC_DEVSET(lun, 0, 7), - IDE_PROC_DEVSET(max_failures, 0, 65535), - IDE_PROC_DEVSET(multcount, 0, 16), - IDE_PROC_DEVSET(nowerr, 0, 1), - IDE_PROC_DEVSET(wcache, 0, 1), - { 0 }, -}; diff --git a/trunk/drivers/ide/ide-dma-sff.c b/trunk/drivers/ide/ide-dma-sff.c deleted file mode 100644 index 0903782689e9..000000000000 --- a/trunk/drivers/ide/ide-dma-sff.c +++ /dev/null @@ -1,356 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/** - * config_drive_for_dma - attempt to activate IDE DMA - * @drive: the drive to place in DMA mode - * - * If the drive supports at least mode 2 DMA or UDMA of any kind - * then attempt to place it into DMA mode. Drives that are known to - * support DMA but predate the DMA properties or that are known - * to have DMA handling bugs are also set up appropriately based - * on the good/bad drive lists. - */ - -int config_drive_for_dma(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u16 *id = drive->id; - - if (drive->media != ide_disk) { - if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA) - return 0; - } - - /* - * Enable DMA on any drive that has - * UltraDMA (mode 0/1/2/3/4/5/6) enabled - */ - if ((id[ATA_ID_FIELD_VALID] & 4) && - ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f)) - return 1; - - /* - * Enable DMA on any drive that has mode2 DMA - * (multi or single) enabled - */ - if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */ - if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || - (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) - return 1; - - /* Consult the list of known "good" drives */ - if (ide_dma_good_drive(drive)) - return 1; - - return 0; -} - -/** - * ide_dma_host_set - Enable/disable DMA on a host - * @drive: drive to control - * - * Enable/disable DMA on an IDE controller following generic - * bus-mastering IDE controller behaviour. - */ - -void ide_dma_host_set(ide_drive_t *drive, int on) -{ - ide_hwif_t *hwif = drive->hwif; - u8 unit = drive->dn & 1; - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - if (on) - dma_stat |= (1 << (5 + unit)); - else - dma_stat &= ~(1 << (5 + unit)); - - if (hwif->host_flags & IDE_HFLAG_MMIO) - writeb(dma_stat, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); -} -EXPORT_SYMBOL_GPL(ide_dma_host_set); - -/** - * ide_build_dmatable - build IDE DMA table - * - * ide_build_dmatable() prepares a dma request. We map the command - * to get the pci bus addresses of the buffers and then build up - * the PRD table that the IDE layer wants to be fed. - * - * Most chipsets correctly interpret a length of 0x0000 as 64KB, - * but at least one (e.g. CS5530) misinterprets it as zero (!). - * So we break the 64KB entry into two 32KB entries instead. - * - * Returns the number of built PRD entries if all went okay, - * returns 0 otherwise. - * - * May also be invoked from trm290.c - */ - -int ide_build_dmatable(ide_drive_t *drive, struct request *rq) -{ - ide_hwif_t *hwif = drive->hwif; - __le32 *table = (__le32 *)hwif->dmatable_cpu; - unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0; - unsigned int count = 0; - int i; - struct scatterlist *sg; - - hwif->sg_nents = ide_build_sglist(drive, rq); - if (hwif->sg_nents == 0) - return 0; - - for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) { - u32 cur_addr, cur_len, xcount, bcount; - - cur_addr = sg_dma_address(sg); - cur_len = sg_dma_len(sg); - - /* - * Fill in the dma table, without crossing any 64kB boundaries. - * Most hardware requires 16-bit alignment of all blocks, - * but the trm290 requires 32-bit alignment. - */ - - while (cur_len) { - if (count++ >= PRD_ENTRIES) - goto use_pio_instead; - - bcount = 0x10000 - (cur_addr & 0xffff); - if (bcount > cur_len) - bcount = cur_len; - *table++ = cpu_to_le32(cur_addr); - xcount = bcount & 0xffff; - if (is_trm290) - xcount = ((xcount >> 2) - 1) << 16; - if (xcount == 0x0000) { - if (count++ >= PRD_ENTRIES) - goto use_pio_instead; - *table++ = cpu_to_le32(0x8000); - *table++ = cpu_to_le32(cur_addr + 0x8000); - xcount = 0x8000; - } - *table++ = cpu_to_le32(xcount); - cur_addr += bcount; - cur_len -= bcount; - } - } - - if (count) { - if (!is_trm290) - *--table |= cpu_to_le32(0x80000000); - return count; - } - -use_pio_instead: - printk(KERN_ERR "%s: %s\n", drive->name, - count ? "DMA table too small" : "empty DMA table?"); - - ide_destroy_dmatable(drive); - - return 0; /* revert to PIO for this request */ -} -EXPORT_SYMBOL_GPL(ide_build_dmatable); - -/** - * ide_dma_setup - begin a DMA phase - * @drive: target device - * - * Build an IDE DMA PRD (IDE speak for scatter gather table) - * and then set up the DMA transfer registers for a device - * that follows generic IDE PCI DMA behaviour. Controllers can - * override this function if they need to - * - * Returns 0 on success. If a PIO fallback is required then 1 - * is returned. - */ - -int ide_dma_setup(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct request *rq = hwif->hwgroup->rq; - unsigned int reading; - u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 dma_stat; - - if (rq_data_dir(rq)) - reading = 0; - else - reading = 1 << 3; - - /* fall back to pio! */ - if (!ide_build_dmatable(drive, rq)) { - ide_map_sg(drive, rq); - return 1; - } - - /* PRD table */ - if (hwif->host_flags & IDE_HFLAG_MMIO) - writel(hwif->dmatable_dma, - (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); - else - outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); - - /* specify r/w */ - if (mmio) - writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - else - outb(reading, hwif->dma_base + ATA_DMA_CMD); - - /* read DMA status for INTR & ERROR flags */ - dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - /* clear INTR & ERROR flags */ - if (mmio) - writeb(dma_stat | 6, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); - - drive->waiting_for_dma = 1; - return 0; -} -EXPORT_SYMBOL_GPL(ide_dma_setup); - -/** - * dma_timer_expiry - handle a DMA timeout - * @drive: Drive that timed out - * - * An IDE DMA transfer timed out. In the event of an error we ask - * the driver to resolve the problem, if a DMA transfer is still - * in progress we continue to wait (arguably we need to add a - * secondary 'I don't care what the drive thinks' timeout here) - * Finally if we have an interrupt we let it complete the I/O. - * But only one time - we clear expiry and if it's still not - * completed after WAIT_CMD, we error and retry in PIO. - * This can occur if an interrupt is lost or due to hang or bugs. - */ - -static int dma_timer_expiry(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", - drive->name, __func__, dma_stat); - - if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ - return WAIT_CMD; - - hwif->hwgroup->expiry = NULL; /* one free ride for now */ - - /* 1 dmaing, 2 error, 4 intr */ - if (dma_stat & 2) /* ERROR */ - return -1; - - if (dma_stat & 1) /* DMAing */ - return WAIT_CMD; - - if (dma_stat & 4) /* Got an Interrupt */ - return WAIT_CMD; - - return 0; /* Status is unknown -- reset the bus */ -} - -void ide_dma_exec_cmd(ide_drive_t *drive, u8 command) -{ - /* issue cmd to drive */ - ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD, - dma_timer_expiry); -} -EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); - -void ide_dma_start(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 dma_cmd; - - /* Note that this is done *after* the cmd has - * been issued to the drive, as per the BM-IDE spec. - * The Promise Ultra33 doesn't work correctly when - * we do this part before issuing the drive cmd. - */ - if (hwif->host_flags & IDE_HFLAG_MMIO) { - dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* start DMA */ - writeb(dma_cmd | 1, - (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - } else { - dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); - } - - wmb(); -} -EXPORT_SYMBOL_GPL(ide_dma_start); - -/* returns 1 on error, 0 otherwise */ -int ide_dma_end(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 dma_stat = 0, dma_cmd = 0; - - drive->waiting_for_dma = 0; - - if (mmio) { - /* get DMA command mode */ - dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* stop DMA */ - writeb(dma_cmd & ~1, - (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - } else { - dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); - } - - /* get DMA status */ - dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - if (mmio) - /* clear the INTR & ERROR bits */ - writeb(dma_stat | 6, - (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); - else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); - - /* purge DMA mappings */ - ide_destroy_dmatable(drive); - /* verify good DMA status */ - wmb(); - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; -} -EXPORT_SYMBOL_GPL(ide_dma_end); - -/* returns 1 if dma irq issued, 0 otherwise */ -int ide_dma_test_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - - return 0; -} -EXPORT_SYMBOL_GPL(ide_dma_test_irq); - -const struct ide_dma_ops sff_dma_ops = { - .dma_host_set = ide_dma_host_set, - .dma_setup = ide_dma_setup, - .dma_exec_cmd = ide_dma_exec_cmd, - .dma_start = ide_dma_start, - .dma_end = ide_dma_end, - .dma_test_irq = ide_dma_test_irq, - .dma_timeout = ide_dma_timeout, - .dma_lost_irq = ide_dma_lost_irq, -}; -EXPORT_SYMBOL_GPL(sff_dma_ops); diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index fffd11717b2d..ef2f1504c0d5 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -28,13 +28,24 @@ * for supplying a Promise UDMA board & WD UDMA drive for this work! */ +#include #include #include +#include +#include +#include +#include +#include #include +#include #include #include -static const struct drive_list_entry drive_whitelist[] = { +#include +#include + +static const struct drive_list_entry drive_whitelist [] = { + { "Micropolis 2112A" , NULL }, { "CONNER CTMA 4000" , NULL }, { "CONNER CTT8000-A" , NULL }, @@ -42,7 +53,8 @@ static const struct drive_list_entry drive_whitelist[] = { { NULL , NULL } }; -static const struct drive_list_entry drive_blacklist[] = { +static const struct drive_list_entry drive_blacklist [] = { + { "WDC AC11000H" , NULL }, { "WDC AC22100H" , NULL }, { "WDC AC32500H" , NULL }, @@ -82,11 +94,11 @@ static const struct drive_list_entry drive_blacklist[] = { * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for * - * Handle an interrupt completing a read/write DMA transfer on an + * Handle an interrupt completing a read/write DMA transfer on an * IDE device */ - -ide_startstop_t ide_dma_intr(ide_drive_t *drive) + +ide_startstop_t ide_dma_intr (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 stat = 0, dma_stat = 0; @@ -96,19 +108,20 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive) if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { if (!dma_stat) { - struct request *rq = hwif->hwgroup->rq; + struct request *rq = HWGROUP(drive)->rq; task_end_request(drive, rq, stat); return ide_stopped; } - printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n", - drive->name, __func__, dma_stat); + printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", + drive->name, dma_stat); } return ide_error(drive, "dma_intr", stat); } + EXPORT_SYMBOL_GPL(ide_dma_intr); -int ide_dma_good_drive(ide_drive_t *drive) +static int ide_dma_good_drive(ide_drive_t *drive) { return ide_in_drive_list(drive->id, drive_whitelist); } @@ -126,7 +139,7 @@ int ide_dma_good_drive(ide_drive_t *drive) int ide_build_sglist(ide_drive_t *drive, struct request *rq) { - ide_hwif_t *hwif = drive->hwif; + ide_hwif_t *hwif = HWIF(drive); struct scatterlist *sg = hwif->sg_table; ide_map_sg(drive, rq); @@ -139,8 +152,106 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq) return dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction); } + EXPORT_SYMBOL_GPL(ide_build_sglist); +#ifdef CONFIG_BLK_DEV_IDEDMA_SFF +/** + * ide_build_dmatable - build IDE DMA table + * + * ide_build_dmatable() prepares a dma request. We map the command + * to get the pci bus addresses of the buffers and then build up + * the PRD table that the IDE layer wants to be fed. The code + * knows about the 64K wrap bug in the CS5530. + * + * Returns the number of built PRD entries if all went okay, + * returns 0 otherwise. + * + * May also be invoked from trm290.c + */ + +int ide_build_dmatable (ide_drive_t *drive, struct request *rq) +{ + ide_hwif_t *hwif = HWIF(drive); + __le32 *table = (__le32 *)hwif->dmatable_cpu; + unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0; + unsigned int count = 0; + int i; + struct scatterlist *sg; + + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; + + sg = hwif->sg_table; + while (i) { + u32 cur_addr; + u32 cur_len; + + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); + + /* + * Fill in the dma table, without crossing any 64kB boundaries. + * Most hardware requires 16-bit alignment of all blocks, + * but the trm290 requires 32-bit alignment. + */ + + while (cur_len) { + if (count++ >= PRD_ENTRIES) { + printk(KERN_ERR "%s: DMA table too small\n", drive->name); + goto use_pio_instead; + } else { + u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); + + if (bcount > cur_len) + bcount = cur_len; + *table++ = cpu_to_le32(cur_addr); + xcount = bcount & 0xffff; + if (is_trm290) + xcount = ((xcount >> 2) - 1) << 16; + else if (xcount == 0x0000) { + /* + * Most chipsets correctly interpret a length of 0x0000 as 64KB, + * but at least one (e.g. CS5530) misinterprets it as zero (!). + * So here we break the 64KB entry into two 32KB entries instead. + */ + if (count++ >= PRD_ENTRIES) { + printk(KERN_ERR "%s: DMA table too small\n", drive->name); + goto use_pio_instead; + } + *table++ = cpu_to_le32(0x8000); + *table++ = cpu_to_le32(cur_addr + 0x8000); + xcount = 0x8000; + } + *table++ = cpu_to_le32(xcount); + cur_addr += bcount; + cur_len -= bcount; + } + } + + sg = sg_next(sg); + i--; + } + + if (count) { + if (!is_trm290) + *--table |= cpu_to_le32(0x80000000); + return count; + } + + printk(KERN_ERR "%s: empty DMA table?\n", drive->name); + +use_pio_instead: + ide_destroy_dmatable(drive); + + return 0; /* revert to PIO for this request */ +} + +EXPORT_SYMBOL_GPL(ide_build_dmatable); +#endif + /** * ide_destroy_dmatable - clean up DMA mapping * @drive: The drive to unmap @@ -151,30 +262,147 @@ EXPORT_SYMBOL_GPL(ide_build_sglist); * an oops as only one mapping can be live for each target at a given * time. */ - -void ide_destroy_dmatable(ide_drive_t *drive) + +void ide_destroy_dmatable (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents, hwif->sg_dma_direction); } + EXPORT_SYMBOL_GPL(ide_destroy_dmatable); +#ifdef CONFIG_BLK_DEV_IDEDMA_SFF +/** + * config_drive_for_dma - attempt to activate IDE DMA + * @drive: the drive to place in DMA mode + * + * If the drive supports at least mode 2 DMA or UDMA of any kind + * then attempt to place it into DMA mode. Drives that are known to + * support DMA but predate the DMA properties or that are known + * to have DMA handling bugs are also set up appropriately based + * on the good/bad drive lists. + */ + +static int config_drive_for_dma (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u16 *id = drive->id; + + if (drive->media != ide_disk) { + if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA) + return 0; + } + + /* + * Enable DMA on any drive that has + * UltraDMA (mode 0/1/2/3/4/5/6) enabled + */ + if ((id[ATA_ID_FIELD_VALID] & 4) && + ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f)) + return 1; + + /* + * Enable DMA on any drive that has mode2 DMA + * (multi or single) enabled + */ + if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */ + if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || + (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) + return 1; + + /* Consult the list of known "good" drives */ + if (ide_dma_good_drive(drive)) + return 1; + + return 0; +} + +/** + * dma_timer_expiry - handle a DMA timeout + * @drive: Drive that timed out + * + * An IDE DMA transfer timed out. In the event of an error we ask + * the driver to resolve the problem, if a DMA transfer is still + * in progress we continue to wait (arguably we need to add a + * secondary 'I don't care what the drive thinks' timeout here) + * Finally if we have an interrupt we let it complete the I/O. + * But only one time - we clear expiry and if it's still not + * completed after WAIT_CMD, we error and retry in PIO. + * This can occur if an interrupt is lost or due to hang or bugs. + */ + +static int dma_timer_expiry (ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n", + drive->name, dma_stat); + + if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ + return WAIT_CMD; + + HWGROUP(drive)->expiry = NULL; /* one free ride for now */ + + /* 1 dmaing, 2 error, 4 intr */ + if (dma_stat & 2) /* ERROR */ + return -1; + + if (dma_stat & 1) /* DMAing */ + return WAIT_CMD; + + if (dma_stat & 4) /* Got an Interrupt */ + return WAIT_CMD; + + return 0; /* Status is unknown -- reset the bus */ +} + +/** + * ide_dma_host_set - Enable/disable DMA on a host + * @drive: drive to control + * + * Enable/disable DMA on an IDE controller following generic + * bus-mastering IDE controller behaviour. + */ + +void ide_dma_host_set(ide_drive_t *drive, int on) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 unit = (drive->select.b.unit & 0x01); + u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + if (on) + dma_stat |= (1 << (5 + unit)); + else + dma_stat &= ~(1 << (5 + unit)); + + if (hwif->host_flags & IDE_HFLAG_MMIO) + writeb(dma_stat, + (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); + else + outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); +} + +EXPORT_SYMBOL_GPL(ide_dma_host_set); +#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ + /** * ide_dma_off_quietly - Generic DMA kill * @drive: drive to control * - * Turn off the current DMA on this IDE controller. + * Turn off the current DMA on this IDE controller. */ void ide_dma_off_quietly(ide_drive_t *drive) { - drive->dev_flags &= ~IDE_DFLAG_USING_DMA; + drive->using_dma = 0; ide_toggle_bounce(drive, 0); drive->hwif->dma_ops->dma_host_set(drive, 0); } + EXPORT_SYMBOL(ide_dma_off_quietly); /** @@ -190,6 +418,7 @@ void ide_dma_off(ide_drive_t *drive) printk(KERN_INFO "%s: DMA disabled\n", drive->name); ide_dma_off_quietly(drive); } + EXPORT_SYMBOL(ide_dma_off); /** @@ -201,13 +430,167 @@ EXPORT_SYMBOL(ide_dma_off); void ide_dma_on(ide_drive_t *drive) { - drive->dev_flags |= IDE_DFLAG_USING_DMA; + drive->using_dma = 1; ide_toggle_bounce(drive, 1); drive->hwif->dma_ops->dma_host_set(drive, 1); } -int __ide_dma_bad_drive(ide_drive_t *drive) +#ifdef CONFIG_BLK_DEV_IDEDMA_SFF +/** + * ide_dma_setup - begin a DMA phase + * @drive: target device + * + * Build an IDE DMA PRD (IDE speak for scatter gather table) + * and then set up the DMA transfer registers for a device + * that follows generic IDE PCI DMA behaviour. Controllers can + * override this function if they need to + * + * Returns 0 on success. If a PIO fallback is required then 1 + * is returned. + */ + +int ide_dma_setup(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct request *rq = HWGROUP(drive)->rq; + unsigned int reading; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + u8 dma_stat; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = 1 << 3; + + /* fall back to pio! */ + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); + return 1; + } + + /* PRD table */ + if (hwif->host_flags & IDE_HFLAG_MMIO) + writel(hwif->dmatable_dma, + (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); + else + outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); + + /* specify r/w */ + if (mmio) + writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + else + outb(reading, hwif->dma_base + ATA_DMA_CMD); + + /* read DMA status for INTR & ERROR flags */ + dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + /* clear INTR & ERROR flags */ + if (mmio) + writeb(dma_stat | 6, + (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); + else + outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + + drive->waiting_for_dma = 1; + return 0; +} + +EXPORT_SYMBOL_GPL(ide_dma_setup); + +void ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); +} +EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); + +void ide_dma_start(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 dma_cmd; + + /* Note that this is done *after* the cmd has + * been issued to the drive, as per the BM-IDE spec. + * The Promise Ultra33 doesn't work correctly when + * we do this part before issuing the drive cmd. + */ + if (hwif->host_flags & IDE_HFLAG_MMIO) { + dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + /* start DMA */ + writeb(dma_cmd | 1, + (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + } else { + dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); + } + + hwif->dma = 1; + wmb(); +} + +EXPORT_SYMBOL_GPL(ide_dma_start); + +/* returns 1 on error, 0 otherwise */ +int __ide_dma_end (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + u8 dma_stat = 0, dma_cmd = 0; + + drive->waiting_for_dma = 0; + + if (mmio) { + /* get DMA command mode */ + dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + /* stop DMA */ + writeb(dma_cmd & ~1, + (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + } else { + dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); + } + + /* get DMA status */ + dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + if (mmio) + /* clear the INTR & ERROR bits */ + writeb(dma_stat | 6, + (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); + else + outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ + hwif->dma = 0; + wmb(); + return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; +} + +EXPORT_SYMBOL(__ide_dma_end); + +/* returns 1 if dma irq issued, 0 otherwise */ +int ide_dma_test_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); + + /* return 1 if INTR asserted */ + if ((dma_stat & 4) == 4) + return 1; + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __func__); + return 0; +} +EXPORT_SYMBOL_GPL(ide_dma_test_irq); +#else +static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; } +#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ + +int __ide_dma_bad_drive (ide_drive_t *drive) { u16 *id = drive->id; @@ -219,6 +602,7 @@ int __ide_dma_bad_drive(ide_drive_t *drive) } return 0; } + EXPORT_SYMBOL(__ide_dma_bad_drive); static const u8 xfer_mode_bases[] = { @@ -234,7 +618,7 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) const struct ide_port_ops *port_ops = hwif->port_ops; unsigned int mask = 0; - switch (base) { + switch(base) { case XFER_UDMA_0: if ((id[ATA_ID_FIELD_VALID] & 4) == 0) break; @@ -335,6 +719,7 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode) return mode; } + EXPORT_SYMBOL_GPL(ide_find_dma_mode); static int ide_tune_dma(ide_drive_t *drive) @@ -342,8 +727,7 @@ static int ide_tune_dma(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 speed; - if (ata_id_has_dma(drive->id) == 0 || - (drive->dev_flags & IDE_DFLAG_NODMA)) + if (drive->nodma || ata_id_has_dma(drive->id) == 0) return 0; /* consult the list of known "bad" drives */ @@ -443,59 +827,66 @@ void ide_check_dma_crc(ide_drive_t *drive) ide_dma_on(drive); } -void ide_dma_lost_irq(ide_drive_t *drive) +#ifdef CONFIG_BLK_DEV_IDEDMA_SFF +void ide_dma_lost_irq (ide_drive_t *drive) { - printk(KERN_ERR "%s: DMA interrupt recovery\n", drive->name); + printk("%s: DMA interrupt recovery\n", drive->name); } -EXPORT_SYMBOL_GPL(ide_dma_lost_irq); -void ide_dma_timeout(ide_drive_t *drive) +EXPORT_SYMBOL(ide_dma_lost_irq); + +void ide_dma_timeout (ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; + ide_hwif_t *hwif = HWIF(drive); printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); if (hwif->dma_ops->dma_test_irq(drive)) return; - ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif)); - hwif->dma_ops->dma_end(drive); } -EXPORT_SYMBOL_GPL(ide_dma_timeout); + +EXPORT_SYMBOL(ide_dma_timeout); void ide_release_dma_engine(ide_hwif_t *hwif) { if (hwif->dmatable_cpu) { - int prd_size = hwif->prd_max_nents * hwif->prd_ent_size; + struct pci_dev *pdev = to_pci_dev(hwif->dev); - dma_free_coherent(hwif->dev, prd_size, - hwif->dmatable_cpu, hwif->dmatable_dma); + pci_free_consistent(pdev, PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_cpu, hwif->dmatable_dma); hwif->dmatable_cpu = NULL; } } -EXPORT_SYMBOL_GPL(ide_release_dma_engine); int ide_allocate_dma_engine(ide_hwif_t *hwif) { - int prd_size; + struct pci_dev *pdev = to_pci_dev(hwif->dev); - if (hwif->prd_max_nents == 0) - hwif->prd_max_nents = PRD_ENTRIES; - if (hwif->prd_ent_size == 0) - hwif->prd_ent_size = PRD_BYTES; + hwif->dmatable_cpu = pci_alloc_consistent(pdev, + PRD_ENTRIES * PRD_BYTES, + &hwif->dmatable_dma); - prd_size = hwif->prd_max_nents * hwif->prd_ent_size; + if (hwif->dmatable_cpu) + return 0; - hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev, prd_size, - &hwif->dmatable_dma, - GFP_ATOMIC); - if (hwif->dmatable_cpu == NULL) { - printk(KERN_ERR "%s: unable to allocate PRD table\n", + printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n", hwif->name); - return -ENOMEM; - } - return 0; + return 1; } EXPORT_SYMBOL_GPL(ide_allocate_dma_engine); + +const struct ide_dma_ops sff_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = __ide_dma_end, + .dma_test_irq = ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, + .dma_lost_irq = ide_dma_lost_irq, +}; +EXPORT_SYMBOL_GPL(sff_dma_ops); +#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index cf0aa25470ee..d36f155470a4 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -16,7 +16,6 @@ */ #define DRV_NAME "ide-floppy" -#define PFX DRV_NAME ": " #define IDEFLOPPY_VERSION "1.00" @@ -49,17 +48,17 @@ #include "ide-floppy.h" -/* module parameters */ -static unsigned long debug_mask; -module_param(debug_mask, ulong, 0644); - /* define to see debug info */ -#define IDEFLOPPY_DEBUG_LOG 0 +#define IDEFLOPPY_DEBUG_LOG 0 + +/* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */ +#define IDEFLOPPY_DEBUG(fmt, args...) #if IDEFLOPPY_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) +#define debug_log(fmt, args...) \ + printk(KERN_INFO "ide-floppy: " fmt, ## args) #else -#define ide_debug_log(lvl, fmt, args...) do {} while (0) +#define debug_log(fmt, args...) do {} while (0) #endif /* @@ -74,17 +73,18 @@ module_param(debug_mask, ulong, 0644); #define CAPACITY_CURRENT 0x02 #define CAPACITY_NO_CARTRIDGE 0x03 -/* - * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit - * was apparently being deasserted before the unit was ready to receive data. - */ -#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ +#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ /* Error code returned in rq->errors to the higher part of the driver. */ #define IDEFLOPPY_ERROR_GENERAL 101 static DEFINE_MUTEX(idefloppy_ref_mutex); +#define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref) + +#define ide_floppy_g(disk) \ + container_of((disk)->private_data, struct ide_floppy_obj, driver) + static void idefloppy_cleanup_obj(struct kref *); static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) @@ -92,7 +92,7 @@ static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) struct ide_floppy_obj *floppy = NULL; mutex_lock(&idefloppy_ref_mutex); - floppy = ide_drv_g(disk, ide_floppy_obj); + floppy = ide_floppy_g(disk); if (floppy) { if (ide_device_get(floppy->drive)) floppy = NULL; @@ -123,21 +123,13 @@ static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) struct request *rq = HWGROUP(drive)->rq; int error; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + debug_log("Reached %s\n", __func__); switch (uptodate) { - case 0: - error = IDEFLOPPY_ERROR_GENERAL; - break; - - case 1: - error = 0; - break; - - default: - error = uptodate; + case 0: error = IDEFLOPPY_ERROR_GENERAL; break; + case 1: error = 0; break; + default: error = uptodate; } - if (error) floppy->failed_pc = NULL; /* Why does this happen? */ @@ -164,13 +156,13 @@ static void idefloppy_update_buffers(ide_drive_t *drive, idefloppy_end_request(drive, 1, 0); } -static void ide_floppy_callback(ide_drive_t *drive, int dsc) +static void ide_floppy_callback(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - struct ide_atapi_pc *pc = drive->pc; + struct ide_atapi_pc *pc = floppy->pc; int uptodate = pc->error ? 0 : 1; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + debug_log("Reached %s\n", __func__); if (floppy->failed_pc == pc) floppy->failed_pc = NULL; @@ -179,7 +171,7 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc) (pc->rq && blk_pc_request(pc->rq))) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { - u8 *buf = pc->buf; + u8 *buf = floppy->pc->buf; if (!pc->error) { floppy->sense_key = buf[2] & 0x0F; @@ -189,20 +181,99 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc) (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; if (floppy->failed_pc) - ide_debug_log(IDE_DBG_PC, "pc = %x, ", - floppy->failed_pc->c[0]); + debug_log("pc = %x, ", floppy->failed_pc->c[0]); - ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," - "ascq = %x\n", floppy->sense_key, - floppy->asc, floppy->ascq); + debug_log("sense key = %x, asc = %x, ascq = %x\n", + floppy->sense_key, floppy->asc, floppy->ascq); } else - printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " - "Aborting request!\n"); + printk(KERN_ERR "Error in REQUEST SENSE itself - " + "Aborting request!\n"); } idefloppy_end_request(drive, uptodate, 0); } +void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *pc) +{ + ide_init_pc(pc); + pc->c[0] = GPCMD_REQUEST_SENSE; + pc->c[4] = 255; + pc->req_xfer = 18; +} + +/* + * Called when an error was detected during the last packet command. We queue a + * request sense packet command in the head of the request list. + */ +static void idefloppy_retry_pc(ide_drive_t *drive) +{ + struct ide_floppy_obj *floppy = drive->driver_data; + struct request *rq = &floppy->request_sense_rq; + struct ide_atapi_pc *pc = &floppy->request_sense_pc; + + (void)ide_read_error(drive); + ide_floppy_create_request_sense_cmd(pc); + ide_queue_pc_head(drive, floppy->disk, pc, rq); +} + +/* The usual interrupt handler called during a packet command. */ +static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) +{ + idefloppy_floppy_t *floppy = drive->driver_data; + + return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr, + WAIT_FLOPPY_CMD, NULL, idefloppy_update_buffers, + idefloppy_retry_pc, NULL, ide_io_buffers); +} + +/* + * What we have here is a classic case of a top half / bottom half interrupt + * service routine. In interrupt mode, the device sends an interrupt to signal + * that it is ready to receive a packet. However, we need to delay about 2-3 + * ticks before issuing the packet or we gets in trouble. + */ +static int idefloppy_transfer_pc(ide_drive_t *drive) +{ + idefloppy_floppy_t *floppy = drive->driver_data; + + /* Send the actual packet */ + drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12); + + /* Timeout for the packet command */ + return WAIT_FLOPPY_CMD; +} + +/* + * Called as an interrupt (or directly). When the device says it's ready for a + * packet, we schedule the packet transfer to occur about 2-3 ticks later in + * transfer_pc. + */ +static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive) +{ + idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_atapi_pc *pc = floppy->pc; + ide_expiry_t *expiry; + unsigned int timeout; + + /* + * The following delay solves a problem with ATAPI Zip 100 drives + * where the Busy flag was apparently being deasserted before the + * unit was ready to receive data. This was happening on a + * 1200 MHz Athlon system. 10/26/01 25msec is too short, + * 40 and 50msec work well. idefloppy_pc_intr will not be actually + * used until after the packet is moved in about 50 msec. + */ + if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { + timeout = floppy->ticks; + expiry = &idefloppy_transfer_pc; + } else { + timeout = WAIT_FLOPPY_CMD; + expiry = NULL; + } + + return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); +} + static void ide_floppy_report_error(idefloppy_floppy_t *floppy, struct ide_atapi_pc *pc) { @@ -212,7 +283,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, floppy->ascq == 0x00) return; - printk(KERN_ERR PFX "%s: I/O error, pc = %2x, key = %2x, " + printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, " "asc = %2x, ascq = %2x\n", floppy->drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); @@ -227,9 +298,8 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, if (floppy->failed_pc == NULL && pc->c[0] != GPCMD_REQUEST_SENSE) floppy->failed_pc = pc; - /* Set the current packet command */ - drive->pc = pc; + floppy->pc = pc; if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) @@ -238,15 +308,16 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, pc->error = IDEFLOPPY_ERROR_GENERAL; floppy->failed_pc = NULL; - drive->pc_callback(drive, 0); + drive->pc_callback(drive); return ide_stopped; } - ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries); + debug_log("Retry number - %d\n", pc->retries); pc->retries++; - return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL); + return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer, + WAIT_FLOPPY_CMD, NULL); } void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) @@ -276,23 +347,23 @@ void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) length += 32; break; default: - printk(KERN_ERR PFX "unsupported page code in %s\n", __func__); + printk(KERN_ERR "ide-floppy: unsupported page code " + "in create_mode_sense_cmd\n"); } put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); pc->req_xfer = length; } -static void idefloppy_create_rw_cmd(ide_drive_t *drive, +static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, struct ide_atapi_pc *pc, struct request *rq, unsigned long sector) { - idefloppy_floppy_t *floppy = drive->driver_data; int block = sector / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); - ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__, - block, blocks); + debug_log("create_rw10_cmd: block == %d, blocks == %d\n", + block, blocks); ide_init_pc(pc); pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; @@ -337,42 +408,41 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, struct ide_atapi_pc *pc; unsigned long block = (unsigned long)block_s; - ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " - "errors: %d\n", - __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", - rq->cmd[0], rq->cmd_type, rq->errors); + debug_log("%s: dev: %s, cmd: 0x%x, cmd_type: %x, errors: %d\n", + __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", + rq->cmd[0], rq->cmd_type, rq->errors); - ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, " - "current_nr_sectors: %d\n", - __func__, (long)rq->sector, rq->nr_sectors, - rq->current_nr_sectors); + debug_log("%s: sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n", + __func__, (long)rq->sector, rq->nr_sectors, + rq->current_nr_sectors); if (rq->errors >= ERROR_MAX) { if (floppy->failed_pc) ide_floppy_report_error(floppy, floppy->failed_pc); else - printk(KERN_ERR PFX "%s: I/O error\n", drive->name); - + printk(KERN_ERR "ide-floppy: %s: I/O error\n", + drive->name); idefloppy_end_request(drive, 0, 0); return ide_stopped; } if (blk_fs_request(rq)) { if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { - printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", - drive->name); + printk(KERN_ERR "%s: unsupported r/w request size\n", + drive->name); idefloppy_end_request(drive, 0, 0); return ide_stopped; } pc = &floppy->queued_pc; - idefloppy_create_rw_cmd(drive, pc, rq, block); + idefloppy_create_rw_cmd(floppy, pc, rq, block); } else if (blk_special_request(rq)) { pc = (struct ide_atapi_pc *) rq->buffer; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; idefloppy_blockpc_cmd(floppy, pc, rq); } else { - blk_dump_rq_flags(rq, PFX "unsupported command in queue"); + blk_dump_rq_flags(rq, + "ide-floppy: unsupported command in queue"); idefloppy_end_request(drive, 0, 0); return ide_stopped; } @@ -405,7 +475,8 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); if (ide_queue_pc_tail(drive, disk, &pc)) { - printk(KERN_ERR PFX "Can't get flexible disk page params\n"); + printk(KERN_ERR "ide-floppy: Can't get flexible disk page" + " parameters\n"); return 1; } @@ -428,7 +499,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) capacity = cyls * heads * sectors * sector_size; if (memcmp(page, &floppy->flexible_disk_page, 32)) - printk(KERN_INFO PFX "%s: %dkB, %d/%d/%d CHS, %d kBps, " + printk(KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, " "%d sector size, %d rpm\n", drive->name, capacity / 1024, cyls, heads, sectors, transfer_rate / 8, sector_size, rpm); @@ -440,7 +511,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) lba_capacity = floppy->blocks * floppy->block_size; if (capacity < lba_capacity) { - printk(KERN_NOTICE PFX "%s: The disk reports a capacity of %d " + printk(KERN_NOTICE "%s: The disk reports a capacity of %d " "bytes, but the drive only handles %d\n", drive->name, lba_capacity, capacity); floppy->blocks = floppy->block_size ? @@ -470,7 +541,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) ide_floppy_create_read_capacity_cmd(&pc); if (ide_queue_pc_tail(drive, disk, &pc)) { - printk(KERN_ERR PFX "Can't get floppy parameters\n"); + printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return 1; } header_len = pc.buf[3]; @@ -483,9 +554,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); - ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " - "%d sector size\n", - i, blocks * length / 1024, blocks, length); + debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n", + i, blocks * length / 1024, blocks, length); if (i) continue; @@ -505,24 +575,23 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */ if (memcmp(cap_desc, &floppy->cap_desc, 8)) - printk(KERN_INFO PFX "%s: %dkB, %d blocks, %d " - "sector size\n", - drive->name, blocks * length / 1024, - blocks, length); + printk(KERN_INFO "%s: %dkB, %d blocks, %d " + "sector size\n", drive->name, + blocks * length / 1024, blocks, length); memcpy(&floppy->cap_desc, cap_desc, 8); if (!length || length % 512) { - printk(KERN_NOTICE PFX "%s: %d bytes block size" - " not supported\n", drive->name, length); + printk(KERN_NOTICE "%s: %d bytes block size " + "not supported\n", drive->name, length); } else { floppy->blocks = blocks; floppy->block_size = length; floppy->bs_factor = length / 512; if (floppy->bs_factor != 1) - printk(KERN_NOTICE PFX "%s: Warning: " - "non 512 bytes block size not " - "fully supported\n", - drive->name); + printk(KERN_NOTICE "%s: warning: non " + "512 bytes block size not " + "fully supported\n", + drive->name); rc = 0; } break; @@ -531,16 +600,15 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) * This is a KERN_ERR so it appears on screen * for the user to see */ - printk(KERN_ERR PFX "%s: No disk in drive\n", - drive->name); + printk(KERN_ERR "%s: No disk in drive\n", drive->name); break; case CAPACITY_INVALID: - printk(KERN_ERR PFX "%s: Invalid capacity for disk " + printk(KERN_ERR "%s: Invalid capacity for disk " "in drive\n", drive->name); break; } - ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n", - pc.buf[desc_start + 4] & 0x03); + debug_log("Descriptor 0 Code: %d\n", + pc.buf[desc_start + 4] & 0x03); } /* Clik! disk does not support get_flexible_disk_page */ @@ -552,7 +620,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) return rc; } -sector_t ide_floppy_capacity(ide_drive_t *drive) +static sector_t idefloppy_capacity(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; unsigned long capacity = floppy->blocks * floppy->bs_factor; @@ -560,14 +628,46 @@ sector_t ide_floppy_capacity(ide_drive_t *drive) return capacity; } +#ifdef CONFIG_IDE_PROC_FS +ide_devset_rw_field(bios_cyl, bios_cyl); +ide_devset_rw_field(bios_head, bios_head); +ide_devset_rw_field(bios_sect, bios_sect); + +static int get_ticks(ide_drive_t *drive) +{ + idefloppy_floppy_t *floppy = drive->driver_data; + return floppy->ticks; +} + +static int set_ticks(ide_drive_t *drive, int arg) +{ + idefloppy_floppy_t *floppy = drive->driver_data; + floppy->ticks = arg; + return 0; +} + +IDE_DEVSET(ticks, DS_SYNC, get_ticks, set_ticks); + +static const struct ide_proc_devset idefloppy_settings[] = { + IDE_PROC_DEVSET(bios_cyl, 0, 1023), + IDE_PROC_DEVSET(bios_head, 0, 255), + IDE_PROC_DEVSET(bios_sect, 0, 63), + IDE_PROC_DEVSET(ticks, 0, 255), + { 0 }, +}; +#endif + static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) { u16 *id = drive->id; + u8 gcw[2]; + + *((u16 *)&gcw) = id[ATA_ID_CONFIG]; - drive->pc_callback = ide_floppy_callback; - drive->pc_update_buffers = idefloppy_update_buffers; - drive->pc_io_buffers = ide_io_buffers; + drive->pc_callback = ide_floppy_callback; + if (((gcw[0] & 0x60) >> 5) == 1) + drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; /* * We used to check revisions here. At this point however I'm giving up. * Just assume they are all broken, its easier. @@ -580,7 +680,7 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; /* This value will be visible in the /proc/ide/hdx/settings */ - drive->pc_delay = IDEFLOPPY_PC_DELAY; + floppy->ticks = IDEFLOPPY_TICKS_DELAY; blk_queue_max_sectors(drive->queue, 64); } @@ -614,7 +714,7 @@ static void ide_floppy_remove(ide_drive_t *drive) static void idefloppy_cleanup_obj(struct kref *kref) { - struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj); + struct ide_floppy_obj *floppy = to_ide_floppy(kref); ide_drive_t *drive = floppy->drive; struct gendisk *g = floppy->disk; @@ -624,6 +724,24 @@ static void idefloppy_cleanup_obj(struct kref *kref) kfree(floppy); } +#ifdef CONFIG_IDE_PROC_FS +static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + ide_drive_t*drive = (ide_drive_t *)data; + int len; + + len = sprintf(page, "%llu\n", (long long)idefloppy_capacity(drive)); + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); +} + +static ide_proc_entry_t idefloppy_proc[] = { + { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, + { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, + { NULL, 0, NULL, NULL } +}; +#endif /* CONFIG_IDE_PROC_FS */ + static int ide_floppy_probe(ide_drive_t *); static ide_driver_t idefloppy_driver = { @@ -635,12 +753,13 @@ static ide_driver_t idefloppy_driver = { .probe = ide_floppy_probe, .remove = ide_floppy_remove, .version = IDEFLOPPY_VERSION, + .media = ide_floppy, .do_request = idefloppy_do_request, .end_request = idefloppy_end_request, .error = __ide_error, #ifdef CONFIG_IDE_PROC_FS - .proc = ide_floppy_proc, - .settings = ide_floppy_settings, + .proc = idefloppy_proc, + .settings = idefloppy_settings, #endif }; @@ -651,14 +770,14 @@ static int idefloppy_open(struct inode *inode, struct file *filp) ide_drive_t *drive; int ret = 0; + debug_log("Reached %s\n", __func__); + floppy = ide_floppy_get(disk); if (!floppy) return -ENXIO; drive = floppy->drive; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - floppy->openers++; if (floppy->openers == 1) { @@ -703,10 +822,10 @@ static int idefloppy_open(struct inode *inode, struct file *filp) static int idefloppy_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); + struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + debug_log("Reached %s\n", __func__); if (floppy->openers == 1) { ide_set_media_lock(drive, disk, 0); @@ -722,8 +841,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp) static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) { - struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, - ide_floppy_obj); + struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); ide_drive_t *drive = floppy->drive; geo->heads = drive->bios_head; @@ -732,15 +850,64 @@ static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } +static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, + unsigned long arg, unsigned int cmd) +{ + idefloppy_floppy_t *floppy = drive->driver_data; + struct gendisk *disk = floppy->disk; + int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; + + if (floppy->openers > 1) + return -EBUSY; + + ide_set_media_lock(drive, disk, prevent); + + if (cmd == CDROMEJECT) + ide_do_start_stop(drive, disk, 2); + + return 0; +} + +static int idefloppy_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); + ide_drive_t *drive = floppy->drive; + struct ide_atapi_pc pc; + void __user *argp = (void __user *)arg; + int err; + + if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) + return ide_floppy_lockdoor(drive, &pc, arg, cmd); + + err = ide_floppy_format_ioctl(drive, file, cmd, argp); + if (err != -ENOTTY) + return err; + + /* + * skip SCSI_IOCTL_SEND_COMMAND (deprecated) + * and CDROM_SEND_PACKET (legacy) ioctls + */ + if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) + err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, + bdev->bd_disk, cmd, argp); + + if (err == -ENOTTY) + err = generic_ide_ioctl(drive, file, bdev, cmd, arg); + + return err; +} + static int idefloppy_media_changed(struct gendisk *disk) { - struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); + struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; int ret; /* do not scan partitions twice if this is a removable device */ - if (drive->dev_flags & IDE_DFLAG_ATTACH) { - drive->dev_flags &= ~IDE_DFLAG_ATTACH; + if (drive->attach) { + drive->attach = 0; return 0; } ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); @@ -750,8 +917,8 @@ static int idefloppy_media_changed(struct gendisk *disk) static int idefloppy_revalidate_disk(struct gendisk *disk) { - struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); - set_capacity(disk, ide_floppy_capacity(floppy->drive)); + struct ide_floppy_obj *floppy = ide_floppy_g(disk); + set_capacity(disk, idefloppy_capacity(floppy->drive)); return 0; } @@ -759,7 +926,7 @@ static struct block_device_operations idefloppy_ops = { .owner = THIS_MODULE, .open = idefloppy_open, .release = idefloppy_release, - .ioctl = ide_floppy_ioctl, + .ioctl = idefloppy_ioctl, .getgeo = idefloppy_getgeo, .media_changed = idefloppy_media_changed, .revalidate_disk = idefloppy_revalidate_disk @@ -777,14 +944,14 @@ static int ide_floppy_probe(ide_drive_t *drive) goto failed; if (!ide_check_atapi_device(drive, DRV_NAME)) { - printk(KERN_ERR PFX "%s: not supported by this version of " - DRV_NAME "\n", drive->name); + printk(KERN_ERR "ide-floppy: %s: not supported by this version" + " of ide-floppy\n", drive->name); goto failed; } floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); if (!floppy) { - printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n", - drive->name); + printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" + " structure\n", drive->name); goto failed; } @@ -804,16 +971,13 @@ static int ide_floppy_probe(ide_drive_t *drive) drive->driver_data = floppy; - drive->debug_mask = debug_mask; - idefloppy_setup(drive, floppy); - drive->dev_flags |= IDE_DFLAG_ATTACH; g->minors = 1 << PARTN_BITS; g->driverfs_dev = &drive->gendev; - if (drive->dev_flags & IDE_DFLAG_REMOVABLE) - g->flags = GENHD_FL_REMOVABLE; + g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; g->fops = &idefloppy_ops; + drive->attach = 1; add_disk(g); return 0; @@ -830,7 +994,7 @@ static void __exit idefloppy_exit(void) static int __init idefloppy_init(void) { - printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n"); + printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); return driver_register(&idefloppy_driver.gen_driver); } diff --git a/trunk/drivers/ide/ide-floppy.h b/trunk/drivers/ide/ide-floppy.h index 17cf865e583d..ecadc2bc322d 100644 --- a/trunk/drivers/ide/ide-floppy.h +++ b/trunk/drivers/ide/ide-floppy.h @@ -13,14 +13,20 @@ typedef struct ide_floppy_obj { struct kref kref; unsigned int openers; /* protected by BKL for now */ + /* Current packet command */ + struct ide_atapi_pc *pc; /* Last failed packet command */ struct ide_atapi_pc *failed_pc; /* used for blk_{fs,pc}_request() requests */ struct ide_atapi_pc queued_pc; + struct ide_atapi_pc request_sense_pc; + struct request request_sense_rq; + /* Last error information */ u8 sense_key, asc, ascq; - + /* delay this long before sending packet command */ + u8 ticks; int progress_indication; /* Device information */ @@ -48,15 +54,10 @@ typedef struct ide_floppy_obj { /* ide-floppy.c */ void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); -sector_t ide_floppy_capacity(ide_drive_t *); +void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *); /* ide-floppy_ioctl.c */ -int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); - -#ifdef CONFIG_IDE_PROC_FS -/* ide-floppy_proc.c */ -extern ide_proc_entry_t ide_floppy_proc[]; -extern const struct ide_proc_devset ide_floppy_settings[]; -#endif +int ide_floppy_format_ioctl(ide_drive_t *, struct file *, unsigned int, + void __user *); #endif /*__IDE_FLOPPY_H */ diff --git a/trunk/drivers/ide/ide-floppy_ioctl.c b/trunk/drivers/ide/ide-floppy_ioctl.c index a3a7a0809e2b..5ffc4512d14b 100644 --- a/trunk/drivers/ide/ide-floppy_ioctl.c +++ b/trunk/drivers/ide/ide-floppy_ioctl.c @@ -195,7 +195,7 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) int progress_indication = 0x10000; if (drive->atapi_flags & IDE_AFLAG_SRFP) { - ide_create_request_sense_cmd(drive, &pc); + ide_floppy_create_request_sense_cmd(&pc); if (ide_queue_pc_tail(drive, floppy->disk, &pc)) return -EIO; @@ -223,26 +223,8 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) return 0; } -static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned long arg, unsigned int cmd) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - struct gendisk *disk = floppy->disk; - int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; - - if (floppy->openers > 1) - return -EBUSY; - - ide_set_media_lock(drive, disk, prevent); - - if (cmd == CDROMEJECT) - ide_do_start_stop(drive, disk, 2); - - return 0; -} - -static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, - unsigned int cmd, void __user *argp) +int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, + unsigned int cmd, void __user *argp) { switch (cmd) { case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: @@ -259,35 +241,3 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, return -ENOTTY; } } - -int ide_floppy_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct block_device *bdev = inode->i_bdev; - struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, - ide_floppy_obj); - ide_drive_t *drive = floppy->drive; - struct ide_atapi_pc pc; - void __user *argp = (void __user *)arg; - int err; - - if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) - return ide_floppy_lockdoor(drive, &pc, arg, cmd); - - err = ide_floppy_format_ioctl(drive, file, cmd, argp); - if (err != -ENOTTY) - return err; - - /* - * skip SCSI_IOCTL_SEND_COMMAND (deprecated) - * and CDROM_SEND_PACKET (legacy) ioctls - */ - if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) - err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, - bdev->bd_disk, cmd, argp); - - if (err == -ENOTTY) - err = generic_ide_ioctl(drive, file, bdev, cmd, arg); - - return err; -} diff --git a/trunk/drivers/ide/ide-floppy_proc.c b/trunk/drivers/ide/ide-floppy_proc.c deleted file mode 100644 index 76f0c6c4eca3..000000000000 --- a/trunk/drivers/ide/ide-floppy_proc.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "ide-floppy.h" - -static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - ide_drive_t*drive = (ide_drive_t *)data; - int len; - - len = sprintf(page, "%llu\n", (long long)ide_floppy_capacity(drive)); - PROC_IDE_READ_RETURN(page, start, off, count, eof, len); -} - -ide_proc_entry_t ide_floppy_proc[] = { - { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, - { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, - { NULL, 0, NULL, NULL } -}; - -ide_devset_rw_field(bios_cyl, bios_cyl); -ide_devset_rw_field(bios_head, bios_head); -ide_devset_rw_field(bios_sect, bios_sect); -ide_devset_rw_field(ticks, pc_delay); - -const struct ide_proc_devset ide_floppy_settings[] = { - IDE_PROC_DEVSET(bios_cyl, 0, 1023), - IDE_PROC_DEVSET(bios_head, 0, 255), - IDE_PROC_DEVSET(bios_sect, 0, 63), - IDE_PROC_DEVSET(ticks, 0, 255), - { 0 }, -}; diff --git a/trunk/drivers/ide/ide-generic.c b/trunk/drivers/ide/ide-generic.c index 81a5282ce1eb..0a3cb0c33ae5 100644 --- a/trunk/drivers/ide/ide-generic.c +++ b/trunk/drivers/ide/ide-generic.c @@ -137,10 +137,15 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary) static int __init ide_generic_init(void) { - hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; + hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; + struct ide_host *host; unsigned long io_addr; - int i, rc = 0, primary = 0, secondary = 0; + int i, rc, primary = 0, secondary = 0; +#ifdef CONFIG_MIPS + if (!ide_probe_legacy()) + return -ENODEV; +#endif ide_generic_check_pci_legacy_iobases(&primary, &secondary); if (!probe_mask) { @@ -156,9 +161,13 @@ static int __init ide_generic_init(void) printk(KERN_INFO DRV_NAME ": enforcing probing of I/O ports " "upon user request\n"); + memset(hws, 0, sizeof(hw_regs_t *) * MAX_HWIFS); + for (i = 0; i < ARRAY_SIZE(legacy_bases); i++) { io_addr = legacy_bases[i]; + hws[i] = NULL; + if ((probe_mask & (1 << i)) && io_addr) { if (!request_region(io_addr, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " @@ -175,27 +184,45 @@ static int __init ide_generic_init(void) continue; } - memset(&hw, 0, sizeof(hw)); - ide_std_init_ports(&hw, io_addr, io_addr + 0x206); + memset(&hw[i], 0, sizeof(hw[i])); + ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206); #ifdef CONFIG_IA64 - hw.irq = isa_irq_to_vector(legacy_irqs[i]); + hw[i].irq = isa_irq_to_vector(legacy_irqs[i]); #else - hw.irq = legacy_irqs[i]; + hw[i].irq = legacy_irqs[i]; #endif - hw.chipset = ide_generic; + hw[i].chipset = ide_generic; - rc = ide_host_add(NULL, hws, NULL); - if (rc) { - release_region(io_addr + 0x206, 1); - release_region(io_addr, 8); - } + hws[i] = &hw[i]; } } + host = ide_host_alloc_all(NULL, hws); + if (host == NULL) { + rc = -ENOMEM; + goto err; + } + + rc = ide_host_register(host, NULL, hws); + if (rc) + goto err_free; + if (ide_generic_sysfs_init()) printk(KERN_ERR DRV_NAME ": failed to create ide_generic " "class\n"); + return 0; +err_free: + ide_host_free(host); +err: + for (i = 0; i < MAX_HWIFS; i++) { + if (hws[i] == NULL) + continue; + + io_addr = hws[i]->io_ports.data_addr; + release_region(io_addr + 0x206, 1); + release_region(io_addr, 8); + } return rc; } diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 77c6eaeacefa..1c51949833be 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -78,9 +78,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, * decide whether to reenable DMA -- 3 is a random magic for now, * if we DMA timeout more than 3 times, just stay in PIO */ - if ((drive->dev_flags & IDE_DFLAG_DMA_PIO_RETRY) && - drive->retry_pio <= 3) { - drive->dev_flags &= ~IDE_DFLAG_DMA_PIO_RETRY; + if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { + drive->state = 0; ide_dma_on(drive); } @@ -132,6 +131,21 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) } EXPORT_SYMBOL(ide_end_request); +/* + * Power Management state machine. This one is rather trivial for now, + * we should probably add more, like switching back to PIO on suspend + * to help some BIOSes, re-do the door locking on resume, etc... + */ + +enum { + ide_pm_flush_cache = ide_pm_state_start_suspend, + idedisk_pm_standby, + + idedisk_pm_restore_pio = ide_pm_state_start_resume, + idedisk_pm_idle, + ide_pm_restore_dma, +}; + static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) { struct request_pm_state *pm = rq->data; @@ -140,20 +154,20 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s return; switch (pm->pm_step) { - case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ + case ide_pm_flush_cache: /* Suspend step 1 (flush cache) complete */ if (pm->pm_state == PM_EVENT_FREEZE) - pm->pm_step = IDE_PM_COMPLETED; + pm->pm_step = ide_pm_state_completed; else - pm->pm_step = IDE_PM_STANDBY; + pm->pm_step = idedisk_pm_standby; break; - case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - pm->pm_step = IDE_PM_COMPLETED; + case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ + pm->pm_step = ide_pm_state_completed; break; - case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ - pm->pm_step = IDE_PM_IDLE; + case idedisk_pm_restore_pio: /* Resume step 1 complete */ + pm->pm_step = idedisk_pm_idle; break; - case IDE_PM_IDLE: /* Resume step 2 (idle)*/ - pm->pm_step = IDE_PM_RESTORE_DMA; + case idedisk_pm_idle: /* Resume step 2 (idle) complete */ + pm->pm_step = ide_pm_restore_dma; break; } } @@ -166,12 +180,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * memset(args, 0, sizeof(*args)); switch (pm->pm_step) { - case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ + case ide_pm_flush_cache: /* Suspend step 1 (flush cache) */ if (drive->media != ide_disk) break; /* Not supported? Switch to next step now. */ - if (ata_id_flush_enabled(drive->id) == 0 || - (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { + if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) { ide_complete_power_step(drive, rq, 0, 0); return ide_stopped; } @@ -180,23 +193,27 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * else args->tf.command = ATA_CMD_FLUSH; goto out_do_tf; - case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ + + case idedisk_pm_standby: /* Suspend step 2 (standby) */ args->tf.command = ATA_CMD_STANDBYNOW1; goto out_do_tf; - case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ + + case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ ide_set_max_pio(drive); /* - * skip IDE_PM_IDLE for ATAPI devices + * skip idedisk_pm_idle for ATAPI devices */ if (drive->media != ide_disk) - pm->pm_step = IDE_PM_RESTORE_DMA; + pm->pm_step = ide_pm_restore_dma; else ide_complete_power_step(drive, rq, 0, 0); return ide_stopped; - case IDE_PM_IDLE: /* Resume step 2 (idle) */ + + case idedisk_pm_idle: /* Resume step 2 (idle) */ args->tf.command = ATA_CMD_IDLEIMMEDIATE; goto out_do_tf; - case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ + + case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ /* * Right now, all we do is call ide_set_dma(drive), * we could be smarter and check for current xfer_speed @@ -205,13 +222,12 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * if (drive->hwif->dma_ops == NULL) break; /* - * TODO: respect IDE_DFLAG_USING_DMA + * TODO: respect ->using_dma setting */ ide_set_dma(drive); break; } - - pm->pm_step = IDE_PM_COMPLETED; + pm->pm_step = ide_pm_state_completed; return ide_stopped; out_do_tf: @@ -271,7 +287,7 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) if (blk_pm_suspend_request(rq)) { blk_stop_queue(drive->queue); } else { - drive->dev_flags &= ~IDE_DFLAG_BLOCKED; + drive->blocked = 0; blk_start_queue(drive->queue); } HWGROUP(drive)->rq = NULL; @@ -327,7 +343,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) drive->name, rq->pm->pm_step, stat, err); #endif ide_complete_power_step(drive, rq, stat, err); - if (pm->pm_step == IDE_PM_COMPLETED) + if (pm->pm_step == ide_pm_state_completed) ide_complete_pm_request(drive, rq); return; } @@ -358,14 +374,13 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 { ide_hwif_t *hwif = drive->hwif; - if ((stat & ATA_BUSY) || - ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { + if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { /* other bits are useless when BUSY */ rq->errors |= ERROR_RESET; } else if (stat & ATA_ERR) { /* err has different meaning on cdrom and tape */ if (err == ATA_ABORTED) { - if ((drive->dev_flags & IDE_DFLAG_LBA) && + if (drive->select.b.lba && /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) return ide_stopped; @@ -413,8 +428,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u { ide_hwif_t *hwif = drive->hwif; - if ((stat & ATA_BUSY) || - ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { + if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { /* other bits are useless when BUSY */ rq->errors |= ERROR_RESET; } else { @@ -495,7 +509,7 @@ static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) tf->lbal = drive->sect; tf->lbam = drive->cyl; tf->lbah = drive->cyl >> 8; - tf->device = (drive->head - 1) | drive->select; + tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA; tf->command = ATA_CMD_INIT_DEV_PARAMS; } @@ -543,6 +557,30 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) return ide_started; } +/* + * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away + */ +static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) +{ + switch (req_pio) { + case 202: + case 201: + case 200: + case 102: + case 101: + case 100: + return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; + case 9: + case 8: + return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; + case 7: + case 6: + return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; + default: + return 0; + } +} + /** * do_special - issue some special commands * @drive: drive the command is for @@ -560,12 +598,45 @@ static ide_startstop_t do_special (ide_drive_t *drive) #ifdef DEBUG printk("%s: do_special: 0x%02x\n", drive->name, s->all); #endif - if (drive->media == ide_disk) - return ide_disk_special(drive); + if (s->b.set_tune) { + ide_hwif_t *hwif = drive->hwif; + const struct ide_port_ops *port_ops = hwif->port_ops; + u8 req_pio = drive->tune_req; - s->all = 0; - drive->mult_req = 0; - return ide_stopped; + s->b.set_tune = 0; + + if (set_pio_mode_abuse(drive->hwif, req_pio)) { + /* + * take ide_lock for drive->[no_]unmask/[no_]io_32bit + */ + if (req_pio == 8 || req_pio == 9) { + unsigned long flags; + + spin_lock_irqsave(&ide_lock, flags); + port_ops->set_pio_mode(drive, req_pio); + spin_unlock_irqrestore(&ide_lock, flags); + } else + port_ops->set_pio_mode(drive, req_pio); + } else { + int keep_dma = drive->using_dma; + + ide_set_pio(drive, req_pio); + + if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { + if (keep_dma) + ide_dma_on(drive); + } + } + + return ide_stopped; + } else { + if (drive->media == ide_disk) + return ide_disk_special(drive); + + s->all = 0; + drive->mult_req = 0; + return ide_stopped; + } } void ide_map_sg(ide_drive_t *drive, struct request *rq) @@ -655,7 +726,10 @@ int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting, if (!(setting->flags & DS_SYNC)) return setting->set(drive, arg); - rq = blk_get_request(q, READ, __GFP_WAIT); + rq = blk_get_request(q, READ, GFP_KERNEL); + if (!rq) + return -ENOMEM; + rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_len = 5; rq->cmd[0] = REQ_DEVSET_EXEC; @@ -672,32 +746,7 @@ EXPORT_SYMBOL_GPL(ide_devset_execute); static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) { - u8 cmd = rq->cmd[0]; - - if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) { - ide_task_t task; - struct ide_taskfile *tf = &task.tf; - - memset(&task, 0, sizeof(task)); - if (cmd == REQ_PARK_HEADS) { - drive->sleep = *(unsigned long *)rq->special; - drive->dev_flags |= IDE_DFLAG_SLEEPING; - tf->command = ATA_CMD_IDLEIMMEDIATE; - tf->feature = 0x44; - tf->lbal = 0x4c; - tf->lbam = 0x4e; - tf->lbah = 0x55; - task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; - } else /* cmd == REQ_UNPARK_HEADS */ - tf->command = ATA_CMD_CHK_POWER; - - task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - task.rq = rq; - drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA; - return do_rw_taskfile(drive, &task); - } - - switch (cmd) { + switch (rq->cmd[0]) { case REQ_DEVSET_EXEC: { int err, (*setfunc)(ide_drive_t *, int) = rq->special; @@ -724,11 +773,11 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) struct request_pm_state *pm = rq->data; if (blk_pm_suspend_request(rq) && - pm->pm_step == IDE_PM_START_SUSPEND) + pm->pm_step == ide_pm_state_start_suspend) /* Mark drive blocked when starting the suspend sequence. */ - drive->dev_flags |= IDE_DFLAG_BLOCKED; + drive->blocked = 1; else if (blk_pm_resume_request(rq) && - pm->pm_step == IDE_PM_START_RESUME) { + pm->pm_step == ide_pm_state_start_resume) { /* * The first thing we do on wakeup is to wait for BSY bit to * go away (with a looong timeout) as a drive on this hwif may @@ -808,7 +857,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) #endif startstop = ide_start_power_step(drive, rq); if (startstop == ide_stopped && - pm->pm_step == IDE_PM_COMPLETED) + pm->pm_step == ide_pm_state_completed) ide_complete_pm_request(drive, rq); return startstop; } else if (!rq->rq_disk && blk_special_request(rq)) @@ -846,7 +895,7 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) if (timeout > WAIT_WORSTCASE) timeout = WAIT_WORSTCASE; drive->sleep = timeout + jiffies; - drive->dev_flags |= IDE_DFLAG_SLEEPING; + drive->sleeping = 1; } EXPORT_SYMBOL(ide_stall_queue); @@ -886,23 +935,18 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) } do { - u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING); - u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING)); - - if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) && - !elv_queue_empty(drive->queue)) { - if (best == NULL || - (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) || - (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) { + if ((!drive->sleeping || time_after_eq(jiffies, drive->sleep)) + && !elv_queue_empty(drive->queue)) { + if (!best + || (drive->sleeping && (!best->sleeping || time_before(drive->sleep, best->sleep))) + || (!best->sleeping && time_before(WAKEUP(drive), WAKEUP(best)))) + { if (!blk_queue_plugged(drive->queue)) best = drive; } } } while ((drive = drive->next) != hwgroup->drive); - - if (best && (best->dev_flags & IDE_DFLAG_NICE1) && - (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 && - best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { + if (best && best->nice1 && !best->sleeping && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { long t = (signed long)(WAKEUP(best) - jiffies); if (t >= WAIT_MIN_SLEEP) { /* @@ -911,7 +955,7 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) */ drive = best->next; do { - if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0 + if (!drive->sleeping && time_before(jiffies - best->service_time, WAKEUP(drive)) && time_before(WAKEUP(drive), jiffies + t)) { @@ -982,9 +1026,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) hwgroup->rq = NULL; drive = hwgroup->drive; do { - if ((drive->dev_flags & IDE_DFLAG_SLEEPING) && - (sleeping == 0 || - time_before(drive->sleep, sleep))) { + if (drive->sleeping && (!sleeping || time_before(drive->sleep, sleep))) { sleeping = 1; sleep = drive->sleep; } @@ -1033,7 +1075,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) } hwgroup->hwif = hwif; hwgroup->drive = drive; - drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); + drive->sleeping = 0; drive->service_start = jiffies; if (blk_queue_plugged(drive->queue)) { @@ -1067,9 +1109,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) * We count how many times we loop here to make sure we service * all drives in the hwgroup without looping for ever */ - if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && - blk_pm_request(rq) == 0 && - (rq->cmd_flags & REQ_PREEMPT) == 0) { + if (drive->blocked && !blk_pm_request(rq) && !(rq->cmd_flags & REQ_PREEMPT)) { drive = drive->next ? drive->next : hwgroup->drive; if (loops++ < 4 && !blk_queue_plugged(drive->queue)) goto again; @@ -1142,8 +1182,8 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) * a timeout -- we'll reenable after we finish this next request * (or rather the first chunk of it) in pio. */ - drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY; drive->retry_pio++; + drive->state = DMA_PIO_RETRY; ide_dma_off_quietly(drive); /* @@ -1440,16 +1480,23 @@ irqreturn_t ide_intr (int irq, void *dev_id) del_timer(&hwgroup->timer); spin_unlock(&ide_lock); - if (hwif->port_ops && hwif->port_ops->clear_irq) - hwif->port_ops->clear_irq(drive); + /* Some controllers might set DMA INTR no matter DMA or PIO; + * bmdma status might need to be cleared even for + * PIO interrupts to prevent spurious/lost irq. + */ + if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma)) + /* ide_dma_end() needs bmdma status for error checking. + * So, skip clearing bmdma status here and leave it + * to ide_dma_end() if this is dma interrupt. + */ + hwif->ide_dma_clear_irq(drive); - if (drive->dev_flags & IDE_DFLAG_UNMASK) + if (drive->unmask) local_irq_enable_in_hardirq(); - /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); - spin_lock_irq(&ide_lock); + /* * Note that handler() may have set things up for another * interrupt to occur soon, but it cannot happen until diff --git a/trunk/drivers/ide/ide-ioctls.c b/trunk/drivers/ide/ide-ioctls.c index a90945f49792..cf01564901af 100644 --- a/trunk/drivers/ide/ide-ioctls.c +++ b/trunk/drivers/ide/ide-ioctls.c @@ -62,7 +62,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, int size = (cmd == HDIO_GET_IDENTITY) ? (ATA_ID_WORDS * 2) : 142; int rc = 0; - if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { + if (drive->id_read == 0) { rc = -ENOMSG; goto out; } @@ -86,10 +86,8 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, static int ide_get_nice_ioctl(ide_drive_t *drive, unsigned long arg) { - return put_user((!!(drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) - << IDE_NICE_DSC_OVERLAP) | - (!!(drive->dev_flags & IDE_DFLAG_NICE1) - << IDE_NICE_1), (long __user *)arg); + return put_user((drive->dsc_overlap << IDE_NICE_DSC_OVERLAP) | + (drive->nice1 << IDE_NICE_1), (long __user *)arg); } static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) @@ -99,18 +97,11 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && (drive->media == ide_disk || drive->media == ide_floppy || - (drive->dev_flags & IDE_DFLAG_SCSI))) + drive->scsi)) return -EPERM; - if ((arg >> IDE_NICE_DSC_OVERLAP) & 1) - drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; - else - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; - - if ((arg >> IDE_NICE_1) & 1) - drive->dev_flags |= IDE_DFLAG_NICE1; - else - drive->dev_flags &= ~IDE_DFLAG_NICE1; + drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; + drive->nice1 = (arg >> IDE_NICE_1) & 1; return 0; } diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index b762deb2dacb..0a2fd3b37ac4 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -181,7 +181,7 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) tf_outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - tf_outb((tf->device & HIHI) | drive->select, + tf_outb((tf->device & HIHI) | drive->select.all, io_ports->device_addr); } EXPORT_SYMBOL_GPL(ide_tf_load); @@ -647,7 +647,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) return 1; no_80w: - if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) + if (drive->udma33_warned == 1) return 0; printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " @@ -655,7 +655,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) drive->name, hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); - drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED; + drive->udma33_warned = 1; return 0; } @@ -711,7 +711,7 @@ int ide_driveid_update(ide_drive_t *drive) kfree(id); - if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) + if (drive->using_dma && ide_id_dma_bug(drive)) ide_dma_off(drive); return 1; @@ -790,7 +790,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) skip: #ifdef CONFIG_BLK_DEV_IDEDMA - if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA)) + if (speed >= XFER_SW_DMA_0 && drive->using_dma) hwif->dma_ops->dma_host_set(drive, 1); else if (hwif->dma_ops) /* check if host supports DMA */ ide_dma_off_quietly(drive); @@ -940,25 +940,6 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) return ide_stopped; } -static void ide_reset_report_error(ide_hwif_t *hwif, u8 err) -{ - static const char *err_master_vals[] = - { NULL, "passed", "formatter device error", - "sector buffer error", "ECC circuitry error", - "controlling MPU error" }; - - u8 err_master = err & 0x7f; - - printk(KERN_ERR "%s: reset: master: ", hwif->name); - if (err_master && err_master < 6) - printk(KERN_CONT "%s", err_master_vals[err_master]); - else - printk(KERN_CONT "error (0x%02x?)", err); - if (err & 0x80) - printk(KERN_CONT "; slave: failed"); - printk(KERN_CONT "\n"); -} - /* * reset_pollfunc() gets invoked to poll the interface for completion every 50ms * during an ide reset operation. If the drives have not yet responded, @@ -994,14 +975,31 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) drive->failures++; err = -EIO; } else { + printk("%s: reset: ", hwif->name); tmp = ide_read_error(drive); if (tmp == 1) { - printk(KERN_INFO "%s: reset: success\n", hwif->name); + printk("success\n"); drive->failures = 0; } else { - ide_reset_report_error(hwif, tmp); drive->failures++; + printk("master: "); + switch (tmp & 0x7f) { + case 1: printk("passed"); + break; + case 2: printk("formatter device error"); + break; + case 3: printk("sector buffer error"); + break; + case 4: printk("ECC circuitry error"); + break; + case 5: printk("controlling MPU error"); + break; + default:printk("error (0x%02x?)", tmp); + } + if (tmp & 0x80) + printk("; slave: failed"); + printk("\n"); err = -EIO; } } @@ -1018,14 +1016,9 @@ static void ide_disk_pre_reset(ide_drive_t *drive) drive->special.all = 0; drive->special.b.set_geometry = legacy; drive->special.b.recalibrate = legacy; - drive->mult_count = 0; - drive->dev_flags &= ~IDE_DFLAG_PARKED; - - if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && - (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) + if (!drive->keep_settings && !drive->using_dma) drive->mult_req = 0; - if (drive->mult_req != drive->mult_count) drive->special.b.set_multmode = 1; } @@ -1037,18 +1030,18 @@ static void pre_reset(ide_drive_t *drive) if (drive->media == ide_disk) ide_disk_pre_reset(drive); else - drive->dev_flags |= IDE_DFLAG_POST_RESET; + drive->post_reset = 1; - if (drive->dev_flags & IDE_DFLAG_USING_DMA) { + if (drive->using_dma) { if (drive->crc_count) ide_check_dma_crc(drive); else ide_dma_off(drive); } - if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) { - if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) { - drive->dev_flags &= ~IDE_DFLAG_UNMASK; + if (!drive->keep_settings) { + if (!drive->using_dma) { + drive->unmask = 0; drive->io_32bit = 0; } return; @@ -1080,13 +1073,12 @@ static void pre_reset(ide_drive_t *drive) static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) { unsigned int unit; - unsigned long flags, timeout; + unsigned long flags; ide_hwif_t *hwif; ide_hwgroup_t *hwgroup; struct ide_io_ports *io_ports; const struct ide_tp_ops *tp_ops; const struct ide_port_ops *port_ops; - DEFINE_WAIT(wait); spin_lock_irqsave(&ide_lock, flags); hwif = HWIF(drive); @@ -1113,31 +1105,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) return ide_started; } - /* We must not disturb devices in the IDE_DFLAG_PARKED state. */ - do { - unsigned long now; - - prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); - timeout = jiffies; - for (unit = 0; unit < MAX_DRIVES; unit++) { - ide_drive_t *tdrive = &hwif->drives[unit]; - - if (tdrive->dev_flags & IDE_DFLAG_PRESENT && - tdrive->dev_flags & IDE_DFLAG_PARKED && - time_after(tdrive->sleep, timeout)) - timeout = tdrive->sleep; - } - - now = jiffies; - if (time_before_eq(timeout, now)) - break; - - spin_unlock_irqrestore(&ide_lock, flags); - timeout = schedule_timeout_uninterruptible(timeout - now); - spin_lock_irqsave(&ide_lock, flags); - } while (timeout); - finish_wait(&ide_park_wq, &wait); - /* * First, reset any device state data we were maintaining * for any of the drives on this interface. diff --git a/trunk/drivers/ide/ide-lib.c b/trunk/drivers/ide/ide-lib.c index 9fc4cfb2a272..ed426dd0fdd8 100644 --- a/trunk/drivers/ide/ide-lib.c +++ b/trunk/drivers/ide/ide-lib.c @@ -317,7 +317,7 @@ static void ide_dump_sector(ide_drive_t *drive) { ide_task_t task; struct ide_taskfile *tf = &task.tf; - u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); + int lba48 = (drive->addressing == 1) ? 1 : 0; memset(&task, 0, sizeof(task)); if (lba48) diff --git a/trunk/drivers/ide/ide-park.c b/trunk/drivers/ide/ide-park.c deleted file mode 100644 index 03b00e57e93f..000000000000 --- a/trunk/drivers/ide/ide-park.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include -#include - -DECLARE_WAIT_QUEUE_HEAD(ide_park_wq); - -static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) -{ - struct request_queue *q = drive->queue; - struct request *rq; - int rc; - - timeout += jiffies; - spin_lock_irq(&ide_lock); - if (drive->dev_flags & IDE_DFLAG_PARKED) { - ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; - int reset_timer; - - reset_timer = time_before(timeout, drive->sleep); - drive->sleep = timeout; - wake_up_all(&ide_park_wq); - if (reset_timer && hwgroup->sleeping && - del_timer(&hwgroup->timer)) { - hwgroup->sleeping = 0; - hwgroup->busy = 0; - blk_start_queueing(q); - } - spin_unlock_irq(&ide_lock); - return; - } - spin_unlock_irq(&ide_lock); - - rq = blk_get_request(q, READ, __GFP_WAIT); - rq->cmd[0] = REQ_PARK_HEADS; - rq->cmd_len = 1; - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->special = &timeout; - rc = blk_execute_rq(q, NULL, rq, 1); - blk_put_request(rq); - if (rc) - goto out; - - /* - * Make sure that *some* command is sent to the drive after the - * timeout has expired, so power management will be reenabled. - */ - rq = blk_get_request(q, READ, GFP_NOWAIT); - if (unlikely(!rq)) - goto out; - - rq->cmd[0] = REQ_UNPARK_HEADS; - rq->cmd_len = 1; - rq->cmd_type = REQ_TYPE_SPECIAL; - elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1); - -out: - return; -} - -ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - unsigned long now; - unsigned int msecs; - - if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) - return -EOPNOTSUPP; - - spin_lock_irq(&ide_lock); - now = jiffies; - if (drive->dev_flags & IDE_DFLAG_PARKED && - time_after(drive->sleep, now)) - msecs = jiffies_to_msecs(drive->sleep - now); - else - msecs = 0; - spin_unlock_irq(&ide_lock); - - return snprintf(buf, 20, "%u\n", msecs); -} - -ssize_t ide_park_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t len) -{ -#define MAX_PARK_TIMEOUT 30000 - ide_drive_t *drive = to_ide_device(dev); - long int input; - int rc; - - rc = strict_strtol(buf, 10, &input); - if (rc || input < -2) - return -EINVAL; - if (input > MAX_PARK_TIMEOUT) { - input = MAX_PARK_TIMEOUT; - rc = -EOVERFLOW; - } - - mutex_lock(&ide_setting_mtx); - if (input >= 0) { - if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) - rc = -EOPNOTSUPP; - else if (input || drive->dev_flags & IDE_DFLAG_PARKED) - issue_park_cmd(drive, msecs_to_jiffies(input)); - } else { - if (drive->media == ide_disk) - switch (input) { - case -1: - drive->dev_flags &= ~IDE_DFLAG_NO_UNLOAD; - break; - case -2: - drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; - break; - } - else - rc = -EOPNOTSUPP; - } - mutex_unlock(&ide_setting_mtx); - - return rc ? rc : len; -} diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 19f8c7770a25..06575a12b635 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -121,8 +121,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) /* read 512 bytes of id info */ hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); - drive->dev_flags |= IDE_DFLAG_ID_READ; - + drive->id_read = 1; local_irq_enable(); #ifdef DEBUG printk(KERN_INFO "%s: dumping identify data\n", drive->name); @@ -154,8 +153,8 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) printk(KERN_INFO "%s: %s, ", drive->name, m); - drive->dev_flags |= IDE_DFLAG_PRESENT; - drive->dev_flags &= ~IDE_DFLAG_DEAD; + drive->present = 1; + drive->dead = 0; /* * Check for an ATAPI device @@ -173,14 +172,14 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) printk(KERN_CONT "cdrom or floppy?, assuming "); if (drive->media != ide_cdrom) { printk(KERN_CONT "FLOPPY"); - drive->dev_flags |= IDE_DFLAG_REMOVABLE; + drive->removable = 1; break; } } /* Early cdrom models used zero */ type = ide_cdrom; case ide_cdrom: - drive->dev_flags |= IDE_DFLAG_REMOVABLE; + drive->removable = 1; #ifdef CONFIG_PPC /* kludge for Apple PowerBook internal zip */ if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { @@ -196,7 +195,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) break; case ide_optical: printk(KERN_CONT "OPTICAL"); - drive->dev_flags |= IDE_DFLAG_REMOVABLE; + drive->removable = 1; break; default: printk(KERN_CONT "UNKNOWN (type %d)", type); @@ -206,10 +205,6 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) drive->media = type; /* an ATAPI device ignores DRDY */ drive->ready_stat = 0; - if (ata_id_cdb_intr(id)) - drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; - /* we don't do head unloading on ATAPI devices */ - drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; return; } @@ -221,20 +216,17 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) /* CF devices are *not* removable in Linux definition of the term */ if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) - drive->dev_flags |= IDE_DFLAG_REMOVABLE; + drive->removable = 1; drive->media = ide_disk; - if (!ata_id_has_unload(drive->id)) - drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; - printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA"); return; err_misc: kfree(id); - drive->dev_flags &= ~IDE_DFLAG_PRESENT; + drive->present = 0; return; } @@ -434,15 +426,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ide_hwif_t *hwif = HWIF(drive); const struct ide_tp_ops *tp_ops = hwif->tp_ops; int rc; - u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; - - /* avoid waiting for inappropriate probes */ - if (present && drive->media != ide_disk && cmd == ATA_CMD_ID_ATA) - return 4; + u8 stat; + if (drive->present) { + /* avoid waiting for inappropriate probes */ + if (drive->media != ide_disk && cmd == ATA_CMD_ID_ATA) + return 4; + } #ifdef DEBUG printk(KERN_INFO "probing for %s: present=%d, media=%d, probetype=%s\n", - drive->name, present, drive->media, + drive->name, drive->present, drive->media, (cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI"); #endif @@ -453,8 +446,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd) SELECT_DRIVE(drive); msleep(50); - if (ide_read_device(drive) != drive->select && present == 0) { - if (drive->dn & 1) { + if (ide_read_device(drive) != drive->select.all && !drive->present) { + if (drive->select.b.unit != 0) { /* exit with drive0 selected */ SELECT_DRIVE(&hwif->drives[0]); /* allow ATA_BUSY to assert & clear */ @@ -467,7 +460,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) stat = tp_ops->read_status(hwif); if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || - present || cmd == ATA_CMD_ID_ATAPI) { + drive->present || cmd == ATA_CMD_ID_ATAPI) { /* send cmd and wait */ if ((rc = try_to_identify(drive, cmd))) { /* failed: try again */ @@ -500,7 +493,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) /* not present or maybe ATAPI */ rc = 3; } - if (drive->dn & 1) { + if (drive->select.b.unit != 0) { /* exit with drive0 selected */ SELECT_DRIVE(&hwif->drives[0]); msleep(50); @@ -549,8 +542,8 @@ static void enable_nest (ide_drive_t *drive) * and presents things to the user as needed. * * Returns: 0 no device was found - * 1 device was found - * (note: IDE_DFLAG_PRESENT might still be not set) + * 1 device was found (note: drive->present might + * still be 0) */ static inline u8 probe_for_drive (ide_drive_t *drive) @@ -566,10 +559,10 @@ static inline u8 probe_for_drive (ide_drive_t *drive) * Also note that 0 everywhere means "can't do X" */ - drive->dev_flags &= ~IDE_DFLAG_ID_READ; - drive->id = kzalloc(SECTOR_SIZE, GFP_KERNEL); - if (drive->id == NULL) { + drive->id_read = 0; + if(drive->id == NULL) + { printk(KERN_ERR "ide: out of memory for id data.\n"); return 0; } @@ -578,14 +571,14 @@ static inline u8 probe_for_drive (ide_drive_t *drive) strcpy(m, "UNKNOWN"); /* skip probing? */ - if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) { + if (!drive->noprobe) { retry: /* if !(success||timed-out) */ if (do_probe(drive, ATA_CMD_ID_ATA) >= 2) /* look for ATAPI device */ (void)do_probe(drive, ATA_CMD_ID_ATAPI); - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (!drive->present) /* drive not found */ return 0; @@ -595,7 +588,7 @@ static inline u8 probe_for_drive (ide_drive_t *drive) } /* identification failed? */ - if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { + if (!drive->id_read) { if (drive->media == ide_disk) { printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d\n", drive->name, drive->cyl, @@ -605,17 +598,15 @@ static inline u8 probe_for_drive (ide_drive_t *drive) } else { /* nuke it */ printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name); - drive->dev_flags &= ~IDE_DFLAG_PRESENT; + drive->present = 0; } } /* drive was found */ } - - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if(!drive->present) return 0; - /* The drive wasn't being helpful. Add generic info only */ - if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { + if (drive->id_read == 0) { generic_id(drive); return 1; } @@ -625,7 +616,7 @@ static inline u8 probe_for_drive (ide_drive_t *drive) ide_disk_init_mult_count(drive); } - return !!(drive->dev_flags & IDE_DFLAG_PRESENT); + return drive->present; } static void hwif_release_dev(struct device *dev) @@ -657,8 +648,8 @@ static int ide_register_port(ide_hwif_t *hwif) goto out; } - hwif->portdev = device_create(ide_port_class, &hwif->gendev, - MKDEV(0, 0), hwif, hwif->name); + hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev, + MKDEV(0, 0), hwif, hwif->name); if (IS_ERR(hwif->portdev)) { ret = PTR_ERR(hwif->portdev); device_unregister(&hwif->gendev); @@ -716,8 +707,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) ide_drive_t *drive = &hwif->drives[unit]; /* Ignore disks that we will not probe for later. */ - if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 || - (drive->dev_flags & IDE_DFLAG_PRESENT)) { + if (!drive->noprobe || drive->present) { SELECT_DRIVE(drive); hwif->tp_ops->set_irq(hwif, 1); mdelay(2); @@ -749,7 +739,7 @@ void ide_undecoded_slave(ide_drive_t *dev1) { ide_drive_t *dev0 = &dev1->hwif->drives[0]; - if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0) + if ((dev1->dn & 1) == 0 || dev0->present == 0) return; /* If the models don't match they are not the same product */ @@ -769,7 +759,7 @@ void ide_undecoded_slave(ide_drive_t *dev1) /* Appears to be an IDE flash adapter with decode bugs */ printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); - dev1->dev_flags &= ~IDE_DFLAG_PRESENT; + dev1->present = 0; } EXPORT_SYMBOL_GPL(ide_undecoded_slave); @@ -782,8 +772,7 @@ static int ide_probe_port(ide_hwif_t *hwif) BUG_ON(hwif->present); - if ((hwif->drives[0].dev_flags & IDE_DFLAG_NOPROBE) && - (hwif->drives[1].dev_flags & IDE_DFLAG_NOPROBE)) + if (hwif->drives[0].noprobe && hwif->drives[1].noprobe) return -EACCES; /* @@ -805,9 +794,9 @@ static int ide_probe_port(ide_hwif_t *hwif) */ for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - + drive->dn = (hwif->channel ? 2 : 0) + unit; (void) probe_for_drive(drive); - if (drive->dev_flags & IDE_DFLAG_PRESENT) + if (drive->present) rc = 0; } @@ -831,19 +820,17 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) for (unit = 0; unit < MAX_DRIVES; unit++) { ide_drive_t *drive = &hwif->drives[unit]; - if (drive->dev_flags & IDE_DFLAG_PRESENT) { - if (port_ops && port_ops->quirkproc) - port_ops->quirkproc(drive); - } + if (drive->present && port_ops && port_ops->quirkproc) + port_ops->quirkproc(drive); } for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - if (drive->dev_flags & IDE_DFLAG_PRESENT) { + if (drive->present) { ide_set_max_pio(drive); - drive->dev_flags |= IDE_DFLAG_NICE1; + drive->nice1 = 1; if (hwif->dma_ops) ide_set_dma(drive); @@ -853,14 +840,14 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - if ((hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) || - drive->id[ATA_ID_DWORD_IO]) - drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; + if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) + drive->no_io_32bit = 1; else - drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; + drive->no_io_32bit = drive->id[ATA_ID_DWORD_IO] ? 1 : 0; } } +#if MAX_HWIFS > 1 /* * save_match() is used to simplify logic in init_irq() below. * @@ -885,6 +872,7 @@ static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */ *match = new; } +#endif /* MAX_HWIFS > 1 */ /* * init request queue @@ -963,33 +951,26 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive) * - allocate the block device queue * - link drive into the hwgroup */ -static int ide_port_setup_devices(ide_hwif_t *hwif) +static void ide_port_setup_devices(ide_hwif_t *hwif) { - int i, j = 0; + int i; mutex_lock(&ide_cfg_mtx); for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive = &hwif->drives[i]; - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (!drive->present) continue; if (ide_init_queue(drive)) { printk(KERN_ERR "ide: failed to init %s\n", drive->name); - kfree(drive->id); - drive->id = NULL; - drive->dev_flags &= ~IDE_DFLAG_PRESENT; continue; } - j++; - ide_add_drive_to_hwgroup(drive); } mutex_unlock(&ide_cfg_mtx); - - return j; } static ide_hwif_t *ide_ports[MAX_HWIFS]; @@ -1048,7 +1029,7 @@ static int init_irq (ide_hwif_t *hwif) mutex_lock(&ide_cfg_mtx); hwif->hwgroup = NULL; - +#if MAX_HWIFS > 1 /* * Group up with any other hwifs that share our irq(s). */ @@ -1073,7 +1054,7 @@ static int init_irq (ide_hwif_t *hwif) } } } - +#endif /* MAX_HWIFS > 1 */ /* * If we are still without a hwgroup, then form a new one */ @@ -1172,13 +1153,12 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) ide_hwif_t *hwif = data; int unit = *part >> PARTN_BITS; ide_drive_t *drive = &hwif->drives[unit]; - - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (!drive->present) return NULL; if (drive->media == ide_disk) request_module("ide-disk"); - if (drive->dev_flags & IDE_DFLAG_SCSI) + if (drive->scsi) request_module("ide-scsi"); if (drive->media == ide_cdrom || drive->media == ide_optical) request_module("ide-cd"); @@ -1225,7 +1205,7 @@ EXPORT_SYMBOL_GPL(ide_unregister_region); void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - unsigned int unit = drive->dn & 1; + unsigned int unit = (drive->select.all >> 4) & 1; disk->major = hwif->major; disk->first_minor = unit << PARTN_BITS; @@ -1268,7 +1248,7 @@ static void drive_release_dev (struct device *dev) ide_remove_drive_from_hwgroup(drive); kfree(drive->id); drive->id = NULL; - drive->dev_flags &= ~IDE_DFLAG_PRESENT; + drive->present = 0; /* Messed up locking ... */ spin_unlock_irq(&ide_lock); blk_cleanup_queue(drive->queue); @@ -1347,7 +1327,7 @@ static void hwif_register_devices(ide_hwif_t *hwif) struct device *dev = &drive->gendev; int ret; - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (!drive->present) continue; snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i); @@ -1371,14 +1351,12 @@ static void ide_port_init_devices(ide_hwif_t *hwif) for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive = &hwif->drives[i]; - drive->dn = i + hwif->channel * 2; - if (hwif->host_flags & IDE_HFLAG_IO_32BIT) drive->io_32bit = 1; if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS) - drive->dev_flags |= IDE_DFLAG_UNMASK; + drive->unmask = 1; if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) - drive->dev_flags |= IDE_DFLAG_NO_UNMASK; + drive->no_unmask = 1; if (port_ops && port_ops->init_dev) port_ops->init_dev(drive); @@ -1535,14 +1513,19 @@ static int ide_find_port_slot(const struct ide_port_info *d) * ports 0x1f0/0x170 (the ide0/ide1 defaults). */ mutex_lock(&ide_cfg_mtx); - if (bootable) { - if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1) - idx = ffz(ide_indexes | i); + if (MAX_HWIFS == 1) { + if (ide_indexes == 0 && i == 0) + idx = 1; } else { - if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1) - idx = ffz(ide_indexes | 3); - else if ((ide_indexes & 3) != 3) - idx = ffz(ide_indexes); + if (bootable) { + if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1) + idx = ffz(ide_indexes | i); + } else { + if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1) + idx = ffz(ide_indexes | 3); + else if ((ide_indexes & 3) != 3) + idx = ffz(ide_indexes); + } } if (idx >= 0) ide_indexes |= (1 << idx); @@ -1558,7 +1541,8 @@ static void ide_free_port_slot(int idx) mutex_unlock(&ide_cfg_mtx); } -struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) +struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, + hw_regs_t **hws) { struct ide_host *host; int i; @@ -1567,7 +1551,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) if (host == NULL) return NULL; - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { ide_hwif_t *hwif; int idx; @@ -1609,6 +1593,18 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) return host; } +EXPORT_SYMBOL_GPL(ide_host_alloc_all); + +struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) +{ + hw_regs_t *hws_all[MAX_HWIFS]; + int i; + + for (i = 0; i < MAX_HWIFS; i++) + hws_all[i] = (i < 4) ? hws[i] : NULL; + + return ide_host_alloc_all(d, hws_all); +} EXPORT_SYMBOL_GPL(ide_host_alloc); int ide_host_register(struct ide_host *host, const struct ide_port_info *d, @@ -1617,7 +1613,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_hwif_t *hwif, *mate = NULL; int i, j = 0; - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { hwif = host->ports[i]; if (hwif == NULL) { @@ -1630,22 +1626,22 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, if (d == NULL) { mate = NULL; - } else { - if ((i & 1) && mate) { - hwif->mate = mate; - mate->mate = hwif; - } - - mate = (i & 1) ? NULL : hwif; + continue; + } - ide_init_port(hwif, i & 1, d); - ide_port_cable_detect(hwif); + if ((i & 1) && mate) { + hwif->mate = mate; + mate->mate = hwif; } + mate = (i & 1) ? NULL : hwif; + + ide_init_port(hwif, i & 1, d); + ide_port_cable_detect(hwif); ide_port_init_devices(hwif); } - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1662,7 +1658,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_port_tune_devices(hwif); } - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1675,21 +1671,18 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, continue; } - if (hwif->present) - if (ide_port_setup_devices(hwif) == 0) { - hwif->present = 0; - continue; - } - j++; + if (hwif->present) + ide_port_setup_devices(hwif); + ide_acpi_init(hwif); if (hwif->present) ide_acpi_port_init_devices(hwif); } - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1702,7 +1695,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, hwif_register_devices(hwif); } - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1747,7 +1740,7 @@ void ide_host_free(struct ide_host *host) ide_hwif_t *hwif; int i; - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { hwif = host->ports[i]; if (hwif == NULL) @@ -1765,7 +1758,7 @@ void ide_host_remove(struct ide_host *host) { int i; - for (i = 0; i < MAX_HOST_PORTS; i++) { + for (i = 0; i < MAX_HWIFS; i++) { if (host->ports[i]) ide_unregister(host->ports[i]); } diff --git a/trunk/drivers/ide/ide-proc.c b/trunk/drivers/ide/ide-proc.c index b26926487cc0..e7030a491463 100644 --- a/trunk/drivers/ide/ide-proc.c +++ b/trunk/drivers/ide/ide-proc.c @@ -227,7 +227,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) ide_devset_rw(current_speed, xfer_rate); ide_devset_rw_field(init_speed, init_speed); -ide_devset_rw_flag(nice1, IDE_DFLAG_NICE1); +ide_devset_rw_field(nice1, nice1); ide_devset_rw_field(number, dn); static const struct ide_proc_devset ide_generic_settings[] = { @@ -622,7 +622,9 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif) for (d = 0; d < MAX_DRIVES; d++) { ide_drive_t *drive = &hwif->drives[d]; - if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc) + if (!drive->present) + continue; + if (drive->proc) continue; drive->proc = proc_mkdir(drive->name, parent); diff --git a/trunk/drivers/ide/ide-tape.c b/trunk/drivers/ide/ide-tape.c index d879c7797cde..f8c84df4a0bc 100644 --- a/trunk/drivers/ide/ide-tape.c +++ b/trunk/drivers/ide/ide-tape.c @@ -172,16 +172,23 @@ typedef struct ide_tape_obj { struct kref kref; /* + * pc points to the current processed packet command. + * * failed_pc points to the last failed packet command, or contains * NULL if we do not need to retry any packet command. This is * required since an additional packet command is needed before the * retry, to get detailed information on what went wrong. */ + /* Current packet command */ + struct ide_atapi_pc *pc; /* Last failed packet command */ struct ide_atapi_pc *failed_pc; /* used by REQ_IDETAPE_{READ,WRITE} requests */ struct ide_atapi_pc queued_pc; + struct ide_atapi_pc request_sense_pc; + struct request request_sense_rq; + /* * DSC polling variables. * @@ -267,6 +274,11 @@ static DEFINE_MUTEX(idetape_ref_mutex); static struct class *idetape_sysfs_class; +#define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref) + +#define ide_tape_g(disk) \ + container_of((disk)->private_data, struct ide_tape_obj, driver) + static void ide_tape_release(struct kref *); static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) @@ -274,7 +286,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) struct ide_tape_obj *tape = NULL; mutex_lock(&idetape_ref_mutex); - tape = ide_drv_g(disk, ide_tape_obj); + tape = ide_tape_g(disk); if (tape) { if (ide_device_get(tape->drive)) tape = NULL; @@ -301,6 +313,8 @@ static void ide_tape_put(struct ide_tape_obj *tape) */ static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; +#define ide_tape_f(file) ((file)->private_data) + static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) { struct ide_tape_obj *tape = NULL; @@ -508,19 +522,14 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) return 0; } -static void ide_tape_handle_dsc(ide_drive_t *); - -static void ide_tape_callback(ide_drive_t *drive, int dsc) +static void ide_tape_callback(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = drive->pc; + struct ide_atapi_pc *pc = tape->pc; int uptodate = pc->error ? 0 : 1; debug_log(DBG_PROCS, "Enter %s\n", __func__); - if (dsc) - ide_tape_handle_dsc(drive); - if (tape->failed_pc == pc) tape->failed_pc = NULL; @@ -549,7 +558,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc) if (pc->error) uptodate = pc->error; } else if (pc->c[0] == READ_POSITION && uptodate) { - u8 *readpos = pc->buf; + u8 *readpos = tape->pc->buf; debug_log(DBG_SENSE, "BOP - %s\n", (readpos[0] & 0x80) ? "Yes" : "No"); @@ -574,6 +583,31 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc) idetape_end_request(drive, uptodate, 0); } +static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) +{ + ide_init_pc(pc); + pc->c[0] = REQUEST_SENSE; + pc->c[4] = 20; + pc->req_xfer = 20; +} + +/* + * idetape_retry_pc is called when an error was detected during the + * last packet command. We queue a request sense packet command in + * the head of the request list. + */ +static void idetape_retry_pc(ide_drive_t *drive) +{ + struct ide_tape_obj *tape = drive->driver_data; + struct request *rq = &tape->request_sense_rq; + struct ide_atapi_pc *pc = &tape->request_sense_pc; + + (void)ide_read_error(drive); + idetape_create_request_sense_cmd(pc); + set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); + ide_queue_pc_head(drive, tape->disk, pc, rq); +} + /* * Postpone the current request so that ide.c will be able to service requests * from another device on the same hwgroup while we are polling for DSC. @@ -611,19 +645,35 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, return bcount; } +/* + * This is the usual interrupt handler which will be called during a packet + * command. We will transfer some of the data (as requested by the drive) and + * will re-point interrupt handler to us. When data transfer is finished, we + * will act according to the algorithm described before + * idetape_issue_pc. + */ +static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) +{ + idetape_tape_t *tape = drive->driver_data; + + return ide_pc_intr(drive, tape->pc, idetape_pc_intr, WAIT_TAPE_CMD, + NULL, idetape_update_buffers, idetape_retry_pc, + ide_tape_handle_dsc, ide_tape_io_buffers); +} + /* * Packet Command Interface * - * The current Packet Command is available in drive->pc, and will not change + * The current Packet Command is available in tape->pc, and will not change * until we finish handling it. Each packet command is associated with a * callback function that will be called when the command is finished. * * The handling will be done in three stages: * * 1. idetape_issue_pc will send the packet command to the drive, and will set - * the interrupt handler to ide_pc_intr. + * the interrupt handler to idetape_pc_intr. * - * 2. On each interrupt, ide_pc_intr will be called. This step will be + * 2. On each interrupt, idetape_pc_intr will be called. This step will be * repeated until the device signals us that no more interrupts will be issued. * * 3. ATAPI Tape media access commands have immediate status with a delayed @@ -647,13 +697,20 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, * again, the callback function will be called and then we will handle the next * request. */ +static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) +{ + idetape_tape_t *tape = drive->driver_data; + + return ide_transfer_pc(drive, tape->pc, idetape_pc_intr, + WAIT_TAPE_CMD, NULL); +} static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { idetape_tape_t *tape = drive->driver_data; - if (drive->pc->c[0] == REQUEST_SENSE && + if (tape->pc->c[0] == REQUEST_SENSE && pc->c[0] == REQUEST_SENSE) { printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " "Two request sense in serial were issued\n"); @@ -661,9 +718,8 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) tape->failed_pc = pc; - /* Set the current packet command */ - drive->pc = pc; + tape->pc = pc; if (pc->retries > IDETAPE_MAX_PC_RETRIES || (pc->flags & PC_FLAG_ABORT)) { @@ -687,14 +743,15 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->error = IDETAPE_ERROR_GENERAL; } tape->failed_pc = NULL; - drive->pc_callback(drive, 0); + drive->pc_callback(drive); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); pc->retries++; - return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL); + return ide_issue_pc(drive, pc, idetape_transfer_pc, + WAIT_TAPE_CMD, NULL); } /* A mode sense command is used to "sense" tape parameters. */ @@ -728,7 +785,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = drive->pc; + struct ide_atapi_pc *pc = tape->pc; u8 stat; stat = hwif->tp_ops->read_status(hwif); @@ -740,7 +797,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: I/O error, ", tape->name); /* Retry operation */ - ide_retry_pc(drive, tape->disk); + idetape_retry_pc(drive); return ide_stopped; } pc->error = 0; @@ -748,7 +805,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) pc->error = IDETAPE_ERROR_GENERAL; tape->failed_pc = NULL; } - drive->pc_callback(drive, 0); + drive->pc_callback(drive); return ide_stopped; } @@ -805,7 +862,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, } /* Retry a failed packet command */ - if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { + if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) { pc = tape->failed_pc; goto out; } @@ -826,13 +883,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, */ stat = hwif->tp_ops->read_status(hwif); - if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && - (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) + if (!drive->dsc_overlap && !(rq->cmd[13] & REQ_IDETAPE_PC2)) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - if (drive->dev_flags & IDE_DFLAG_POST_RESET) { + if (drive->post_reset == 1) { set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - drive->dev_flags &= ~IDE_DFLAG_POST_RESET; + drive->post_reset = 0; } if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && @@ -1355,7 +1411,7 @@ static int idetape_init_read(ide_drive_t *drive) * No point in issuing this if DSC overlap isn't supported, some * drives (Seagate STT3401A) will return an error. */ - if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { + if (drive->dsc_overlap) { bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_bh); @@ -1536,7 +1592,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct ide_tape_obj *tape = file->private_data; + struct ide_tape_obj *tape = ide_tape_f(file); ide_drive_t *drive = tape->drive; ssize_t bytes_read, temp, actually_read = 0, rc; ssize_t ret = 0; @@ -1598,7 +1654,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct ide_tape_obj *tape = file->private_data; + struct ide_tape_obj *tape = ide_tape_f(file); ide_drive_t *drive = tape->drive; ssize_t actually_written = 0; ssize_t ret = 0; @@ -1631,7 +1687,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, * point in issuing this if DSC overlap isn't supported, some * drives (Seagate STT3401A) will return an error. */ - if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { + if (drive->dsc_overlap) { ssize_t retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_bh); @@ -1830,7 +1886,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct ide_tape_obj *tape = file->private_data; + struct ide_tape_obj *tape = ide_tape_f(file); ide_drive_t *drive = tape->drive; struct mtop mtop; struct mtget mtget; @@ -2007,7 +2063,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) static int idetape_chrdev_release(struct inode *inode, struct file *filp) { - struct ide_tape_obj *tape = filp->private_data; + struct ide_tape_obj *tape = ide_tape_f(filp); ide_drive_t *drive = tape->drive; unsigned int minor = iminor(inode); @@ -2146,7 +2202,7 @@ static int divf_tdsc(ide_drive_t *drive) { return HZ; } static int divf_buffer(ide_drive_t *drive) { return 2; } static int divf_buffer_size(ide_drive_t *drive) { return 1024; } -ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); +ide_devset_rw_field(dsc_overlap, dsc_overlap); ide_tape_devset_rw_field(debug_mask, debug_mask); ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); @@ -2185,32 +2241,33 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) unsigned long t; int speed; int buffer_size; + u8 gcw[2]; u16 *ctl = (u16 *)&tape->caps[12]; - drive->pc_callback = ide_tape_callback; - drive->pc_update_buffers = idetape_update_buffers; - drive->pc_io_buffers = ide_tape_io_buffers; + drive->pc_callback = ide_tape_callback; spin_lock_init(&tape->lock); - - drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; - + drive->dsc_overlap = 1; if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", tape->name); - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + drive->dsc_overlap = 0; } - /* Seagate Travan drives do not support DSC overlap. */ if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401")) - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; - + drive->dsc_overlap = 0; tape->minor = minor; tape->name[0] = 'h'; tape->name[1] = 't'; tape->name[2] = '0' + minor; tape->chrdev_dir = IDETAPE_DIR_NONE; + *((u16 *)&gcw) = drive->id[ATA_ID_CONFIG]; + + /* Command packet DRQ type */ + if (((gcw[0] & 0x60) >> 5) == 1) + set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); + idetape_get_inquiry_results(drive); idetape_get_mode_sense_results(drive); ide_tape_get_bsize_from_bdesc(drive); @@ -2245,7 +2302,7 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size, tape->buffer_size / 1024, tape->best_dsc_rw_freq * 1000 / HZ, - (drive->dev_flags & IDE_DFLAG_USING_DMA) ? ", DMA" : ""); + drive->using_dma ? ", DMA":""); ide_proc_register_driver(drive, tape->driver); } @@ -2263,13 +2320,13 @@ static void ide_tape_remove(ide_drive_t *drive) static void ide_tape_release(struct kref *kref) { - struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj); + struct ide_tape_obj *tape = to_ide_tape(kref); ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; BUG_ON(tape->merge_bh_size); - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + drive->dsc_overlap = 0; drive->driver_data = NULL; device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); device_destroy(idetape_sysfs_class, @@ -2311,6 +2368,7 @@ static ide_driver_t idetape_driver = { .probe = ide_tape_probe, .remove = ide_tape_remove, .version = IDETAPE_VERSION, + .media = ide_tape, .do_request = idetape_do_request, .end_request = idetape_end_request, .error = __ide_error, @@ -2345,7 +2403,7 @@ static int idetape_open(struct inode *inode, struct file *filp) static int idetape_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); + struct ide_tape_obj *tape = ide_tape_g(disk); ide_tape_put(tape); @@ -2356,7 +2414,7 @@ static int idetape_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); + struct ide_tape_obj *tape = ide_tape_g(bdev->bd_disk); ide_drive_t *drive = tape->drive; int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); if (err == -EINVAL) @@ -2383,8 +2441,7 @@ static int ide_tape_probe(ide_drive_t *drive) if (drive->media != ide_tape) goto failed; - if ((drive->dev_flags & IDE_DFLAG_ID_READ) && - ide_check_atapi_device(drive, DRV_NAME) == 0) { + if (drive->id_read == 1 && !ide_check_atapi_device(drive, DRV_NAME)) { printk(KERN_ERR "ide-tape: %s: not supported by this version of" " the driver\n", drive->name); goto failed; @@ -2420,11 +2477,12 @@ static int ide_tape_probe(ide_drive_t *drive) idetape_setup(drive, tape, minor); - device_create(idetape_sysfs_class, &drive->gendev, - MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name); - device_create(idetape_sysfs_class, &drive->gendev, - MKDEV(IDETAPE_MAJOR, minor + 128), NULL, - "n%s", tape->name); + device_create_drvdata(idetape_sysfs_class, &drive->gendev, + MKDEV(IDETAPE_MAJOR, minor), NULL, + "%s", tape->name); + device_create_drvdata(idetape_sysfs_class, &drive->gendev, + MKDEV(IDETAPE_MAJOR, minor + 128), NULL, + "n%s", tape->name); g->fops = &idetape_block_ops; ide_register_region(g); diff --git a/trunk/drivers/ide/ide-taskfile.c b/trunk/drivers/ide/ide-taskfile.c index bf4fb9d8d176..487b18b3ebae 100644 --- a/trunk/drivers/ide/ide-taskfile.c +++ b/trunk/drivers/ide/ide-taskfile.c @@ -53,6 +53,9 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) } static ide_startstop_t task_no_data_intr(ide_drive_t *); +static ide_startstop_t set_geometry_intr(ide_drive_t *); +static ide_startstop_t recal_intr(ide_drive_t *); +static ide_startstop_t set_multmode_intr(ide_drive_t *); static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); static ide_startstop_t task_in_intr(ide_drive_t *); @@ -76,8 +79,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) if (task->tf_flags & IDE_TFLAG_FLAGGED) task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; - memcpy(&hwif->task, task, sizeof(*task)); - if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); tp_ops->set_irq(hwif, 1); @@ -98,12 +99,24 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) case TASKFILE_NO_DATA: if (handler == NULL) handler = task_no_data_intr; + if (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) { + switch (tf->command) { + case ATA_CMD_INIT_DEV_PARAMS: + handler = set_geometry_intr; + break; + case ATA_CMD_RESTORE: + handler = recal_intr; + break; + case ATA_CMD_SET_MULTI: + handler = set_multmode_intr; + break; + } + } ide_execute_command(drive, tf->command, handler, WAIT_WORSTCASE, NULL); return ide_started; default: - if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || - dma_ops->dma_setup(drive)) + if (drive->using_dma == 0 || dma_ops->dma_setup(drive)) return ide_stopped; dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_start(drive); @@ -113,15 +126,33 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) EXPORT_SYMBOL_GPL(do_rw_taskfile); /* - * Handler for commands without a data phase + * set_multmode_intr() is invoked on completion of a ATA_CMD_SET_MULTI cmd. */ -static ide_startstop_t task_no_data_intr(ide_drive_t *drive) +static ide_startstop_t set_multmode_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - ide_task_t *task = &hwif->task; - struct ide_taskfile *tf = &task->tf; - int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0; - int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1; + u8 stat; + + local_irq_enable_in_hardirq(); + stat = hwif->tp_ops->read_status(hwif); + + if (OK_STAT(stat, ATA_DRDY, BAD_STAT)) + drive->mult_count = drive->mult_req; + else { + drive->mult_req = drive->mult_count = 0; + drive->special.b.recalibrate = 1; + (void) ide_dump_status(drive, "set_multmode", stat); + } + return ide_stopped; +} + +/* + * set_geometry_intr() is invoked on completion of a ATA_CMD_INIT_DEV_PARAMS cmd. + */ +static ide_startstop_t set_geometry_intr(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + int retries = 5; u8 stat; local_irq_enable_in_hardirq(); @@ -133,36 +164,50 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) udelay(10); }; - if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { - if (custom && tf->command == ATA_CMD_SET_MULTI) { - drive->mult_req = drive->mult_count = 0; - drive->special.b.recalibrate = 1; - (void)ide_dump_status(drive, __func__, stat); - return ide_stopped; - } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) { - if ((stat & (ATA_ERR | ATA_DRQ)) == 0) { - ide_set_handler(drive, &task_no_data_intr, - WAIT_WORSTCASE, NULL); - return ide_started; - } - } + if (OK_STAT(stat, ATA_DRDY, BAD_STAT)) + return ide_stopped; + + if (stat & (ATA_ERR | ATA_DRQ)) + return ide_error(drive, "set_geometry_intr", stat); + + ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); + return ide_started; +} + +/* + * recal_intr() is invoked on completion of a ATA_CMD_RESTORE (recalibrate) cmd. + */ +static ide_startstop_t recal_intr(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + u8 stat; + + local_irq_enable_in_hardirq(); + stat = hwif->tp_ops->read_status(hwif); + + if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) + return ide_error(drive, "recal_intr", stat); + return ide_stopped; +} + +/* + * Handler for commands without a data phase + */ +static ide_startstop_t task_no_data_intr(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + ide_task_t *args = hwif->hwgroup->rq->special; + u8 stat; + + local_irq_enable_in_hardirq(); + stat = hwif->tp_ops->read_status(hwif); + + if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) return ide_error(drive, "task_no_data_intr", stat); /* calls ide_end_drive_cmd */ - } - if (!custom) - ide_end_drive_cmd(drive, stat, ide_read_error(drive)); - else if (tf->command == ATA_CMD_IDLEIMMEDIATE) { - hwif->tp_ops->tf_read(drive, task); - if (tf->lbal != 0xc4) { - printk(KERN_ERR "%s: head unload failed!\n", - drive->name); - ide_tf_dump(drive->name, tf); - } else - drive->dev_flags |= IDE_DFLAG_PARKED; + if (args) ide_end_drive_cmd(drive, stat, ide_read_error(drive)); - } else if (tf->command == ATA_CMD_SET_MULTI) - drive->mult_count = drive->mult_req; return ide_stopped; } @@ -424,12 +469,13 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) if (ide_wait_stat(&startstop, drive, ATA_DRQ, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", - drive->name, drive->hwif->data_phase ? "MULT" : "", - (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); + drive->name, + drive->hwif->data_phase ? "MULT" : "", + drive->addressing ? "_EXT" : ""); return startstop; } - if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) + if (!drive->unmask) local_irq_disable(); ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); @@ -545,7 +591,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | IDE_TFLAG_IN_TF; - if (drive->dev_flags & IDE_DFLAG_LBA48) + if (drive->addressing == 1) args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); if (req_task->out_flags.all) { @@ -648,7 +694,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) && req_task->in_flags.all == 0) { req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; - if (drive->dev_flags & IDE_DFLAG_LBA48) + if (drive->addressing == 1) req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); } diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index 04f8f13cb9d7..9dcf5aed92cb 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -114,7 +114,7 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) memset(drive, 0, sizeof(*drive)); drive->media = ide_disk; - drive->select = (unit << 4) | ATA_DEVICE_OBS; + drive->select.all = (unit<<4)|0xa0; drive->hwif = hwif; drive->ready_stat = ATA_DRDY; drive->bad_wstat = BAD_W_STAT; @@ -138,7 +138,7 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif) for (i = 0; i < MAX_DRIVES; i++) { ide_drive_t *drive = &hwif->drives[i]; - if (drive->dev_flags & IDE_DFLAG_PRESENT) { + if (drive->present) { spin_unlock_irq(&ide_lock); device_unregister(&drive->gendev); wait_for_completion(&drive->gendev_rel_comp); @@ -227,7 +227,8 @@ void ide_unregister(ide_hwif_t *hwif) kfree(hwif->sg_table); unregister_blkdev(hwif->major, hwif->name); - ide_release_dma_engine(hwif); + if (hwif->dma_base) + ide_release_dma_engine(hwif); mutex_unlock(&ide_cfg_mtx); } @@ -253,7 +254,7 @@ ide_devset_get(io_32bit, io_32bit); static int set_io_32bit(ide_drive_t *drive, int arg) { - if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) + if (drive->no_io_32bit) return -EPERM; if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) @@ -264,22 +265,19 @@ static int set_io_32bit(ide_drive_t *drive, int arg) return 0; } -ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS); +ide_devset_get(ksettings, keep_settings); static int set_ksettings(ide_drive_t *drive, int arg) { if (arg < 0 || arg > 1) return -EINVAL; - if (arg) - drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS; - else - drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS; + drive->keep_settings = arg; return 0; } -ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA); +ide_devset_get(using_dma, using_dma); static int set_using_dma(ide_drive_t *drive, int arg) { @@ -313,32 +311,9 @@ static int set_using_dma(ide_drive_t *drive, int arg) #endif } -/* - * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away - */ -static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) -{ - switch (req_pio) { - case 202: - case 201: - case 200: - case 102: - case 101: - case 100: - return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; - case 9: - case 8: - return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; - case 7: - case 6: - return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; - default: - return 0; - } -} - static int set_pio_mode(ide_drive_t *drive, int arg) { + struct request *rq; ide_hwif_t *hwif = drive->hwif; const struct ide_port_ops *port_ops = hwif->port_ops; @@ -349,65 +324,56 @@ static int set_pio_mode(ide_drive_t *drive, int arg) (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) return -ENOSYS; - if (set_pio_mode_abuse(drive->hwif, arg)) { - if (arg == 8 || arg == 9) { - unsigned long flags; + if (drive->special.b.set_tune) + return -EBUSY; - /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ - spin_lock_irqsave(&ide_lock, flags); - port_ops->set_pio_mode(drive, arg); - spin_unlock_irqrestore(&ide_lock, flags); - } else - port_ops->set_pio_mode(drive, arg); - } else { - int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; - ide_set_pio(drive, arg); + drive->tune_req = (u8) arg; + drive->special.b.set_tune = 1; - if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { - if (keep_dma) - ide_dma_on(drive); - } - } + blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); return 0; } -ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK); +ide_devset_get(unmaskirq, unmask); static int set_unmaskirq(ide_drive_t *drive, int arg) { - if (drive->dev_flags & IDE_DFLAG_NO_UNMASK) + if (drive->no_unmask) return -EPERM; if (arg < 0 || arg > 1) return -EINVAL; - if (arg) - drive->dev_flags |= IDE_DFLAG_UNMASK; - else - drive->dev_flags &= ~IDE_DFLAG_UNMASK; + drive->unmask = arg; return 0; } -ide_ext_devset_rw_sync(io_32bit, io_32bit); -ide_ext_devset_rw_sync(keepsettings, ksettings); -ide_ext_devset_rw_sync(unmaskirq, unmaskirq); -ide_ext_devset_rw_sync(using_dma, using_dma); -__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode); +#define ide_gen_devset_rw(_name, _func) \ +__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) + +ide_gen_devset_rw(io_32bit, io_32bit); +ide_gen_devset_rw(keepsettings, ksettings); +ide_gen_devset_rw(unmaskirq, unmaskirq); +ide_gen_devset_rw(using_dma, using_dma); +__IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode); static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { - ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); + ide_drive_t *drive = dev->driver_data; ide_hwif_t *hwif = HWIF(drive); struct request *rq; struct request_pm_state rqpm; ide_task_t args; int ret; - /* call ACPI _GTM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) + /* Call ACPI _GTM only once */ + if (!(drive->dn % 2)) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); @@ -416,32 +382,33 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) rq->cmd_type = REQ_TYPE_PM_SUSPEND; rq->special = &args; rq->data = &rqpm; - rqpm.pm_step = IDE_PM_START_SUSPEND; + rqpm.pm_step = ide_pm_state_start_suspend; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; ret = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); - - /* call ACPI _PS3 only after both devices are suspended */ - if (ret == 0 && ((drive->dn & 1) || pair == NULL)) + /* only call ACPI _PS3 after both drivers are suspended */ + if (!ret && (((drive->dn % 2) && hwif->drives[0].present + && hwif->drives[1].present) + || !hwif->drives[0].present + || !hwif->drives[1].present)) ide_acpi_set_state(hwif, 0); - return ret; } static int generic_ide_resume(struct device *dev) { - ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); + ide_drive_t *drive = dev->driver_data; ide_hwif_t *hwif = HWIF(drive); struct request *rq; struct request_pm_state rqpm; ide_task_t args; int err; - /* call ACPI _PS0 / _STM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) { + /* Call ACPI _STM only once */ + if (!(drive->dn % 2)) { ide_acpi_set_state(hwif, 1); ide_acpi_push_timing(hwif); } @@ -455,7 +422,7 @@ static int generic_ide_resume(struct device *dev) rq->cmd_flags |= REQ_PREEMPT; rq->special = &args; rq->data = &rqpm; - rqpm.pm_step = IDE_PM_START_RESUME; + rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_state = PM_EVENT_ON; err = blk_execute_rq(drive->queue, NULL, rq, 1); @@ -587,7 +554,6 @@ static struct device_attribute ide_dev_attrs[] = { __ATTR_RO(model), __ATTR_RO(firmware), __ATTR(serial, 0400, serial_show, NULL), - __ATTR(unload_heads, 0644, ide_park_show, ide_park_store), __ATTR_NULL }; @@ -742,22 +708,22 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) module_param_call(chs, ide_set_disk_chs, NULL, NULL, 0); MODULE_PARM_DESC(chs, "force device as a disk (using CHS)"); -static void ide_dev_apply_params(ide_drive_t *drive, u8 unit) +static void ide_dev_apply_params(ide_drive_t *drive) { - int i = drive->hwif->index * MAX_DRIVES + unit; + int i = drive->hwif->index * MAX_DRIVES + drive->select.b.unit; if (ide_nodma & (1 << i)) { printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name); - drive->dev_flags |= IDE_DFLAG_NODMA; + drive->nodma = 1; } if (ide_noflush & (1 << i)) { printk(KERN_INFO "ide: disabling flush requests for %s\n", drive->name); - drive->dev_flags |= IDE_DFLAG_NOFLUSH; + drive->noflush = 1; } if (ide_noprobe & (1 << i)) { printk(KERN_INFO "ide: skipping probe for %s\n", drive->name); - drive->dev_flags |= IDE_DFLAG_NOPROBE; + drive->noprobe = 1; } if (ide_nowerr & (1 << i)) { printk(KERN_INFO "ide: ignoring the ATA_DF bit for %s\n", @@ -766,7 +732,7 @@ static void ide_dev_apply_params(ide_drive_t *drive, u8 unit) } if (ide_cdroms & (1 << i)) { printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name); - drive->dev_flags |= IDE_DFLAG_PRESENT; + drive->present = 1; drive->media = ide_cdrom; /* an ATAPI device ignores DRDY */ drive->ready_stat = 0; @@ -775,12 +741,11 @@ static void ide_dev_apply_params(ide_drive_t *drive, u8 unit) drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl; drive->head = drive->bios_head = ide_disks_chs[i].head; drive->sect = drive->bios_sect = ide_disks_chs[i].sect; - + drive->forced_geom = 1; printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n", drive->name, drive->cyl, drive->head, drive->sect); - - drive->dev_flags |= IDE_DFLAG_FORCED_GEOM | IDE_DFLAG_PRESENT; + drive->present = 1; drive->media = ide_disk; drive->ready_stat = ATA_DRDY; } @@ -820,7 +785,7 @@ void ide_port_apply_params(ide_hwif_t *hwif) } for (i = 0; i < MAX_DRIVES; i++) - ide_dev_apply_params(&hwif->drives[i], i); + ide_dev_apply_params(&hwif->drives[i]); } /* diff --git a/trunk/drivers/ide/legacy/ali14xx.c b/trunk/drivers/ide/legacy/ali14xx.c index 90da1f953ed0..7276c96aaa2a 100644 --- a/trunk/drivers/ide/legacy/ali14xx.c +++ b/trunk/drivers/ide/legacy/ali14xx.c @@ -131,7 +131,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) drive->name, pio, time1, time2, param1, param2, param3, param4); /* stuff timing parameters into controller registers */ - driveNum = (drive->hwif->index << 1) + (drive->dn & 1); + driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit; spin_lock_irqsave(&ali14xx_lock, flags); outb_p(regOn, basePort); outReg(param1, regTab[driveNum].reg1); diff --git a/trunk/drivers/ide/legacy/ht6560b.c b/trunk/drivers/ide/legacy/ht6560b.c index c7e5c2246b79..5123ea291d07 100644 --- a/trunk/drivers/ide/legacy/ht6560b.c +++ b/trunk/drivers/ide/legacy/ht6560b.c @@ -120,8 +120,7 @@ static void ht6560b_selectproc (ide_drive_t *drive) * Need to enforce prefetch sometimes because otherwise * it'll hang (hard). */ - if (drive->media != ide_disk || - (drive->dev_flags & IDE_DFLAG_PRESENT) == 0) + if (drive->media != ide_disk || !drive->present) select |= HT_PREFETCH_MODE; if (select != current_select || timing != current_timing) { @@ -250,11 +249,11 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state) */ if (state) { drive->drive_data |= t; /* enable prefetch mode */ - drive->dev_flags |= IDE_DFLAG_NO_UNMASK; - drive->dev_flags &= ~IDE_DFLAG_UNMASK; + drive->no_unmask = 1; + drive->unmask = 0; } else { drive->drive_data &= ~t; /* disable prefetch mode */ - drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; + drive->no_unmask = 0; } spin_unlock_irqrestore(&ht6560b_lock, flags); diff --git a/trunk/drivers/ide/legacy/ide-4drives.c b/trunk/drivers/ide/legacy/ide-4drives.c index 9e85b1ec9607..c76d55de6996 100644 --- a/trunk/drivers/ide/legacy/ide-4drives.c +++ b/trunk/drivers/ide/legacy/ide-4drives.c @@ -14,7 +14,7 @@ MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); static void ide_4drives_init_dev(ide_drive_t *drive) { if (drive->hwif->channel) - drive->select ^= 0x20; + drive->select.all ^= 0x20; } static const struct ide_port_ops ide_4drives_port_ops = { diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index cb199c815b53..ee6fc30d5e2b 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -219,91 +219,103 @@ static struct ide_host *idecs_register(unsigned long io, unsigned long ctl, #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -struct pcmcia_config_check { - unsigned long ctl_base; - int skip_vcc; - int is_kme; -}; - -static int pcmcia_check_one_config(struct pcmcia_device *pdev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - struct pcmcia_config_check *stk = priv_data; - - /* Check for matching Vcc, unless we're desperate */ - if (!stk->skip_vcc) { - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) - return -ENODEV; - } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) - return -ENODEV; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) - pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; - - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - pdev->conf.ConfigIndex = cfg->index; - pdev->io.BasePort1 = io->win[0].base; - pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (!(io->flags & CISTPL_IO_16BIT)) - pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - if (io->nwin == 2) { - pdev->io.NumPorts1 = 8; - pdev->io.BasePort2 = io->win[1].base; - pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; - if (pcmcia_request_io(pdev, &pdev->io) != 0) - return -ENODEV; - stk->ctl_base = pdev->io.BasePort2; - } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { - pdev->io.NumPorts1 = io->win[0].len; - pdev->io.NumPorts2 = 0; - if (pcmcia_request_io(pdev, &pdev->io) != 0) - return -ENODEV; - stk->ctl_base = pdev->io.BasePort1 + 0x0e; - } else - return -ENODEV; - /* If we've got this far, we're done */ - return 0; - } - return -ENODEV; -} - static int ide_config(struct pcmcia_device *link) { ide_info_t *info = link->priv; - struct pcmcia_config_check *stk = NULL; - int last_ret = 0, last_fn = 0, is_kme = 0; + tuple_t tuple; + struct { + u_short buf[128]; + cisparse_t parse; + config_info_t conf; + cistpl_cftable_entry_t dflt; + } *stk = NULL; + cistpl_cftable_entry_t *cfg; + int pass, last_ret = 0, last_fn = 0, is_kme = 0; unsigned long io_base, ctl_base; struct ide_host *host; DEBUG(0, "ide_config(0x%p)\n", link); + stk = kzalloc(sizeof(*stk), GFP_KERNEL); + if (!stk) goto err_mem; + cfg = &stk->parse.cftable_entry; + + tuple.TupleData = (cisdata_t *)&stk->buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + is_kme = ((link->manf_id == MANFID_KME) && ((link->card_id == PRODID_KME_KXLC005_A) || (link->card_id == PRODID_KME_KXLC005_B))); - stk = kzalloc(sizeof(*stk), GFP_KERNEL); - if (!stk) - goto err_mem; - stk->is_kme = is_kme; - stk->skip_vcc = io_base = ctl_base = 0; - - if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) { - stk->skip_vcc = 1; - if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) - goto failed; /* No suitable config found */ + /* Not sure if this is right... look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); + + pass = io_base = ctl_base = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry; + if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry; + + /* Check for matching Vcc, unless we're desperate */ + if (!pass) { + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) + goto next_entry; + } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; + link->conf.ConfigIndex = cfg->index; + link->io.BasePort1 = io->win[0].base; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + if (io->nwin == 2) { + link->io.NumPorts1 = 8; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = (is_kme) ? 2 : 1; + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + io_base = link->io.BasePort1; + ctl_base = link->io.BasePort2; + } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { + link->io.NumPorts1 = io->win[0].len; + link->io.NumPorts2 = 0; + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + io_base = link->io.BasePort1; + ctl_base = link->io.BasePort1 + 0x0e; + } else goto next_entry; + /* If we've got this far, we're done */ + break; + } + + next_entry: + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); + if (pass) { + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } else if (pcmcia_get_next_tuple(link, &tuple) != 0) { + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + memset(&stk->dflt, 0, sizeof(stk->dflt)); + pass++; + } } - io_base = link->io.BasePort1; - ctl_base = stk->ctl_base; CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -391,10 +403,8 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */ PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */ PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), - PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ - PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ diff --git a/trunk/drivers/ide/legacy/qd65xx.c b/trunk/drivers/ide/legacy/qd65xx.c index bc27c7aba936..ec408b3a7100 100644 --- a/trunk/drivers/ide/legacy/qd65xx.c +++ b/trunk/drivers/ide/legacy/qd65xx.c @@ -305,7 +305,7 @@ static void __init qd6580_init_dev(ide_drive_t *drive) } else t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; - drive->drive_data = (drive->dn & 1) ? t2 : t1; + drive->drive_data = drive->select.b.unit ? t2 : t1; } static const struct ide_port_ops qd6500_port_ops = { diff --git a/trunk/drivers/ide/mips/au1xxx-ide.c b/trunk/drivers/ide/mips/au1xxx-ide.c index 0ec8fd1e4dcb..11b7f61aae40 100644 --- a/trunk/drivers/ide/mips/au1xxx-ide.c +++ b/trunk/drivers/ide/mips/au1xxx-ide.c @@ -322,7 +322,11 @@ static int auide_dma_setup(ide_drive_t *drive) } static int auide_dma_test_irq(ide_drive_t *drive) -{ +{ + if (drive->waiting_for_dma == 0) + printk(KERN_WARNING "%s: ide_dma_test_irq \ + called while not waiting\n", drive->name); + /* If dbdma didn't execute the STOP command yet, the * active bit is still set */ @@ -340,6 +344,11 @@ static void auide_dma_host_set(ide_drive_t *drive, int on) { } +static void auide_dma_lost_irq(ide_drive_t *drive) +{ + printk(KERN_ERR "%s: IRQ lost\n", drive->name); +} + static void auide_ddma_tx_callback(int irq, void *param) { _auide_hwif *ahwif = (_auide_hwif*)param; @@ -366,6 +375,18 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de } #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA +static void auide_dma_timeout(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + + printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); + + if (auide_dma_test_irq(drive)) + return; + + auide_dma_end(drive); +} + static const struct ide_dma_ops au1xxx_dma_ops = { .dma_host_set = auide_dma_host_set, .dma_setup = auide_dma_setup, @@ -373,8 +394,8 @@ static const struct ide_dma_ops au1xxx_dma_ops = { .dma_start = auide_dma_start, .dma_end = auide_dma_end, .dma_test_irq = auide_dma_test_irq, - .dma_lost_irq = ide_dma_lost_irq, - .dma_timeout = ide_dma_timeout, + .dma_lost_irq = auide_dma_lost_irq, + .dma_timeout = auide_dma_timeout, }; static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) @@ -427,9 +448,10 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) NUM_DESCRIPTORS); auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, NUM_DESCRIPTORS); - - /* FIXME: check return value */ - (void)ide_allocate_dma_engine(hwif); + + hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev, + PRD_ENTRIES * PRD_BYTES, /* 1 Page */ + &hwif->dmatable_dma, GFP_KERNEL); au1xxx_dbdma_start( auide->tx_chan ); au1xxx_dbdma_start( auide->rx_chan ); diff --git a/trunk/drivers/ide/pci/aec62xx.c b/trunk/drivers/ide/pci/aec62xx.c index 4142c698e0d3..e7475ba559c7 100644 --- a/trunk/drivers/ide/pci/aec62xx.c +++ b/trunk/drivers/ide/pci/aec62xx.c @@ -115,7 +115,7 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_host *host = pci_get_drvdata(dev); struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; - u8 unit = drive->dn & 1; + u8 unit = (drive->select.b.unit & 0x01); u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; unsigned long flags; @@ -302,7 +302,7 @@ static const struct pci_device_id aec62xx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); -static struct pci_driver aec62xx_pci_driver = { +static struct pci_driver driver = { .name = "AEC62xx_IDE", .id_table = aec62xx_pci_tbl, .probe = aec62xx_init_one, @@ -313,12 +313,12 @@ static struct pci_driver aec62xx_pci_driver = { static int __init aec62xx_ide_init(void) { - return ide_pci_register_driver(&aec62xx_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit aec62xx_ide_exit(void) { - pci_unregister_driver(&aec62xx_pci_driver); + pci_unregister_driver(&driver); } module_init(aec62xx_ide_init); diff --git a/trunk/drivers/ide/pci/alim15x3.c b/trunk/drivers/ide/pci/alim15x3.c index daf9dce39e52..053c75263918 100644 --- a/trunk/drivers/ide/pci/alim15x3.c +++ b/trunk/drivers/ide/pci/alim15x3.c @@ -77,7 +77,8 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) int bus_speed = ide_pci_clk ? ide_pci_clk : 33; int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; - u8 cd_dma_fifo = 0, unit = drive->dn & 1; + u8 cd_dma_fifo = 0; + int unit = drive->select.b.unit & 1; if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) s_clc = 0; @@ -111,7 +112,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) } pci_write_config_byte(dev, port, s_clc); - pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); + pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc); local_irq_restore(flags); } @@ -153,7 +154,7 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); u8 speed1 = speed; - u8 unit = drive->dn & 1; + u8 unit = (drive->select.b.unit & 0x01); u8 tmpbyte = 0x00; int m5229_udma = (hwif->channel) ? 0x57 : 0x56; @@ -507,7 +508,7 @@ static const struct ide_dma_ops ali_dma_ops = { .dma_setup = ali15x3_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = ide_dma_end, + .dma_end = __ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, .dma_timeout = ide_dma_timeout, @@ -575,7 +576,7 @@ static const struct pci_device_id alim15x3_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); -static struct pci_driver alim15x3_pci_driver = { +static struct pci_driver driver = { .name = "ALI15x3_IDE", .id_table = alim15x3_pci_tbl, .probe = alim15x3_init_one, @@ -586,12 +587,12 @@ static struct pci_driver alim15x3_pci_driver = { static int __init ali15x3_ide_init(void) { - return ide_pci_register_driver(&alim15x3_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit ali15x3_ide_exit(void) { - return pci_unregister_driver(&alim15x3_pci_driver); + return pci_unregister_driver(&driver); } module_init(ali15x3_ide_init); diff --git a/trunk/drivers/ide/pci/amd74xx.c b/trunk/drivers/ide/pci/amd74xx.c index 81ec73134eda..824471f91bf5 100644 --- a/trunk/drivers/ide/pci/amd74xx.c +++ b/trunk/drivers/ide/pci/amd74xx.c @@ -92,7 +92,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) ide_timing_compute(drive, speed, &t, T, UT); - if (peer->dev_flags & IDE_DFLAG_PRESENT) { + if (peer->present) { ide_timing_compute(peer, peer->current_speed, &p, T, UT); ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); } @@ -319,7 +319,7 @@ static const struct pci_device_id amd74xx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); -static struct pci_driver amd74xx_pci_driver = { +static struct pci_driver driver = { .name = "AMD_IDE", .id_table = amd74xx_pci_tbl, .probe = amd74xx_probe, @@ -330,12 +330,12 @@ static struct pci_driver amd74xx_pci_driver = { static int __init amd74xx_ide_init(void) { - return ide_pci_register_driver(&amd74xx_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit amd74xx_ide_exit(void) { - pci_unregister_driver(&amd74xx_pci_driver); + pci_unregister_driver(&driver); } module_init(amd74xx_ide_init); diff --git a/trunk/drivers/ide/pci/atiixp.c b/trunk/drivers/ide/pci/atiixp.c index b2735d28f5cc..e4437034dd08 100644 --- a/trunk/drivers/ide/pci/atiixp.c +++ b/trunk/drivers/ide/pci/atiixp.c @@ -182,7 +182,7 @@ static const struct pci_device_id atiixp_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); -static struct pci_driver atiixp_pci_driver = { +static struct pci_driver driver = { .name = "ATIIXP_IDE", .id_table = atiixp_pci_tbl, .probe = atiixp_init_one, @@ -193,12 +193,12 @@ static struct pci_driver atiixp_pci_driver = { static int __init atiixp_ide_init(void) { - return ide_pci_register_driver(&atiixp_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit atiixp_ide_exit(void) { - pci_unregister_driver(&atiixp_pci_driver); + pci_unregister_driver(&driver); } module_init(atiixp_ide_init); diff --git a/trunk/drivers/ide/pci/cmd640.c b/trunk/drivers/ide/pci/cmd640.c index e4306647d00d..7f39cdb41410 100644 --- a/trunk/drivers/ide/pci/cmd640.c +++ b/trunk/drivers/ide/pci/cmd640.c @@ -378,13 +378,13 @@ static void __set_prefetch_mode(ide_drive_t *drive, int mode) { if (mode) { /* want prefetch on? */ #if CMD640_PREFETCH_MASKS - drive->dev_flags |= IDE_DFLAG_NO_UNMASK; - drive->dev_flags &= ~IDE_DFLAG_UNMASK; + drive->no_unmask = 1; + drive->unmask = 0; #endif - drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; + drive->no_io_32bit = 0; } else { - drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; - drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; + drive->no_unmask = 0; + drive->no_io_32bit = 1; drive->io_32bit = 0; } } @@ -468,10 +468,10 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index) */ if (index > 1) { ide_hwif_t *hwif = drive->hwif; - ide_drive_t *peer = &hwif->drives[!(drive->dn & 1)]; + ide_drive_t *peer = &hwif->drives[!drive->select.b.unit]; unsigned int mate = index ^ 1; - if (peer->dev_flags & IDE_DFLAG_PRESENT) { + if (peer->present) { if (setup_count < setup_counts[mate]) setup_count = setup_counts[mate]; if (active_count < active_counts[mate]) @@ -607,7 +607,7 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) static void cmd640_init_dev(ide_drive_t *drive) { - unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1); + unsigned int i = drive->hwif->channel * 2 + drive->select.b.unit; #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED /* @@ -626,7 +626,7 @@ static void cmd640_init_dev(ide_drive_t *drive) */ check_prefetch(drive, i); printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n", - i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on"); + i, drive->no_io_32bit ? "off" : "on"); #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ } diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 935385c77e06..456dee18b660 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -228,7 +228,7 @@ static int cmd648_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); unsigned long base = hwif->dma_base - (hwif->channel * 8); - int err = ide_dma_end(drive); + int err = __ide_dma_end(drive); u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; u8 mrdmode = inb(base + 1); @@ -248,7 +248,7 @@ static int cmd64x_dma_end(ide_drive_t *drive) u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; u8 irq_stat = 0; - int err = ide_dma_end(drive); + int err = __ide_dma_end(drive); (void) pci_read_config_byte(dev, irq_reg, &irq_stat); /* clear the interrupt bit */ @@ -505,7 +505,7 @@ static const struct pci_device_id cmd64x_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cmd64x_pci_tbl); -static struct pci_driver cmd64x_pci_driver = { +static struct pci_driver driver = { .name = "CMD64x_IDE", .id_table = cmd64x_pci_tbl, .probe = cmd64x_init_one, @@ -516,12 +516,12 @@ static struct pci_driver cmd64x_pci_driver = { static int __init cmd64x_ide_init(void) { - return ide_pci_register_driver(&cmd64x_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit cmd64x_ide_exit(void) { - pci_unregister_driver(&cmd64x_pci_driver); + pci_unregister_driver(&driver); } module_init(cmd64x_ide_init); diff --git a/trunk/drivers/ide/pci/cs5520.c b/trunk/drivers/ide/pci/cs5520.c index 5efb467f8fa0..d6341f7c4144 100644 --- a/trunk/drivers/ide/pci/cs5520.c +++ b/trunk/drivers/ide/pci/cs5520.c @@ -145,7 +145,7 @@ static const struct pci_device_id cs5520_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cs5520_pci_tbl); -static struct pci_driver cs5520_pci_driver = { +static struct pci_driver driver = { .name = "Cyrix_IDE", .id_table = cs5520_pci_tbl, .probe = cs5520_init_one, @@ -155,7 +155,7 @@ static struct pci_driver cs5520_pci_driver = { static int __init cs5520_ide_init(void) { - return ide_pci_register_driver(&cs5520_pci_driver); + return ide_pci_register_driver(&driver); } module_init(cs5520_ide_init); diff --git a/trunk/drivers/ide/pci/cs5530.c b/trunk/drivers/ide/pci/cs5530.c index 53f079cc00af..da42fa7e9f97 100644 --- a/trunk/drivers/ide/pci/cs5530.c +++ b/trunk/drivers/ide/pci/cs5530.c @@ -267,7 +267,7 @@ static const struct pci_device_id cs5530_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cs5530_pci_tbl); -static struct pci_driver cs5530_pci_driver = { +static struct pci_driver driver = { .name = "CS5530 IDE", .id_table = cs5530_pci_tbl, .probe = cs5530_init_one, @@ -278,12 +278,12 @@ static struct pci_driver cs5530_pci_driver = { static int __init cs5530_ide_init(void) { - return ide_pci_register_driver(&cs5530_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit cs5530_ide_exit(void) { - pci_unregister_driver(&cs5530_pci_driver); + pci_unregister_driver(&driver); } module_init(cs5530_ide_init); diff --git a/trunk/drivers/ide/pci/cs5535.c b/trunk/drivers/ide/pci/cs5535.c index 983d957a0189..1e5bc59ea2fb 100644 --- a/trunk/drivers/ide/pci/cs5535.c +++ b/trunk/drivers/ide/pci/cs5535.c @@ -76,7 +76,7 @@ static unsigned int cs5535_udma_timings[5] = static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) { u32 reg = 0, dummy; - u8 unit = drive->dn & 1; + int unit = drive->select.b.unit; /* Set the PIO timings */ if (speed < XFER_SW_DMA_0) { @@ -192,7 +192,7 @@ static const struct pci_device_id cs5535_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl); -static struct pci_driver cs5535_pci_driver = { +static struct pci_driver driver = { .name = "CS5535_IDE", .id_table = cs5535_pci_tbl, .probe = cs5535_init_one, @@ -203,12 +203,12 @@ static struct pci_driver cs5535_pci_driver = { static int __init cs5535_ide_init(void) { - return ide_pci_register_driver(&cs5535_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit cs5535_ide_exit(void) { - pci_unregister_driver(&cs5535_pci_driver); + pci_unregister_driver(&driver); } module_init(cs5535_ide_init); diff --git a/trunk/drivers/ide/pci/cy82c693.c b/trunk/drivers/ide/pci/cy82c693.c index 5297f07d2933..69820e9224d1 100644 --- a/trunk/drivers/ide/pci/cy82c693.c +++ b/trunk/drivers/ide/pci/cy82c693.c @@ -50,11 +50,18 @@ #define DRV_NAME "cy82c693" +/* the current version */ +#define CY82_VERSION "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)" + /* * The following are used to debug the driver. */ +#define CY82C693_DEBUG_LOGS 0 #define CY82C693_DEBUG_INFO 0 +/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */ +#undef CY82C693_SETDMA_CLOCK + /* * NOTE: the value for busmaster timeout is tricky and I got it by * trial and error! By using a to low value will cause DMA timeouts @@ -82,6 +89,7 @@ #define CY82_INDEX_PORT 0x22 #define CY82_DATA_PORT 0x23 +#define CY82_INDEX_CTRLREG1 0x01 #define CY82_INDEX_CHANNEL0 0x30 #define CY82_INDEX_CHANNEL1 0x31 #define CY82_INDEX_TIMEOUT 0x32 @@ -171,6 +179,17 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0; +#if CY82C693_DEBUG_LOGS + /* for debug let's show the previous values */ + + outb(index, CY82_INDEX_PORT); + data = inb(CY82_DATA_PORT); + + printk(KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", + drive->name, HWIF(drive)->channel, drive->select.b.unit, + (data&0x3), ((data>>2)&1)); +#endif /* CY82C693_DEBUG_LOGS */ + data = (mode & 3) | (single << 2); outb(index, CY82_INDEX_PORT); @@ -178,7 +197,8 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) #if CY82C693_DEBUG_INFO printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", - drive->name, hwif->channel, drive->dn & 1, mode & 3, single); + drive->name, HWIF(drive)->channel, drive->select.b.unit, + mode & 3, single); #endif /* CY82C693_DEBUG_INFO */ /* @@ -219,11 +239,50 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) } } +#if CY82C693_DEBUG_LOGS + /* for debug let's show the register values */ + + if (drive->select.b.unit == 0) { + /* + * get master drive registers + * address setup control register + * is 32 bit !!! + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + addrCtrl &= 0x0F; + + /* now let's get the remaining registers */ + pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r); + pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w); + pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8); + } else { + /* + * set slave drive registers + * address setup control register + * is 32 bit !!! + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + + addrCtrl &= 0xF0; + addrCtrl >>= 4; + + /* now let's get the remaining registers */ + pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r); + pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w); + pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8); + } + + printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is " + "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", + drive->name, hwif->channel, drive->select.b.unit, + addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); +#endif /* CY82C693_DEBUG_LOGS */ + /* let's calc the values for this PIO mode */ compute_clocks(pio, &pclk); /* now let's write the clocks registers */ - if ((drive->dn & 1) == 0) { + if (drive->select.b.unit == 0) { /* * set master drive * address setup control register @@ -265,11 +324,63 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) #if CY82C693_DEBUG_INFO printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to " "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", - drive->name, hwif->channel, drive->dn & 1, + drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); #endif /* CY82C693_DEBUG_INFO */ } +/* + * this function is called during init and is used to setup the cy82c693 chip + */ +static unsigned int init_chipset_cy82c693(struct pci_dev *dev) +{ + if (PCI_FUNC(dev->devfn) != 1) + return 0; + +#ifdef CY82C693_SETDMA_CLOCK + u8 data = 0; +#endif /* CY82C693_SETDMA_CLOCK */ + + /* write info about this verion of the driver */ + printk(KERN_INFO CY82_VERSION "\n"); + +#ifdef CY82C693_SETDMA_CLOCK + /* okay let's set the DMA clock speed */ + + outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); + data = inb(CY82_DATA_PORT); + +#if CY82C693_DEBUG_INFO + printk(KERN_INFO DRV_NAME ": Peripheral Configuration Register: 0x%X\n", + data); +#endif /* CY82C693_DEBUG_INFO */ + + /* + * for some reason sometimes the DMA controller + * speed is set to ATCLK/2 ???? - we fix this here + * + * note: i don't know what causes this strange behaviour, + * but even changing the dma speed doesn't solve it :-( + * the ide performance is still only half the normal speed + * + * if anybody knows what goes wrong with my machine, please + * let me know - ASK + */ + + data |= 0x03; + + outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); + outb(data, CY82_DATA_PORT); + +#if CY82C693_DEBUG_INFO + printk(KERN_INFO ": New Peripheral Configuration Register: 0x%X\n", + data); +#endif /* CY82C693_DEBUG_INFO */ + +#endif /* CY82C693_SETDMA_CLOCK */ + return 0; +} + static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) { static ide_hwif_t *primary; @@ -290,6 +401,7 @@ static const struct ide_port_ops cy82c693_port_ops = { static const struct ide_port_info cy82c693_chipset __devinitdata = { .name = DRV_NAME, + .init_chipset = init_chipset_cy82c693, .init_iops = init_iops_cy82c693, .port_ops = &cy82c693_port_ops, .chipset = ide_cy82c693, @@ -331,7 +443,7 @@ static const struct pci_device_id cy82c693_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cy82c693_pci_tbl); -static struct pci_driver cy82c693_pci_driver = { +static struct pci_driver driver = { .name = "Cypress_IDE", .id_table = cy82c693_pci_tbl, .probe = cy82c693_init_one, @@ -342,12 +454,12 @@ static struct pci_driver cy82c693_pci_driver = { static int __init cy82c693_ide_init(void) { - return ide_pci_register_driver(&cy82c693_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit cy82c693_ide_exit(void) { - pci_unregister_driver(&cy82c693_pci_driver); + pci_unregister_driver(&driver); } module_init(cy82c693_ide_init); diff --git a/trunk/drivers/ide/pci/delkin_cb.c b/trunk/drivers/ide/pci/delkin_cb.c index 8689a706f537..83b63b365e51 100644 --- a/trunk/drivers/ide/pci/delkin_cb.c +++ b/trunk/drivers/ide/pci/delkin_cb.c @@ -117,7 +117,7 @@ static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl); -static struct pci_driver delkin_cb_pci_driver = { +static struct pci_driver driver = { .name = "Delkin-ASKA-Workbit Cardbus IDE", .id_table = delkin_cb_pci_tbl, .probe = delkin_cb_probe, @@ -126,12 +126,12 @@ static struct pci_driver delkin_cb_pci_driver = { static int __init delkin_cb_init(void) { - return pci_register_driver(&delkin_cb_pci_driver); + return pci_register_driver(&driver); } static void __exit delkin_cb_exit(void) { - pci_unregister_driver(&delkin_cb_pci_driver); + pci_unregister_driver(&driver); } module_init(delkin_cb_init); diff --git a/trunk/drivers/ide/pci/generic.c b/trunk/drivers/ide/pci/generic.c index 474f96a7c076..092b238cb250 100644 --- a/trunk/drivers/ide/pci/generic.c +++ b/trunk/drivers/ide/pci/generic.c @@ -166,7 +166,7 @@ static const struct pci_device_id generic_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, generic_pci_tbl); -static struct pci_driver generic_pci_driver = { +static struct pci_driver driver = { .name = "PCI_IDE", .id_table = generic_pci_tbl, .probe = generic_init_one, @@ -177,12 +177,12 @@ static struct pci_driver generic_pci_driver = { static int __init generic_ide_init(void) { - return ide_pci_register_driver(&generic_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit generic_ide_exit(void) { - pci_unregister_driver(&generic_pci_driver); + pci_unregister_driver(&driver); } module_init(generic_ide_init); diff --git a/trunk/drivers/ide/pci/hpt34x.c b/trunk/drivers/ide/pci/hpt34x.c index fb1a3aa57f07..644de29f8fe4 100644 --- a/trunk/drivers/ide/pci/hpt34x.c +++ b/trunk/drivers/ide/pci/hpt34x.c @@ -166,7 +166,7 @@ static const struct pci_device_id hpt34x_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl); -static struct pci_driver hpt34x_pci_driver = { +static struct pci_driver driver = { .name = "HPT34x_IDE", .id_table = hpt34x_pci_tbl, .probe = hpt34x_init_one, @@ -177,12 +177,12 @@ static struct pci_driver hpt34x_pci_driver = { static int __init hpt34x_ide_init(void) { - return ide_pci_register_driver(&hpt34x_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit hpt34x_ide_exit(void) { - pci_unregister_driver(&hpt34x_pci_driver); + pci_unregister_driver(&driver); } module_init(hpt34x_ide_init); diff --git a/trunk/drivers/ide/pci/hpt366.c b/trunk/drivers/ide/pci/hpt366.c index 9cf171cb9376..a194022b6a61 100644 --- a/trunk/drivers/ide/pci/hpt366.c +++ b/trunk/drivers/ide/pci/hpt366.c @@ -835,7 +835,7 @@ static int hpt370_dma_end(ide_drive_t *drive) if (dma_stat & 0x01) hpt370_irq_timeout(drive); } - return ide_dma_end(drive); + return __ide_dma_end(drive); } static void hpt370_dma_timeout(ide_drive_t *drive) @@ -863,6 +863,9 @@ static int hpt374_dma_test_irq(ide_drive_t *drive) if (dma_stat & 4) return 1; + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __func__); return 0; } @@ -877,7 +880,7 @@ static int hpt374_dma_end(ide_drive_t *drive) pci_read_config_byte(dev, mcr_addr, &mcr); if (bwsr & mask) pci_write_config_byte(dev, mcr_addr, mcr | 0x30); - return ide_dma_end(drive); + return __ide_dma_end(drive); } /** @@ -1453,7 +1456,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = ide_dma_end, + .dma_end = __ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = hpt366_dma_lost_irq, .dma_timeout = ide_dma_timeout, @@ -1619,7 +1622,7 @@ static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = { }; MODULE_DEVICE_TABLE(pci, hpt366_pci_tbl); -static struct pci_driver hpt366_pci_driver = { +static struct pci_driver driver = { .name = "HPT366_IDE", .id_table = hpt366_pci_tbl, .probe = hpt366_init_one, @@ -1630,12 +1633,12 @@ static struct pci_driver hpt366_pci_driver = { static int __init hpt366_ide_init(void) { - return ide_pci_register_driver(&hpt366_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit hpt366_ide_exit(void) { - pci_unregister_driver(&hpt366_pci_driver); + pci_unregister_driver(&driver); } module_init(hpt366_ide_init); diff --git a/trunk/drivers/ide/pci/it8213.c b/trunk/drivers/ide/pci/it8213.c index 7c2feeb3c5ec..0954ccd08d6f 100644 --- a/trunk/drivers/ide/pci/it8213.c +++ b/trunk/drivers/ide/pci/it8213.c @@ -189,7 +189,7 @@ static const struct pci_device_id it8213_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, it8213_pci_tbl); -static struct pci_driver it8213_pci_driver = { +static struct pci_driver driver = { .name = "ITE8213_IDE", .id_table = it8213_pci_tbl, .probe = it8213_init_one, @@ -200,12 +200,12 @@ static struct pci_driver it8213_pci_driver = { static int __init it8213_ide_init(void) { - return ide_pci_register_driver(&it8213_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit it8213_ide_exit(void) { - pci_unregister_driver(&it8213_pci_driver); + pci_unregister_driver(&driver); } module_init(it8213_ide_init); diff --git a/trunk/drivers/ide/pci/it821x.c b/trunk/drivers/ide/pci/it821x.c index 995e18bb3139..46edd083b348 100644 --- a/trunk/drivers/ide/pci/it821x.c +++ b/trunk/drivers/ide/pci/it821x.c @@ -138,7 +138,8 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing) struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = ide_get_hwifdata(hwif); int channel = hwif->channel; - u8 unit = drive->dn & 1, conf; + int unit = drive->select.b.unit; + u8 conf; /* Program UDMA timing bits */ if(itdev->clock_mode == ATA_66) @@ -167,11 +168,13 @@ static void it821x_clock_strategy(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = ide_get_hwifdata(hwif); - ide_drive_t *pair; - int clock, altclock, sel = 0; - u8 unit = drive->dn & 1, v; - pair = &hwif->drives[1 - unit]; + u8 unit = drive->select.b.unit; + ide_drive_t *pair = &hwif->drives[1-unit]; + + int clock, altclock; + u8 v; + int sel = 0; if(itdev->want[0][0] > itdev->want[1][0]) { clock = itdev->want[0][1]; @@ -237,17 +240,16 @@ static void it821x_clock_strategy(ide_drive_t *drive) static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) { - ide_hwif_t *hwif = drive->hwif; + ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - ide_drive_t *pair; - u8 unit = drive->dn & 1, set_pio = pio; + int unit = drive->select.b.unit; + ide_drive_t *pair = &hwif->drives[1 - unit]; + u8 set_pio = pio; /* Spec says 89 ref driver uses 88 */ static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; - pair = &hwif->drives[1 - unit]; - /* * Compute the best PIO mode we can for a given device. We must * pick a speed that does not cause problems with the other device @@ -284,7 +286,9 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted) ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif); - u8 unit = drive->dn & 1, channel = hwif->channel, conf; + int unit = drive->select.b.unit; + int channel = hwif->channel; + u8 conf; static u16 dma[] = { 0x8866, 0x3222, 0x3121 }; static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY }; @@ -321,7 +325,9 @@ static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted) ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct it821x_dev *itdev = ide_get_hwifdata(hwif); - u8 unit = drive->dn & 1, channel = hwif->channel, conf; + int unit = drive->select.b.unit; + int channel = hwif->channel; + u8 conf; static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 }; static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 }; @@ -363,8 +369,7 @@ static void it821x_dma_start(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - u8 unit = drive->dn & 1; - + int unit = drive->select.b.unit; if(itdev->mwdma[unit] != MWDMA_OFF) it821x_program(drive, itdev->mwdma[unit]); else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10) @@ -384,10 +389,9 @@ static void it821x_dma_start(ide_drive_t *drive) static int it821x_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + int unit = drive->select.b.unit; struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int ret = ide_dma_end(drive); - u8 unit = drive->dn & 1; - + int ret = __ide_dma_end(drive); if(itdev->mwdma[unit] != MWDMA_OFF) it821x_program(drive, itdev->pio[unit]); return ret; @@ -450,7 +454,7 @@ static void it821x_quirkproc(ide_drive_t *drive) * IRQ mask as we may well be in PIO (eg rev 0x10) * for now and we know unmasking is safe on this chipset. */ - drive->dev_flags |= IDE_DFLAG_UNMASK; + drive->unmask = 1; } else { /* * Perform fixups on smart mode. We need to "lose" some @@ -676,7 +680,7 @@ static const struct pci_device_id it821x_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, it821x_pci_tbl); -static struct pci_driver it821x_pci_driver = { +static struct pci_driver driver = { .name = "ITE821x IDE", .id_table = it821x_pci_tbl, .probe = it821x_init_one, @@ -687,12 +691,12 @@ static struct pci_driver it821x_pci_driver = { static int __init it821x_ide_init(void) { - return ide_pci_register_driver(&it821x_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit it821x_ide_exit(void) { - pci_unregister_driver(&it821x_pci_driver); + pci_unregister_driver(&driver); } module_init(it821x_ide_init); diff --git a/trunk/drivers/ide/pci/jmicron.c b/trunk/drivers/ide/pci/jmicron.c index 9a68433cf46d..acd647110648 100644 --- a/trunk/drivers/ide/pci/jmicron.c +++ b/trunk/drivers/ide/pci/jmicron.c @@ -149,7 +149,7 @@ static struct pci_device_id jmicron_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl); -static struct pci_driver jmicron_pci_driver = { +static struct pci_driver driver = { .name = "JMicron IDE", .id_table = jmicron_pci_tbl, .probe = jmicron_init_one, @@ -160,12 +160,12 @@ static struct pci_driver jmicron_pci_driver = { static int __init jmicron_ide_init(void) { - return ide_pci_register_driver(&jmicron_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit jmicron_ide_exit(void) { - pci_unregister_driver(&jmicron_pci_driver); + pci_unregister_driver(&driver); } module_init(jmicron_ide_init); diff --git a/trunk/drivers/ide/pci/ns87415.c b/trunk/drivers/ide/pci/ns87415.c index 13789060f407..53bd645736d9 100644 --- a/trunk/drivers/ide/pci/ns87415.c +++ b/trunk/drivers/ide/pci/ns87415.c @@ -137,7 +137,7 @@ static void __devinit superio_init_iops(struct hwif_s *hwif) static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; /* - * This routine either enables/disables (according to IDE_DFLAG_PRESENT) + * This routine either enables/disables (according to drive->present) * the IRQ associated with the port (HWIF(drive)), * and selects either PIO or DMA handshaking for the next I/O operation. */ @@ -153,15 +153,11 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) /* Adjust IRQ enable bit */ bit = 1 << (8 + hwif->channel); - - if (drive->dev_flags & IDE_DFLAG_PRESENT) - new &= ~bit; - else - new |= bit; + new = drive->present ? (new & ~bit) : (new | bit); /* Select PIO or DMA, DMA may only be selected for one drive/channel. */ - bit = 1 << (20 + (drive->dn & 1) + (hwif->channel << 1)); - other = 1 << (20 + (1 - (drive->dn & 1)) + (hwif->channel << 1)); + bit = 1 << (20 + drive->select.b.unit + (hwif->channel << 1)); + other = 1 << (20 + (1 - drive->select.b.unit) + (hwif->channel << 1)); new = use_dma ? ((new & ~other) | bit) : (new & ~bit); if (new != *old) { @@ -191,8 +187,7 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) static void ns87415_selectproc (ide_drive_t *drive) { - ns87415_prepare_drive(drive, - !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); + ns87415_prepare_drive (drive, drive->using_dma); } static int ns87415_dma_end(ide_drive_t *drive) @@ -339,7 +334,7 @@ static const struct pci_device_id ns87415_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl); -static struct pci_driver ns87415_pci_driver = { +static struct pci_driver driver = { .name = "NS87415_IDE", .id_table = ns87415_pci_tbl, .probe = ns87415_init_one, @@ -350,12 +345,12 @@ static struct pci_driver ns87415_pci_driver = { static int __init ns87415_ide_init(void) { - return ide_pci_register_driver(&ns87415_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit ns87415_ide_exit(void) { - pci_unregister_driver(&ns87415_pci_driver); + pci_unregister_driver(&driver); } module_init(ns87415_ide_init); diff --git a/trunk/drivers/ide/pci/opti621.c b/trunk/drivers/ide/pci/opti621.c index 6048eda3cd61..3de11ddcf863 100644 --- a/trunk/drivers/ide/pci/opti621.c +++ b/trunk/drivers/ide/pci/opti621.c @@ -179,7 +179,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) misc = addr_timings[clk][addr_pio]; /* select Index-0/1 for Register-A/B */ - write_reg(drive->dn & 1, MISC_REG); + write_reg(drive->select.b.unit, MISC_REG); /* set read cycle timings */ write_reg(tim, READ_REG); /* set write cycle timings */ @@ -220,7 +220,7 @@ static const struct pci_device_id opti621_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, opti621_pci_tbl); -static struct pci_driver opti621_pci_driver = { +static struct pci_driver driver = { .name = "Opti621_IDE", .id_table = opti621_pci_tbl, .probe = opti621_init_one, @@ -231,12 +231,12 @@ static struct pci_driver opti621_pci_driver = { static int __init opti621_ide_init(void) { - return ide_pci_register_driver(&opti621_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit opti621_ide_exit(void) { - pci_unregister_driver(&opti621_pci_driver); + pci_unregister_driver(&driver); } module_init(opti621_ide_init); diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index 211ae46e3e0c..9fc59962553b 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -561,7 +561,7 @@ static const struct pci_device_id pdc202new_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl); -static struct pci_driver pdc202new_pci_driver = { +static struct pci_driver driver = { .name = "Promise_IDE", .id_table = pdc202new_pci_tbl, .probe = pdc202new_init_one, @@ -572,12 +572,12 @@ static struct pci_driver pdc202new_pci_driver = { static int __init pdc202new_ide_init(void) { - return ide_pci_register_driver(&pdc202new_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit pdc202new_ide_exit(void) { - pci_unregister_driver(&pdc202new_pci_driver); + pci_unregister_driver(&driver); } module_init(pdc202new_ide_init); diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 799557c25eef..cb6d2a00c514 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -168,7 +168,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) { if (drive->current_speed > XFER_UDMA_2) pdc_old_enable_66MHz_clock(drive->hwif); - if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { + if (drive->media != ide_disk || drive->addressing == 1) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->extra_base - 16; @@ -188,7 +188,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) static int pdc202xx_dma_end(ide_drive_t *drive) { - if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { + if (drive->media != ide_disk || drive->addressing == 1) { ide_hwif_t *hwif = HWIF(drive); unsigned long high_16 = hwif->extra_base - 16; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); @@ -200,7 +200,7 @@ static int pdc202xx_dma_end(ide_drive_t *drive) } if (drive->current_speed > XFER_UDMA_2) pdc_old_disable_66MHz_clock(drive->hwif); - return ide_dma_end(drive); + return __ide_dma_end(drive); } static int pdc202xx_dma_test_irq(ide_drive_t *drive) @@ -333,7 +333,7 @@ static const struct ide_dma_ops pdc20246_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = ide_dma_end, + .dma_end = __ide_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, .dma_lost_irq = pdc202xx_dma_lost_irq, .dma_timeout = pdc202xx_dma_timeout, @@ -426,7 +426,7 @@ static const struct pci_device_id pdc202xx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl); -static struct pci_driver pdc202xx_pci_driver = { +static struct pci_driver driver = { .name = "Promise_Old_IDE", .id_table = pdc202xx_pci_tbl, .probe = pdc202xx_init_one, @@ -437,12 +437,12 @@ static struct pci_driver pdc202xx_pci_driver = { static int __init pdc202xx_ide_init(void) { - return ide_pci_register_driver(&pdc202xx_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit pdc202xx_ide_exit(void) { - pci_unregister_driver(&pdc202xx_pci_driver); + pci_unregister_driver(&driver); } module_init(pdc202xx_ide_init); diff --git a/trunk/drivers/ide/pci/piix.c b/trunk/drivers/ide/pci/piix.c index d63f9fdca76b..a06c03f8e295 100644 --- a/trunk/drivers/ide/pci/piix.c +++ b/trunk/drivers/ide/pci/piix.c @@ -215,26 +215,17 @@ static unsigned int init_chipset_ich(struct pci_dev *dev) } /** - * ich_clear_irq - clear BMDMA status - * @drive: IDE drive + * piix_dma_clear_irq - clear BMDMA status + * @drive: IDE drive to clear * - * ICHx contollers set DMA INTR no matter DMA or PIO. - * BMDMA status might need to be cleared even for - * PIO interrupts to prevent spurious/lost IRQ. + * Called from ide_intr() for PIO interrupts + * to clear BMDMA status as needed by ICHx */ -static void ich_clear_irq(ide_drive_t *drive) +static void piix_dma_clear_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 dma_stat; - /* - * ide_dma_end() needs BMDMA status for error checking. - * So, skip clearing BMDMA status here and leave it - * to ide_dma_end() if this is DMA interrupt. - */ - if (drive->waiting_for_dma || hwif->dma_base == 0) - return; - /* clear the INTR & ERROR bits */ dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); /* Should we force the bit as well ? */ @@ -258,7 +249,6 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ - { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ /* end marker */ @@ -303,16 +293,18 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; } -static const struct ide_port_ops piix_port_ops = { - .set_pio_mode = piix_set_pio_mode, - .set_dma_mode = piix_set_dma_mode, - .cable_detect = piix_cable_detect, -}; +static void __devinit init_hwif_ich(ide_hwif_t *hwif) +{ + init_hwif_piix(hwif); -static const struct ide_port_ops ich_port_ops = { + /* ICHx need to clear the BMDMA status for all interrupts */ + if (hwif->dma_base) + hwif->ide_dma_clear_irq = &piix_dma_clear_irq; +} + +static const struct ide_port_ops piix_port_ops = { .set_pio_mode = piix_set_pio_mode, .set_dma_mode = piix_set_dma_mode, - .clear_irq = ich_clear_irq, .cable_detect = piix_cable_detect, }; @@ -339,9 +331,9 @@ static const struct ide_port_ops ich_port_ops = { { \ .name = DRV_NAME, \ .init_chipset = init_chipset_ich, \ - .init_hwif = init_hwif_piix, \ + .init_hwif = init_hwif_ich, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .port_ops = &ich_port_ops, \ + .port_ops = &piix_port_ops, \ .host_flags = IDE_HFLAGS_PIIX, \ .pio_mask = ATA_PIO4, \ .swdma_mask = ATA_SWDMA2_ONLY, \ @@ -452,7 +444,7 @@ static const struct pci_device_id piix_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, piix_pci_tbl); -static struct pci_driver piix_pci_driver = { +static struct pci_driver driver = { .name = "PIIX_IDE", .id_table = piix_pci_tbl, .probe = piix_init_one, @@ -464,12 +456,12 @@ static struct pci_driver piix_pci_driver = { static int __init piix_ide_init(void) { piix_check_450nx(); - return ide_pci_register_driver(&piix_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit piix_ide_exit(void) { - pci_unregister_driver(&piix_pci_driver); + pci_unregister_driver(&driver); } module_init(piix_ide_init); diff --git a/trunk/drivers/ide/pci/rz1000.c b/trunk/drivers/ide/pci/rz1000.c index 7daf0135cbac..c117a068761b 100644 --- a/trunk/drivers/ide/pci/rz1000.c +++ b/trunk/drivers/ide/pci/rz1000.c @@ -59,7 +59,7 @@ static const struct pci_device_id rz1000_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl); -static struct pci_driver rz1000_pci_driver = { +static struct pci_driver driver = { .name = "RZ1000_IDE", .id_table = rz1000_pci_tbl, .probe = rz1000_init_one, @@ -68,12 +68,12 @@ static struct pci_driver rz1000_pci_driver = { static int __init rz1000_ide_init(void) { - return ide_pci_register_driver(&rz1000_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit rz1000_ide_exit(void) { - pci_unregister_driver(&rz1000_pci_driver); + pci_unregister_driver(&driver); } module_init(rz1000_ide_init); diff --git a/trunk/drivers/ide/pci/sc1200.c b/trunk/drivers/ide/pci/sc1200.c index f1a8758e3a99..bdc1fed41260 100644 --- a/trunk/drivers/ide/pci/sc1200.c +++ b/trunk/drivers/ide/pci/sc1200.c @@ -126,6 +126,7 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); + int unit = drive->select.b.unit; unsigned int reg, timings; unsigned short pci_clock; unsigned int basereg = hwif->channel ? 0x50 : 0x40; @@ -154,7 +155,7 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) else timings = mwdma_timing[pci_clock][mode - XFER_MW_DMA_0]; - if ((drive->dn & 1) == 0) { + if (unit == 0) { /* are we configuring drive0? */ pci_read_config_dword(dev, basereg + 4, ®); timings |= reg & 0x80000000; /* preserve PIO format bit */ pci_write_config_dword(dev, basereg + 4, timings); @@ -215,8 +216,7 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) if (mode != -1) { printk("SC1200: %s: changing (U)DMA mode\n", drive->name); ide_dma_off_quietly(drive); - if (ide_set_dma_mode(drive, mode) == 0 && - (drive->dev_flags & IDE_DFLAG_USING_DMA)) + if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma) hwif->dma_ops->dma_host_set(drive, 1); return; } @@ -328,7 +328,7 @@ static const struct pci_device_id sc1200_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); -static struct pci_driver sc1200_pci_driver = { +static struct pci_driver driver = { .name = "SC1200_IDE", .id_table = sc1200_pci_tbl, .probe = sc1200_init_one, @@ -341,12 +341,12 @@ static struct pci_driver sc1200_pci_driver = { static int __init sc1200_ide_init(void) { - return ide_pci_register_driver(&sc1200_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit sc1200_ide_exit(void) { - pci_unregister_driver(&sc1200_pci_driver); + pci_unregister_driver(&driver); } module_init(sc1200_ide_init); diff --git a/trunk/drivers/ide/pci/scc_pata.c b/trunk/drivers/ide/pci/scc_pata.c index 9ce1d8059921..e92a874b31df 100644 --- a/trunk/drivers/ide/pci/scc_pata.c +++ b/trunk/drivers/ide/pci/scc_pata.c @@ -291,7 +291,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) static void scc_dma_host_set(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; - u8 unit = drive->dn & 1; + u8 unit = (drive->select.b.unit & 0x01); u8 dma_stat = scc_ide_inb(hwif->dma_base + 4); if (on) @@ -353,6 +353,7 @@ static void scc_dma_start(ide_drive_t *drive) /* start DMA */ scc_ide_outb(dma_cmd | 1, hwif->dma_base); + hwif->dma = 1; wmb(); } @@ -373,6 +374,7 @@ static int __scc_dma_end(ide_drive_t *drive) /* purge DMA mappings */ ide_destroy_dmatable(drive); /* verify good DMA status */ + hwif->dma = 0; wmb(); return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; } @@ -509,6 +511,9 @@ static int scc_dma_test_irq(ide_drive_t *drive) if (int_stat & INTSTS_IOIRQS) return 1; + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __func__); return 0; } @@ -705,7 +710,7 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) scc_ide_outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) - scc_ide_outb((tf->device & HIHI) | drive->select, + scc_ide_outb((tf->device & HIHI) | drive->select.all, io_ports->device_addr); } @@ -821,12 +826,6 @@ static void __devinit init_iops_scc(ide_hwif_t *hwif) init_mmio_iops_scc(hwif); } -static int __devinit scc_init_dma(ide_hwif_t *hwif, - const struct ide_port_info *d) -{ - return ide_allocate_dma_engine(hwif); -} - static u8 scc_cable_detect(ide_hwif_t *hwif) { return ATA_CBL_PATA80; @@ -891,7 +890,6 @@ static const struct ide_dma_ops scc_dma_ops = { { \ .name = name_str, \ .init_iops = init_iops_scc, \ - .init_dma = scc_init_dma, \ .init_hwif = init_hwif_scc, \ .tp_ops = &scc_tp_ops, \ .port_ops = &scc_port_ops, \ @@ -929,6 +927,13 @@ static void __devexit scc_remove(struct pci_dev *dev) { struct scc_ports *ports = pci_get_drvdata(dev); struct ide_host *host = ports->host; + ide_hwif_t *hwif = host->ports[0]; + + if (hwif->dmatable_cpu) { + pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_cpu, hwif->dmatable_dma); + hwif->dmatable_cpu = NULL; + } ide_host_remove(host); @@ -944,7 +949,7 @@ static const struct pci_device_id scc_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, scc_pci_tbl); -static struct pci_driver scc_pci_driver = { +static struct pci_driver driver = { .name = "SCC IDE", .id_table = scc_pci_tbl, .probe = scc_init_one, @@ -953,14 +958,14 @@ static struct pci_driver scc_pci_driver = { static int scc_ide_init(void) { - return ide_pci_register_driver(&scc_pci_driver); + return ide_pci_register_driver(&driver); } module_init(scc_ide_init); /* -- No exit code? static void scc_ide_exit(void) { - ide_pci_unregister_driver(&scc_pci_driver); + ide_pci_unregister_driver(&driver); } module_exit(scc_ide_exit); */ diff --git a/trunk/drivers/ide/pci/serverworks.c b/trunk/drivers/ide/pci/serverworks.c index 437bc919dafd..3dff2aea317e 100644 --- a/trunk/drivers/ide/pci/serverworks.c +++ b/trunk/drivers/ide/pci/serverworks.c @@ -153,7 +153,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - u8 unit = drive->dn & 1; + u8 unit = (drive->select.b.unit & 0x01); u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; @@ -443,7 +443,7 @@ static const struct pci_device_id svwks_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); -static struct pci_driver svwks_pci_driver = { +static struct pci_driver driver = { .name = "Serverworks_IDE", .id_table = svwks_pci_tbl, .probe = svwks_init_one, @@ -454,12 +454,12 @@ static struct pci_driver svwks_pci_driver = { static int __init svwks_ide_init(void) { - return ide_pci_register_driver(&svwks_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit svwks_ide_exit(void) { - pci_unregister_driver(&svwks_pci_driver); + pci_unregister_driver(&driver); } module_init(svwks_ide_init); diff --git a/trunk/drivers/ide/pci/sgiioc4.c b/trunk/drivers/ide/pci/sgiioc4.c index dd634541ce36..1017fb4f6317 100644 --- a/trunk/drivers/ide/pci/sgiioc4.c +++ b/trunk/drivers/ide/pci/sgiioc4.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (C) 2008 MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -151,7 +150,7 @@ sgiioc4_clearirq(ide_drive_t * drive) int count = 0; stat = sgiioc4_read_status(hwif); - while ((stat & ATA_BUSY) && (count++ < 100)) { + while ((stat & 0x80) && (count++ < 100)) { udelay(1); stat = sgiioc4_read_status(hwif); } @@ -311,7 +310,7 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif) u8 reg = (u8) readb((void __iomem *) port); if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */ - if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */ + if (reg & 0x51) { /* Not busy...check for interrupt */ unsigned long other_ir = port - 0x110; unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); @@ -339,32 +338,36 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) if (dma_base == 0) return -1; - printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); + printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, + dma_base, dma_base + num_ports - 1); - if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { - printk(KERN_ERR "%s(%s) -- ERROR: addresses 0x%08lx to 0x%08lx " - "already in use\n", __func__, hwif->name, - dma_base, dma_base + num_ports - 1); + if (!request_mem_region(dma_base, num_ports, hwif->name)) { + printk(KERN_ERR + "%s(%s) -- ERROR, Addresses 0x%p to 0x%p " + "ALREADY in use\n", + __func__, hwif->name, (void *) dma_base, + (void *) dma_base + num_ports - 1); return -1; } virt_dma_base = ioremap(dma_base, num_ports); if (virt_dma_base == NULL) { - printk(KERN_ERR "%s(%s) -- ERROR: unable to map addresses " - "0x%lx to 0x%lx\n", __func__, hwif->name, - dma_base, dma_base + num_ports - 1); + printk(KERN_ERR + "%s(%s) -- ERROR, Unable to map addresses 0x%lx to 0x%lx\n", + __func__, hwif->name, dma_base, dma_base + num_ports - 1); goto dma_remap_failure; } hwif->dma_base = (unsigned long) virt_dma_base; - hwif->sg_max_nents = IOC4_PRD_ENTRIES; + hwif->dmatable_cpu = pci_alloc_consistent(dev, + IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, + &hwif->dmatable_dma); - hwif->prd_max_nents = IOC4_PRD_ENTRIES; - hwif->prd_ent_size = IOC4_PRD_BYTES; - - if (ide_allocate_dma_engine(hwif)) + if (!hwif->dmatable_cpu) goto dma_pci_alloc_failure; + hwif->sg_max_nents = IOC4_PRD_ENTRIES; + pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE, (dma_addr_t *)&hwif->extra_base); if (pad) { @@ -372,11 +375,13 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) return 0; } - ide_release_dma_engine(hwif); - - printk(KERN_ERR "%s(%s) -- ERROR: Unable to allocate DMA maps\n", + pci_free_consistent(dev, IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, + hwif->dmatable_cpu, hwif->dmatable_dma); + printk(KERN_INFO + "%s() -- Error! Unable to allocate DMA Maps for drive %s\n", __func__, hwif->name); - printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name); + printk(KERN_INFO + "Changing from DMA to PIO mode for Drive %s\n", hwif->name); dma_pci_alloc_failure: iounmap(virt_dma_base); @@ -612,12 +617,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; cmd_phys_base = bar0 + IOC4_CMD_OFFSET; - if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, - DRV_NAME) == NULL) { - printk(KERN_ERR "%s %s -- ERROR: addresses 0x%08lx to 0x%08lx " - "already in use\n", DRV_NAME, pci_name(dev), - cmd_phys_base, cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); - return -EBUSY; + if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, + DRV_NAME)) { + printk(KERN_ERR + "%s %s: -- ERROR, Addresses " + "0x%p to 0x%p ALREADY in use\n", + DRV_NAME, pci_name(dev), (void *)cmd_phys_base, + (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); + return -ENOMEM; } /* Initialize the IO registers */ diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index eb4faf92c571..174a873b4c64 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -116,14 +116,13 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) { ide_hwif_t *hwif = HWIF(drive); unsigned long base = (unsigned long)hwif->hwif_data; - u8 unit = drive->dn & 1; base += 0xA0 + r; if (hwif->host_flags & IDE_HFLAG_MMIO) base += hwif->channel << 6; else base += hwif->channel << 4; - base |= unit << unit; + base |= drive->select.b.unit << drive->select.b.unit; return base; } @@ -256,7 +255,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); u8 mode = 0; - u8 unit = drive->dn & 1; + u8 unit = drive->select.b.unit; /* trim *taskfile* PIO to the slowest of the master/slave */ if (pair) { @@ -302,9 +301,9 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - unsigned long base = (unsigned long)hwif->hwif_data; u16 ultra = 0, multi = 0; - u8 mode = 0, unit = drive->dn & 1; + u8 mode = 0, unit = drive->select.b.unit; + unsigned long base = (unsigned long)hwif->hwif_data; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); @@ -713,7 +712,7 @@ static const struct ide_dma_ops sil_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, - .dma_end = ide_dma_end, + .dma_end = __ide_dma_end, .dma_test_irq = siimage_dma_test_irq, .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, @@ -830,7 +829,7 @@ static const struct pci_device_id siimage_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, siimage_pci_tbl); -static struct pci_driver siimage_pci_driver = { +static struct pci_driver driver = { .name = "SiI_IDE", .id_table = siimage_pci_tbl, .probe = siimage_init_one, @@ -841,12 +840,12 @@ static struct pci_driver siimage_pci_driver = { static int __init siimage_ide_init(void) { - return ide_pci_register_driver(&siimage_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit siimage_ide_exit(void) { - pci_unregister_driver(&siimage_pci_driver); + pci_unregister_driver(&driver); } module_init(siimage_ide_init); diff --git a/trunk/drivers/ide/pci/sis5513.c b/trunk/drivers/ide/pci/sis5513.c index ad32e18c5ba3..734dd41f1f67 100644 --- a/trunk/drivers/ide/pci/sis5513.c +++ b/trunk/drivers/ide/pci/sis5513.c @@ -605,7 +605,7 @@ static const struct pci_device_id sis5513_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); -static struct pci_driver sis5513_pci_driver = { +static struct pci_driver driver = { .name = "SIS_IDE", .id_table = sis5513_pci_tbl, .probe = sis5513_init_one, @@ -616,12 +616,12 @@ static struct pci_driver sis5513_pci_driver = { static int __init sis5513_ide_init(void) { - return ide_pci_register_driver(&sis5513_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit sis5513_ide_exit(void) { - pci_unregister_driver(&sis5513_pci_driver); + pci_unregister_driver(&driver); } module_init(sis5513_ide_init); diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index 84dc33602ff8..37a6b7bdc040 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -207,7 +207,7 @@ static int sl82c105_dma_end(ide_drive_t *drive) DBG(("%s(drive:%s)\n", __func__, drive->name)); - ret = ide_dma_end(drive); + ret = __ide_dma_end(drive); pci_write_config_word(dev, reg, drive->drive_data); @@ -345,7 +345,7 @@ static const struct pci_device_id sl82c105_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); -static struct pci_driver sl82c105_pci_driver = { +static struct pci_driver driver = { .name = "W82C105_IDE", .id_table = sl82c105_pci_tbl, .probe = sl82c105_init_one, @@ -356,12 +356,12 @@ static struct pci_driver sl82c105_pci_driver = { static int __init sl82c105_ide_init(void) { - return ide_pci_register_driver(&sl82c105_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit sl82c105_ide_exit(void) { - pci_unregister_driver(&sl82c105_pci_driver); + pci_unregister_driver(&driver); } module_init(sl82c105_ide_init); diff --git a/trunk/drivers/ide/pci/slc90e66.c b/trunk/drivers/ide/pci/slc90e66.c index 0f759e4ed779..a9551a13ac57 100644 --- a/trunk/drivers/ide/pci/slc90e66.c +++ b/trunk/drivers/ide/pci/slc90e66.c @@ -154,7 +154,7 @@ static const struct pci_device_id slc90e66_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); -static struct pci_driver slc90e66_pci_driver = { +static struct pci_driver driver = { .name = "SLC90e66_IDE", .id_table = slc90e66_pci_tbl, .probe = slc90e66_init_one, @@ -165,12 +165,12 @@ static struct pci_driver slc90e66_pci_driver = { static int __init slc90e66_ide_init(void) { - return ide_pci_register_driver(&slc90e66_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit slc90e66_ide_exit(void) { - pci_unregister_driver(&slc90e66_pci_driver); + pci_unregister_driver(&driver); } module_init(slc90e66_ide_init); diff --git a/trunk/drivers/ide/pci/tc86c001.c b/trunk/drivers/ide/pci/tc86c001.c index 93e2cce4b296..927277c54ec9 100644 --- a/trunk/drivers/ide/pci/tc86c001.c +++ b/trunk/drivers/ide/pci/tc86c001.c @@ -186,7 +186,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = { .dma_setup = ide_dma_setup, .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = tc86c001_dma_start, - .dma_end = ide_dma_end, + .dma_end = __ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, .dma_timeout = ide_dma_timeout, @@ -245,7 +245,7 @@ static const struct pci_device_id tc86c001_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, tc86c001_pci_tbl); -static struct pci_driver tc86c001_pci_driver = { +static struct pci_driver driver = { .name = "TC86C001", .id_table = tc86c001_pci_tbl, .probe = tc86c001_init_one, @@ -254,12 +254,12 @@ static struct pci_driver tc86c001_pci_driver = { static int __init tc86c001_ide_init(void) { - return ide_pci_register_driver(&tc86c001_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit tc86c001_ide_exit(void) { - pci_unregister_driver(&tc86c001_pci_driver); + pci_unregister_driver(&driver); } module_init(tc86c001_ide_init); diff --git a/trunk/drivers/ide/pci/triflex.c b/trunk/drivers/ide/pci/triflex.c index b6ff40336aa9..be8715dcee05 100644 --- a/trunk/drivers/ide/pci/triflex.c +++ b/trunk/drivers/ide/pci/triflex.c @@ -38,12 +38,13 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - u32 triflex_timings = 0; + u8 channel_offset = hwif->channel ? 0x74 : 0x70; u16 timing = 0; - u8 channel_offset = hwif->channel ? 0x74 : 0x70, unit = drive->dn & 1; - + u32 triflex_timings = 0; + u8 unit = (drive->select.b.unit & 0x01); + pci_read_config_dword(dev, channel_offset, &triflex_timings); - + switch(speed) { case XFER_MW_DMA_2: timing = 0x0103; @@ -113,7 +114,7 @@ static const struct pci_device_id triflex_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); -static struct pci_driver triflex_pci_driver = { +static struct pci_driver driver = { .name = "TRIFLEX_IDE", .id_table = triflex_pci_tbl, .probe = triflex_init_one, @@ -124,12 +125,12 @@ static struct pci_driver triflex_pci_driver = { static int __init triflex_ide_init(void) { - return ide_pci_register_driver(&triflex_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit triflex_ide_exit(void) { - pci_unregister_driver(&triflex_pci_driver); + pci_unregister_driver(&driver); } module_init(triflex_ide_init); diff --git a/trunk/drivers/ide/pci/trm290.c b/trunk/drivers/ide/pci/trm290.c index 75ea61526566..4dfbc6a68b5b 100644 --- a/trunk/drivers/ide/pci/trm290.c +++ b/trunk/drivers/ide/pci/trm290.c @@ -161,7 +161,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) } /* enable IRQ if not probing */ - if (drive->dev_flags & IDE_DFLAG_PRESENT) { + if (drive->present) { reg = inw(hwif->config_data + 3); reg &= 0x13; reg &= ~(1 << hwif->channel); @@ -173,7 +173,7 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) static void trm290_selectproc (ide_drive_t *drive) { - trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); + trm290_prepare_drive(drive, drive->using_dma); } static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) @@ -350,7 +350,7 @@ static const struct pci_device_id trm290_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, trm290_pci_tbl); -static struct pci_driver trm290_pci_driver = { +static struct pci_driver driver = { .name = "TRM290_IDE", .id_table = trm290_pci_tbl, .probe = trm290_init_one, @@ -359,12 +359,12 @@ static struct pci_driver trm290_pci_driver = { static int __init trm290_ide_init(void) { - return ide_pci_register_driver(&trm290_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit trm290_ide_exit(void) { - pci_unregister_driver(&trm290_pci_driver); + pci_unregister_driver(&driver); } module_init(trm290_ide_init); diff --git a/trunk/drivers/ide/pci/via82cxxx.c b/trunk/drivers/ide/pci/via82cxxx.c index 2a812d3207e9..acacdaab69c2 100644 --- a/trunk/drivers/ide/pci/via82cxxx.c +++ b/trunk/drivers/ide/pci/via82cxxx.c @@ -487,7 +487,7 @@ static const struct pci_device_id via_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, via_pci_tbl); -static struct pci_driver via_pci_driver = { +static struct pci_driver driver = { .name = "VIA_IDE", .id_table = via_pci_tbl, .probe = via_init_one, @@ -498,12 +498,12 @@ static struct pci_driver via_pci_driver = { static int __init via_ide_init(void) { - return ide_pci_register_driver(&via_pci_driver); + return ide_pci_register_driver(&driver); } static void __exit via_ide_exit(void) { - pci_unregister_driver(&via_pci_driver); + pci_unregister_driver(&driver); } module_init(via_ide_init); diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index 2e19d6298536..c3432da78d52 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -430,7 +430,10 @@ pmac_ide_selectproc(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - if (drive->dn & 1) + if (pmif == NULL) + return; + + if (drive->select.b.unit & 0x01) writel(pmif->timings[1], PMAC_IDE_REG(IDE_TIMING_CONFIG)); else writel(pmif->timings[0], PMAC_IDE_REG(IDE_TIMING_CONFIG)); @@ -449,7 +452,10 @@ pmac_ide_kauai_selectproc(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - if (drive->dn & 1) { + if (pmif == NULL) + return; + + if (drive->select.b.unit & 0x01) { writel(pmif->timings[1], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG)); writel(pmif->timings[3], PMAC_IDE_REG(IDE_KAUAI_ULTRA_CONFIG)); } else { @@ -469,6 +475,9 @@ pmac_ide_do_update_timings(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); + if (pmif == NULL) + return; + if (pmif->kind == controller_sh_ata6 || pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) @@ -515,8 +524,11 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) unsigned accessTime, recTime; unsigned int cycle_time; + if (pmif == NULL) + return; + /* which drive is it ? */ - timings = &pmif->timings[drive->dn & 1]; + timings = &pmif->timings[drive->select.b.unit & 0x01]; t = *timings; cycle_time = ide_pio_cycle_time(drive, pio); @@ -793,9 +805,9 @@ static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); + int unit = (drive->select.b.unit & 0x01); int ret = 0; u32 *timings, *timings2, tl[2]; - u8 unit = drive->dn & 1; timings = &pmif->timings[unit]; timings2 = &pmif->timings[unit+2]; @@ -954,11 +966,11 @@ static void pmac_ide_init_dev(ide_drive_t *drive) if (pmif->mediabay) { #ifdef CONFIG_PMAC_MEDIABAY if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) { - drive->dev_flags &= ~IDE_DFLAG_NOPROBE; + drive->noprobe = 0; return; } #endif - drive->dev_flags |= IDE_DFLAG_NOPROBE; + drive->noprobe = 1; } } @@ -1523,6 +1535,18 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) return 0; /* revert to PIO for this request */ } +/* Teardown mappings after DMA has completed. */ +static void +pmac_ide_destroy_dmatable (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + + if (hwif->sg_nents) { + ide_destroy_dmatable(drive); + hwif->sg_nents = 0; + } +} + /* * Prepare a DMA transfer. We build the DMA table, adjust the timings for * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion @@ -1534,7 +1558,12 @@ pmac_ide_dma_setup(ide_drive_t *drive) pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); struct request *rq = HWGROUP(drive)->rq; - u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); + u8 unit = (drive->select.b.unit & 0x01); + u8 ata4; + + if (pmif == NULL) + return 1; + ata4 = (pmif->kind == controller_kl_ata4); if (!pmac_ide_build_dmatable(drive, rq)) { ide_map_sg(drive, rq); @@ -1588,15 +1617,17 @@ pmac_ide_dma_end (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; + volatile struct dbdma_regs __iomem *dma; u32 dstat; + + if (pmif == NULL) + return 0; + dma = pmif->dma_regs; drive->waiting_for_dma = 0; dstat = readl(&dma->status); writel(((RUN|WAKE|DEAD) << 16), &dma->control); - - ide_destroy_dmatable(drive); - + pmac_ide_destroy_dmatable(drive); /* verify good dma status. we don't check for ACTIVE beeing 0. We should... * in theory, but with ATAPI decices doing buffer underruns, that would * cause us to disable DMA, which isn't what we want @@ -1616,9 +1647,13 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; + volatile struct dbdma_regs __iomem *dma; unsigned long status, timeout; + if (pmif == NULL) + return 0; + dma = pmif->dma_regs; + /* We have to things to deal with here: * * - The dbdma won't stop if the command was started @@ -1637,6 +1672,9 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) status = readl(&dma->status); if (!(status & ACTIVE)) return 1; + if (!drive->waiting_for_dma) + printk(KERN_WARNING "ide%d, ide_dma_test_irq \ + called while not waiting\n", HWIF(drive)->index); /* If dbdma didn't execute the STOP command yet, the * active bit is still set. We consider that we aren't @@ -1671,9 +1709,14 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); - volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; - unsigned long status = readl(&dma->status); + volatile struct dbdma_regs __iomem *dma; + unsigned long status; + if (pmif == NULL) + return; + dma = pmif->dma_regs; + + status = readl(&dma->status); printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status); } diff --git a/trunk/drivers/ieee1394/csr1212.c b/trunk/drivers/ieee1394/csr1212.c index 5e38a68b8af2..9f95337139e3 100644 --- a/trunk/drivers/ieee1394/csr1212.c +++ b/trunk/drivers/ieee1394/csr1212.c @@ -84,7 +84,7 @@ static const u8 csr1212_key_id_type_map[0x30] = { #define quads_to_bytes(_q) ((_q) * sizeof(u32)) -#define bytes_to_quads(_b) DIV_ROUND_UP(_b, sizeof(u32)) +#define bytes_to_quads(_b) (((_b) + sizeof(u32) - 1) / sizeof(u32)) static void free_keyval(struct csr1212_keyval *kv) { diff --git a/trunk/drivers/ieee1394/dv1394.c b/trunk/drivers/ieee1394/dv1394.c index 2f83543a9dfc..b6eb2cf25914 100644 --- a/trunk/drivers/ieee1394/dv1394.c +++ b/trunk/drivers/ieee1394/dv1394.c @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init) /* default SYT offset is 3 cycles */ init->syt_offset = 3; - if (init->channel > 63) + if ( (init->channel > 63) || (init->channel < 0) ) init->channel = 63; chan_mask = (u64)1 << init->channel; @@ -2296,10 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host) ohci = (struct ti_ohci *)host->hostdata; - device_create(hpsb_protocol_class, NULL, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), - NULL, "dv1394-%d", id); + device_create_drvdata(hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL, + "dv1394-%d", id); dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); diff --git a/trunk/drivers/ieee1394/eth1394.c b/trunk/drivers/ieee1394/eth1394.c index 20128692b339..b166b3575fa6 100644 --- a/trunk/drivers/ieee1394/eth1394.c +++ b/trunk/drivers/ieee1394/eth1394.c @@ -1361,7 +1361,7 @@ static unsigned int ether1394_encapsulate_prep(unsigned int max_payload, hdr->ff.dgl = dgl; adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF]; } - return DIV_ROUND_UP(dg_size, adj_max_payload); + return (dg_size + adj_max_payload - 1) / adj_max_payload; } static unsigned int ether1394_encapsulate(struct sk_buff *skb, diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index 2376b729e876..16240a789650 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -154,6 +154,9 @@ struct host_info { static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env); +static void nodemgr_resume_ne(struct node_entry *ne); +static void nodemgr_remove_ne(struct node_entry *ne); +static struct node_entry *find_entry_by_guid(u64 guid); struct bus_type ieee1394_bus_type = { .name = "ieee1394", @@ -382,6 +385,27 @@ static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver); +static ssize_t fw_set_destroy_node(struct bus_type *bus, const char *buf, size_t count) +{ + struct node_entry *ne; + u64 guid = (u64)simple_strtoull(buf, NULL, 16); + + ne = find_entry_by_guid(guid); + + if (ne == NULL || !ne->in_limbo) + return -EINVAL; + + nodemgr_remove_ne(ne); + + return count; +} +static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf) +{ + return sprintf(buf, "You can destroy in_limbo nodes by writing their GUID to this file\n"); +} +static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node); + + static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count) { @@ -418,6 +442,7 @@ static BUS_ATTR(ignore_drivers, S_IWUSR | S_IRUGO, fw_get_ignore_drivers, fw_set struct bus_attribute *const fw_bus_attrs[] = { + &bus_attr_destroy_node, &bus_attr_rescan, &bus_attr_ignore_drivers, NULL @@ -709,10 +734,10 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) static DEFINE_MUTEX(nodemgr_serialize_remove_uds); -static int match_ne(struct device *dev, void *data) +static int __match_ne(struct device *dev, void *data) { struct unit_directory *ud; - struct node_entry *ne = data; + struct node_entry *ne = (struct node_entry *)data; ud = container_of(dev, struct unit_directory, unit_dev); return ud->ne == ne; @@ -729,7 +754,8 @@ static void nodemgr_remove_uds(struct node_entry *ne) */ mutex_lock(&nodemgr_serialize_remove_uds); for (;;) { - dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne); + dev = class_find_device(&nodemgr_ud_class, NULL, ne, + __match_ne); if (!dev) break; ud = container_of(dev, struct unit_directory, unit_dev); @@ -759,7 +785,7 @@ static void nodemgr_remove_ne(struct node_entry *ne) put_device(dev); } -static int remove_host_dev(struct device *dev, void *data) +static int __nodemgr_remove_host_dev(struct device *dev, void *data) { if (dev->bus == &ieee1394_bus_type) nodemgr_remove_ne(container_of(dev, struct node_entry, @@ -769,7 +795,7 @@ static int remove_host_dev(struct device *dev, void *data) static void nodemgr_remove_host_dev(struct device *dev) { - device_for_each_child(dev, NULL, remove_host_dev); + WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev)); sysfs_remove_link(&dev->kobj, "irm_id"); sysfs_remove_link(&dev->kobj, "busmgr_id"); sysfs_remove_link(&dev->kobj, "host_id"); @@ -804,10 +830,11 @@ static void nodemgr_update_bus_options(struct node_entry *ne) } -static struct node_entry *nodemgr_create_node(octlet_t guid, - struct csr1212_csr *csr, struct hpsb_host *host, - nodeid_t nodeid, unsigned int generation) +static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr *csr, + struct host_info *hi, nodeid_t nodeid, + unsigned int generation) { + struct hpsb_host *host = hi->host; struct node_entry *ne; ne = kzalloc(sizeof(*ne), GFP_KERNEL); @@ -861,10 +888,10 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, return NULL; } -static int match_ne_guid(struct device *dev, void *data) +static int __match_ne_guid(struct device *dev, void *data) { struct node_entry *ne; - u64 *guid = data; + u64 *guid = (u64 *)data; ne = container_of(dev, struct node_entry, node_dev); return ne->guid == *guid; @@ -875,7 +902,8 @@ static struct node_entry *find_entry_by_guid(u64 guid) struct device *dev; struct node_entry *ne; - dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid); + dev = class_find_device(&nodemgr_ne_class, NULL, &guid, + __match_ne_guid); if (!dev) return NULL; ne = container_of(dev, struct node_entry, node_dev); @@ -884,21 +912,21 @@ static struct node_entry *find_entry_by_guid(u64 guid) return ne; } -struct match_nodeid_parameter { +struct match_nodeid_param { struct hpsb_host *host; nodeid_t nodeid; }; -static int match_ne_nodeid(struct device *dev, void *data) +static int __match_ne_nodeid(struct device *dev, void *data) { int found = 0; struct node_entry *ne; - struct match_nodeid_parameter *p = data; + struct match_nodeid_param *param = (struct match_nodeid_param *)data; if (!dev) goto ret; ne = container_of(dev, struct node_entry, node_dev); - if (ne->host == p->host && ne->nodeid == p->nodeid) + if (ne->host == param->host && ne->nodeid == param->nodeid) found = 1; ret: return found; @@ -909,12 +937,13 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, { struct device *dev; struct node_entry *ne; - struct match_nodeid_parameter p; + struct match_nodeid_param param; - p.host = host; - p.nodeid = nodeid; + param.host = host; + param.nodeid = nodeid; - dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid); + dev = class_find_device(&nodemgr_ne_class, NULL, ¶m, + __match_ne_nodeid); if (!dev) return NULL; ne = container_of(dev, struct node_entry, node_dev); @@ -961,7 +990,7 @@ static void nodemgr_register_device(struct node_entry *ne, * immediate unit directories looking for software_id and * software_version entries, in order to get driver autoloading working. */ static struct unit_directory *nodemgr_process_unit_directory - (struct node_entry *ne, struct csr1212_keyval *ud_kv, + (struct host_info *hi, struct node_entry *ne, struct csr1212_keyval *ud_kv, unsigned int *id, struct unit_directory *parent) { struct unit_directory *ud; @@ -1054,7 +1083,7 @@ static struct unit_directory *nodemgr_process_unit_directory nodemgr_register_device(ne, ud, &ne->device); /* process the child unit */ - ud_child = nodemgr_process_unit_directory(ne, kv, id, ud); + ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud); if (ud_child == NULL) break; @@ -1108,7 +1137,7 @@ static struct unit_directory *nodemgr_process_unit_directory } -static void nodemgr_process_root_directory(struct node_entry *ne) +static void nodemgr_process_root_directory(struct host_info *hi, struct node_entry *ne) { unsigned int ud_id = 0; struct csr1212_dentry *dentry; @@ -1128,7 +1157,7 @@ static void nodemgr_process_root_directory(struct node_entry *ne) break; case CSR1212_KV_ID_UNIT: - nodemgr_process_unit_directory(ne, kv, &ud_id, NULL); + nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL); break; case CSR1212_KV_ID_DESCRIPTOR: @@ -1244,7 +1273,8 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver) * the to take whatever actions required. */ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, - nodeid_t nodeid, unsigned int generation) + struct host_info *hi, nodeid_t nodeid, + unsigned int generation) { if (ne->nodeid != nodeid) { HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, @@ -1275,23 +1305,19 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, csr1212_destroy_csr(csr); } + if (ne->in_limbo) + nodemgr_resume_ne(ne); + /* Mark the node current */ ne->generation = generation; +} - if (ne->in_limbo) { - device_remove_file(&ne->device, &dev_attr_ne_in_limbo); - ne->in_limbo = false; - HPSB_DEBUG("Node reactivated: " - "ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", - NODE_BUS_ARGS(ne->host, ne->nodeid), - (unsigned long long)ne->guid); - } -} -static void nodemgr_node_scan_one(struct hpsb_host *host, +static void nodemgr_node_scan_one(struct host_info *hi, nodeid_t nodeid, int generation) { + struct hpsb_host *host = hi->host; struct node_entry *ne; octlet_t guid; struct csr1212_csr *csr; @@ -1347,15 +1373,16 @@ static void nodemgr_node_scan_one(struct hpsb_host *host, } if (!ne) - nodemgr_create_node(guid, csr, host, nodeid, generation); + nodemgr_create_node(guid, csr, hi, nodeid, generation); else - nodemgr_update_node(ne, csr, nodeid, generation); + nodemgr_update_node(ne, csr, hi, nodeid, generation); } -static void nodemgr_node_scan(struct hpsb_host *host, int generation) +static void nodemgr_node_scan(struct host_info *hi, int generation) { int count; + struct hpsb_host *host = hi->host; struct selfid *sid = (struct selfid *)host->topology_map; nodeid_t nodeid = LOCAL_BUS; @@ -1368,26 +1395,89 @@ static void nodemgr_node_scan(struct hpsb_host *host, int generation) nodeid++; continue; } - nodemgr_node_scan_one(host, nodeid++, generation); + nodemgr_node_scan_one(hi, nodeid++, generation); + } +} + +static int __nodemgr_driver_suspend(struct device *dev, void *data) +{ + struct unit_directory *ud; + struct device_driver *drv; + struct node_entry *ne = (struct node_entry *)data; + int error; + + ud = container_of(dev, struct unit_directory, unit_dev); + if (ud->ne == ne) { + drv = get_driver(ud->device.driver); + if (drv) { + error = 1; /* release if suspend is not implemented */ + if (drv->suspend) { + down(&ud->device.sem); + error = drv->suspend(&ud->device, PMSG_SUSPEND); + up(&ud->device.sem); + } + if (error) + device_release_driver(&ud->device); + put_driver(drv); + } + } + + return 0; +} + +static int __nodemgr_driver_resume(struct device *dev, void *data) +{ + struct unit_directory *ud; + struct device_driver *drv; + struct node_entry *ne = (struct node_entry *)data; + + ud = container_of(dev, struct unit_directory, unit_dev); + if (ud->ne == ne) { + drv = get_driver(ud->device.driver); + if (drv) { + if (drv->resume) { + down(&ud->device.sem); + drv->resume(&ud->device); + up(&ud->device.sem); + } + put_driver(drv); + } } + + return 0; } -static void nodemgr_pause_ne(struct node_entry *ne) +static void nodemgr_suspend_ne(struct node_entry *ne) { - HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", + HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); - ne->in_limbo = true; + ne->in_limbo = 1; WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); + + class_for_each_device(&nodemgr_ud_class, NULL, ne, + __nodemgr_driver_suspend); +} + + +static void nodemgr_resume_ne(struct node_entry *ne) +{ + ne->in_limbo = 0; + device_remove_file(&ne->device, &dev_attr_ne_in_limbo); + + class_for_each_device(&nodemgr_ud_class, NULL, ne, + __nodemgr_driver_resume); + HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", + NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); } -static int update_pdrv(struct device *dev, void *data) +static int __nodemgr_update_pdrv(struct device *dev, void *data) { struct unit_directory *ud; struct device_driver *drv; struct hpsb_protocol_driver *pdrv; - struct node_entry *ne = data; + struct node_entry *ne = (struct node_entry *)data; int error; ud = container_of(dev, struct unit_directory, unit_dev); @@ -1413,9 +1503,11 @@ static int update_pdrv(struct device *dev, void *data) static void nodemgr_update_pdrv(struct node_entry *ne) { - class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv); + class_for_each_device(&nodemgr_ud_class, NULL, ne, + __nodemgr_update_pdrv); } + /* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This * seems like an optional service but in the end it is practically mandatory * as a consequence of these clauses. @@ -1443,12 +1535,11 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation) } -static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne, - int generation) +static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) { struct device *dev; - if (ne->host != host || ne->in_limbo) + if (ne->host != hi->host || ne->in_limbo) return; dev = get_device(&ne->device); @@ -1463,40 +1554,40 @@ static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne, * down to the drivers. Otherwise, this is a dead node and we * suspend it. */ if (ne->needs_probe) - nodemgr_process_root_directory(ne); + nodemgr_process_root_directory(hi, ne); else if (ne->generation == generation) nodemgr_update_pdrv(ne); else - nodemgr_pause_ne(ne); + nodemgr_suspend_ne(ne); put_device(dev); } -struct node_probe_parameter { - struct hpsb_host *host; +struct probe_param { + struct host_info *hi; int generation; bool probe_now; }; static int node_probe(struct device *dev, void *data) { - struct node_probe_parameter *p = data; + struct probe_param *p = data; struct node_entry *ne; - if (p->generation != get_hpsb_generation(p->host)) + if (p->generation != get_hpsb_generation(p->hi->host)) return -EAGAIN; ne = container_of(dev, struct node_entry, node_dev); if (ne->needs_probe == p->probe_now) - nodemgr_probe_ne(p->host, ne, p->generation); + nodemgr_probe_ne(p->hi, ne, p->generation); return 0; } -static int nodemgr_node_probe(struct hpsb_host *host, int generation) +static void nodemgr_node_probe(struct host_info *hi, int generation) { - struct node_probe_parameter p; + struct probe_param p; - p.host = host; + p.hi = hi; p.generation = generation; /* * Do some processing of the nodes we've probed. This pulls them @@ -1513,11 +1604,11 @@ static int nodemgr_node_probe(struct hpsb_host *host, int generation) */ p.probe_now = false; if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) - return 0; + return; p.probe_now = true; if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) - return 0; + return; /* * Now let's tell the bus to rescan our devices. This may seem * like overhead, but the driver-model core will only scan a @@ -1529,27 +1620,6 @@ static int nodemgr_node_probe(struct hpsb_host *host, int generation) */ if (bus_rescan_devices(&ieee1394_bus_type) != 0) HPSB_DEBUG("bus_rescan_devices had an error"); - - return 1; -} - -static int remove_nodes_in_limbo(struct device *dev, void *data) -{ - struct node_entry *ne; - - if (dev->bus != &ieee1394_bus_type) - return 0; - - ne = container_of(dev, struct node_entry, device); - if (ne->in_limbo) - nodemgr_remove_ne(ne); - - return 0; -} - -static void nodemgr_remove_nodes_in_limbo(struct hpsb_host *host) -{ - device_for_each_child(&host->device, NULL, remove_nodes_in_limbo); } static int nodemgr_send_resume_packet(struct hpsb_host *host) @@ -1660,9 +1730,10 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles) return 1; } -static int nodemgr_host_thread(void *data) +static int nodemgr_host_thread(void *__hi) { - struct hpsb_host *host = data; + struct host_info *hi = (struct host_info *)__hi; + struct hpsb_host *host = hi->host; unsigned int g, generation = 0; int i, reset_cycles = 0; @@ -1716,48 +1787,36 @@ static int nodemgr_host_thread(void *data) * entries. This does not do the sysfs stuff, since that * would trigger uevents and such, which is a bad idea at * this point. */ - nodemgr_node_scan(host, generation); + nodemgr_node_scan(hi, generation); /* This actually does the full probe, with sysfs * registration. */ - if (!nodemgr_node_probe(host, generation)) - continue; + nodemgr_node_probe(hi, generation); /* Update some of our sysfs symlinks */ nodemgr_update_host_dev_links(host); - - /* Sleep 3 seconds */ - for (i = 3000/200; i; i--) { - msleep_interruptible(200); - if (kthread_should_stop()) - goto exit; - - if (generation != get_hpsb_generation(host)) - break; - } - /* Remove nodes which are gone, unless a bus reset happened */ - if (!i) - nodemgr_remove_nodes_in_limbo(host); } exit: HPSB_VERBOSE("NodeMgr: Exiting thread"); return 0; } -struct per_host_parameter { +struct host_iter_param { void *data; int (*cb)(struct hpsb_host *, void *); }; -static int per_host(struct device *dev, void *data) +static int __nodemgr_for_each_host(struct device *dev, void *data) { struct hpsb_host *host; - struct per_host_parameter *p = data; + struct host_iter_param *hip = (struct host_iter_param *)data; + int error = 0; host = container_of(dev, struct hpsb_host, host_dev); - return p->cb(host, p->data); -} + error = hip->cb(host, hip->data); + return error; +} /** * nodemgr_for_each_host - call a function for each IEEE 1394 host * @data: an address to supply to the callback @@ -1772,11 +1831,15 @@ static int per_host(struct device *dev, void *data) */ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) { - struct per_host_parameter p; + struct host_iter_param hip; + int error; + + hip.cb = cb; + hip.data = data; + error = class_for_each_device(&hpsb_host_class, NULL, &hip, + __nodemgr_for_each_host); - p.cb = cb; - p.data = data; - return class_for_each_device(&hpsb_host_class, NULL, &p, per_host); + return error; } /* The following two convenience functions use a struct node_entry @@ -1830,7 +1893,7 @@ static void nodemgr_add_host(struct hpsb_host *host) return; } hi->host = host; - hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d", + hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d", host->id); if (IS_ERR(hi->thread)) { HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id); diff --git a/trunk/drivers/ieee1394/nodemgr.h b/trunk/drivers/ieee1394/nodemgr.h index 4f287a3561ba..6eb26465a84c 100644 --- a/trunk/drivers/ieee1394/nodemgr.h +++ b/trunk/drivers/ieee1394/nodemgr.h @@ -110,7 +110,7 @@ struct node_entry { struct device node_dev; /* Means this node is not attached anymore */ - bool in_limbo; + int in_limbo; struct csr1212_csr *csr; }; diff --git a/trunk/drivers/ieee1394/raw1394-private.h b/trunk/drivers/ieee1394/raw1394-private.h index 7a225a405987..a06aaad5b448 100644 --- a/trunk/drivers/ieee1394/raw1394-private.h +++ b/trunk/drivers/ieee1394/raw1394-private.h @@ -22,7 +22,6 @@ enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0, struct file_info { struct list_head list; - struct mutex state_mutex; enum { opened, initialized, connected } state; unsigned int protocol_version; diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index 9f19ac492106..6fa9e4a21840 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -2268,8 +2267,6 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, return -EFAULT; } - mutex_lock(&fi->state_mutex); - switch (fi->state) { case opened: retval = state_opened(fi, req); @@ -2284,8 +2281,6 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, break; } - mutex_unlock(&fi->state_mutex); - if (retval < 0) { free_pending_request(req); } else { @@ -2546,148 +2541,128 @@ static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr) static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) { struct file_info *fi = file->private_data; - int ret; - - mutex_lock(&fi->state_mutex); if (fi->iso_state == RAW1394_ISO_INACTIVE) - ret = -EINVAL; - else - ret = dma_region_mmap(&fi->iso_handle->data_buf, file, vma); - - mutex_unlock(&fi->state_mutex); - - return ret; -} - -static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd, - void __user *argp) -{ - switch (cmd) { - case RAW1394_IOC_ISO_XMIT_INIT: - return raw1394_iso_xmit_init(fi, argp); - case RAW1394_IOC_ISO_RECV_INIT: - return raw1394_iso_recv_init(fi, argp); - default: return -EINVAL; - } -} - -static long raw1394_ioctl_recv(struct file_info *fi, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - - switch (cmd) { - case RAW1394_IOC_ISO_RECV_START:{ - int args[3]; - - if (copy_from_user(&args[0], argp, sizeof(args))) - return -EFAULT; - return hpsb_iso_recv_start(fi->iso_handle, - args[0], args[1], args[2]); - } - case RAW1394_IOC_ISO_XMIT_RECV_STOP: - hpsb_iso_stop(fi->iso_handle); - return 0; - case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: - return hpsb_iso_recv_listen_channel(fi->iso_handle, arg); - case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: - return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg); - case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{ - u64 mask; - if (copy_from_user(&mask, argp, sizeof(mask))) - return -EFAULT; - return hpsb_iso_recv_set_channel_mask(fi->iso_handle, - mask); - } - case RAW1394_IOC_ISO_GET_STATUS: - return raw1394_iso_get_status(fi, argp); - case RAW1394_IOC_ISO_RECV_PACKETS: - return raw1394_iso_recv_packets(fi, argp); - case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: - return hpsb_iso_recv_release_packets(fi->iso_handle, arg); - case RAW1394_IOC_ISO_RECV_FLUSH: - return hpsb_iso_recv_flush(fi->iso_handle); - case RAW1394_IOC_ISO_SHUTDOWN: - raw1394_iso_shutdown(fi); - return 0; - case RAW1394_IOC_ISO_QUEUE_ACTIVITY: - queue_rawiso_event(fi); - return 0; - default: - return -EINVAL; - } -} - -static long raw1394_ioctl_xmit(struct file_info *fi, unsigned int cmd, - void __user *argp) -{ - switch (cmd) { - case RAW1394_IOC_ISO_XMIT_START:{ - int args[2]; - - if (copy_from_user(&args[0], argp, sizeof(args))) - return -EFAULT; - return hpsb_iso_xmit_start(fi->iso_handle, - args[0], args[1]); - } - case RAW1394_IOC_ISO_XMIT_SYNC: - return hpsb_iso_xmit_sync(fi->iso_handle); - case RAW1394_IOC_ISO_XMIT_RECV_STOP: - hpsb_iso_stop(fi->iso_handle); - return 0; - case RAW1394_IOC_ISO_GET_STATUS: - return raw1394_iso_get_status(fi, argp); - case RAW1394_IOC_ISO_XMIT_PACKETS: - return raw1394_iso_send_packets(fi, argp); - case RAW1394_IOC_ISO_SHUTDOWN: - raw1394_iso_shutdown(fi); - return 0; - case RAW1394_IOC_ISO_QUEUE_ACTIVITY: - queue_rawiso_event(fi); - return 0; - default: - return -EINVAL; - } + return dma_region_mmap(&fi->iso_handle->data_buf, file, vma); } /* ioctl is only used for rawiso operations */ -static long raw1394_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) +static long do_raw1394_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct file_info *fi = file->private_data; void __user *argp = (void __user *)arg; - long ret; - - /* state-independent commands */ - switch(cmd) { - case RAW1394_IOC_GET_CYCLE_TIMER: - return raw1394_read_cycle_timer(fi, argp); - default: - break; - } - - mutex_lock(&fi->state_mutex); switch (fi->iso_state) { case RAW1394_ISO_INACTIVE: - ret = raw1394_ioctl_inactive(fi, cmd, argp); + switch (cmd) { + case RAW1394_IOC_ISO_XMIT_INIT: + return raw1394_iso_xmit_init(fi, argp); + case RAW1394_IOC_ISO_RECV_INIT: + return raw1394_iso_recv_init(fi, argp); + default: + break; + } break; case RAW1394_ISO_RECV: - ret = raw1394_ioctl_recv(fi, cmd, arg); + switch (cmd) { + case RAW1394_IOC_ISO_RECV_START:{ + /* copy args from user-space */ + int args[3]; + if (copy_from_user + (&args[0], argp, sizeof(args))) + return -EFAULT; + return hpsb_iso_recv_start(fi->iso_handle, + args[0], args[1], + args[2]); + } + case RAW1394_IOC_ISO_XMIT_RECV_STOP: + hpsb_iso_stop(fi->iso_handle); + return 0; + case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: + return hpsb_iso_recv_listen_channel(fi->iso_handle, + arg); + case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: + return hpsb_iso_recv_unlisten_channel(fi->iso_handle, + arg); + case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{ + /* copy the u64 from user-space */ + u64 mask; + if (copy_from_user(&mask, argp, sizeof(mask))) + return -EFAULT; + return hpsb_iso_recv_set_channel_mask(fi-> + iso_handle, + mask); + } + case RAW1394_IOC_ISO_GET_STATUS: + return raw1394_iso_get_status(fi, argp); + case RAW1394_IOC_ISO_RECV_PACKETS: + return raw1394_iso_recv_packets(fi, argp); + case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: + return hpsb_iso_recv_release_packets(fi->iso_handle, + arg); + case RAW1394_IOC_ISO_RECV_FLUSH: + return hpsb_iso_recv_flush(fi->iso_handle); + case RAW1394_IOC_ISO_SHUTDOWN: + raw1394_iso_shutdown(fi); + return 0; + case RAW1394_IOC_ISO_QUEUE_ACTIVITY: + queue_rawiso_event(fi); + return 0; + } break; case RAW1394_ISO_XMIT: - ret = raw1394_ioctl_xmit(fi, cmd, argp); + switch (cmd) { + case RAW1394_IOC_ISO_XMIT_START:{ + /* copy two ints from user-space */ + int args[2]; + if (copy_from_user + (&args[0], argp, sizeof(args))) + return -EFAULT; + return hpsb_iso_xmit_start(fi->iso_handle, + args[0], args[1]); + } + case RAW1394_IOC_ISO_XMIT_SYNC: + return hpsb_iso_xmit_sync(fi->iso_handle); + case RAW1394_IOC_ISO_XMIT_RECV_STOP: + hpsb_iso_stop(fi->iso_handle); + return 0; + case RAW1394_IOC_ISO_GET_STATUS: + return raw1394_iso_get_status(fi, argp); + case RAW1394_IOC_ISO_XMIT_PACKETS: + return raw1394_iso_send_packets(fi, argp); + case RAW1394_IOC_ISO_SHUTDOWN: + raw1394_iso_shutdown(fi); + return 0; + case RAW1394_IOC_ISO_QUEUE_ACTIVITY: + queue_rawiso_event(fi); + return 0; + } break; default: - ret = -EINVAL; break; } - mutex_unlock(&fi->state_mutex); + /* state-independent commands */ + switch(cmd) { + case RAW1394_IOC_GET_CYCLE_TIMER: + return raw1394_read_cycle_timer(fi, argp); + default: + break; + } + return -EINVAL; +} + +static long raw1394_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + long ret; + lock_kernel(); + ret = do_raw1394_ioctl(file, cmd, arg); + unlock_kernel(); return ret; } @@ -2725,7 +2700,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd, !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { infos = compat_ptr(infos32); if (!copy_to_user(&dst->infos, &infos, sizeof infos)) - err = raw1394_ioctl(file, cmd, (unsigned long)dst); + err = do_raw1394_ioctl(file, cmd, (unsigned long)dst); } return err; } @@ -2749,6 +2724,7 @@ static long raw1394_compat_ioctl(struct file *file, void __user *argp = (void __user *)arg; long err; + lock_kernel(); switch (cmd) { /* These requests have same format as long as 'int' has same size. */ case RAW1394_IOC_ISO_RECV_INIT: @@ -2765,7 +2741,7 @@ static long raw1394_compat_ioctl(struct file *file, case RAW1394_IOC_ISO_GET_STATUS: case RAW1394_IOC_ISO_SHUTDOWN: case RAW1394_IOC_ISO_QUEUE_ACTIVITY: - err = raw1394_ioctl(file, cmd, arg); + err = do_raw1394_ioctl(file, cmd, arg); break; /* These request have different format. */ case RAW1394_IOC_ISO_RECV_PACKETS32: @@ -2781,6 +2757,7 @@ static long raw1394_compat_ioctl(struct file *file, err = -EINVAL; break; } + unlock_kernel(); return err; } @@ -2814,7 +2791,6 @@ static int raw1394_open(struct inode *inode, struct file *file) fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */ INIT_LIST_HEAD(&fi->list); - mutex_init(&fi->state_mutex); fi->state = opened; INIT_LIST_HEAD(&fi->req_pending); INIT_LIST_HEAD(&fi->req_complete); @@ -3034,10 +3010,10 @@ static int __init init_raw1394(void) hpsb_register_highlevel(&raw1394_highlevel); if (IS_ERR - (device_create(hpsb_protocol_class, NULL, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16), - NULL, RAW1394_DEVICE_NAME))) { + (device_create_drvdata( + hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), + NULL, RAW1394_DEVICE_NAME))) { ret = -EFAULT; goto out_unreg; } diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index c52f6e6e8af2..1d6ad3435537 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -526,41 +526,26 @@ static void sbp2util_write_doorbell(struct work_struct *work) static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) { + struct sbp2_fwhost_info *hi = lu->hi; struct sbp2_command_info *cmd; - struct device *dmadev = lu->hi->host->device.parent; int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS; for (i = 0; i < orbs; i++) { cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) - goto failed_alloc; - - cmd->command_orb_dma = - dma_map_single(dmadev, &cmd->command_orb, - sizeof(struct sbp2_command_orb), - DMA_TO_DEVICE); - if (dma_mapping_error(dmadev, cmd->command_orb_dma)) - goto failed_orb; - - cmd->sge_dma = - dma_map_single(dmadev, &cmd->scatter_gather_element, - sizeof(cmd->scatter_gather_element), - DMA_TO_DEVICE); - if (dma_mapping_error(dmadev, cmd->sge_dma)) - goto failed_sge; - + return -ENOMEM; + cmd->command_orb_dma = dma_map_single(hi->host->device.parent, + &cmd->command_orb, + sizeof(struct sbp2_command_orb), + DMA_TO_DEVICE); + cmd->sge_dma = dma_map_single(hi->host->device.parent, + &cmd->scatter_gather_element, + sizeof(cmd->scatter_gather_element), + DMA_TO_DEVICE); INIT_LIST_HEAD(&cmd->list); list_add_tail(&cmd->list, &lu->cmd_orb_completed); } return 0; - -failed_sge: - dma_unmap_single(dmadev, cmd->command_orb_dma, - sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); -failed_orb: - kfree(cmd); -failed_alloc: - return -ENOMEM; } static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu, @@ -656,11 +641,24 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb( static void sbp2util_mark_command_completed(struct sbp2_lu *lu, struct sbp2_command_info *cmd) { - if (scsi_sg_count(cmd->Current_SCpnt)) - dma_unmap_sg(lu->ud->ne->host->device.parent, - scsi_sglist(cmd->Current_SCpnt), - scsi_sg_count(cmd->Current_SCpnt), - cmd->Current_SCpnt->sc_data_direction); + struct hpsb_host *host = lu->ud->ne->host; + + if (cmd->cmd_dma) { + if (cmd->dma_type == CMD_DMA_SINGLE) + dma_unmap_single(host->device.parent, cmd->cmd_dma, + cmd->dma_size, cmd->dma_dir); + else if (cmd->dma_type == CMD_DMA_PAGE) + dma_unmap_page(host->device.parent, cmd->cmd_dma, + cmd->dma_size, cmd->dma_dir); + /* XXX: Check for CMD_DMA_NONE bug */ + cmd->dma_type = CMD_DMA_NONE; + cmd->cmd_dma = 0; + } + if (cmd->sge_buffer) { + dma_unmap_sg(host->device.parent, cmd->sge_buffer, + cmd->dma_size, cmd->dma_dir); + cmd->sge_buffer = NULL; + } list_move_tail(&cmd->list, &lu->cmd_orb_completed); } @@ -825,10 +823,6 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud) #endif } - if (dma_get_max_seg_size(hi->host->device.parent) > SBP2_MAX_SEG_SIZE) - BUG_ON(dma_set_max_seg_size(hi->host->device.parent, - SBP2_MAX_SEG_SIZE)); - /* Prevent unloading of the 1394 host */ if (!try_module_get(hi->host->driver->owner)) { SBP2_ERR("failed to get a reference on 1394 host driver"); @@ -1500,65 +1494,84 @@ static int sbp2_agent_reset(struct sbp2_lu *lu, int wait) return 0; } -static int sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, - struct sbp2_fwhost_info *hi, - struct sbp2_command_info *cmd, - unsigned int sg_count, - struct scatterlist *sg, - u32 orb_direction, - enum dma_data_direction dma_dir) +static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, + struct sbp2_fwhost_info *hi, + struct sbp2_command_info *cmd, + unsigned int scsi_use_sg, + struct scatterlist *sg, + u32 orb_direction, + enum dma_data_direction dma_dir) { - struct device *dmadev = hi->host->device.parent; - struct sbp2_unrestricted_page_table *pt; - int i, n; - - n = dma_map_sg(dmadev, sg, sg_count, dma_dir); - if (n == 0) - return -ENOMEM; - + cmd->dma_dir = dma_dir; orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); orb->misc |= ORB_SET_DIRECTION(orb_direction); /* special case if only one element (and less than 64KB in size) */ - if (n == 1) { - orb->misc |= ORB_SET_DATA_SIZE(sg_dma_len(sg)); - orb->data_descriptor_lo = sg_dma_address(sg); - } else { - pt = &cmd->scatter_gather_element[0]; + if (scsi_use_sg == 1 && sg->length <= SBP2_MAX_SG_ELEMENT_LENGTH) { - dma_sync_single_for_cpu(dmadev, cmd->sge_dma, - sizeof(cmd->scatter_gather_element), - DMA_TO_DEVICE); + cmd->dma_size = sg->length; + cmd->dma_type = CMD_DMA_PAGE; + cmd->cmd_dma = dma_map_page(hi->host->device.parent, + sg_page(sg), sg->offset, + cmd->dma_size, cmd->dma_dir); - for_each_sg(sg, sg, n, i) { - pt[i].high = cpu_to_be32(sg_dma_len(sg) << 16); - pt[i].low = cpu_to_be32(sg_dma_address(sg)); - } + orb->data_descriptor_lo = cmd->cmd_dma; + orb->misc |= ORB_SET_DATA_SIZE(cmd->dma_size); - orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1) | - ORB_SET_DATA_SIZE(n); + } else { + struct sbp2_unrestricted_page_table *sg_element = + &cmd->scatter_gather_element[0]; + u32 sg_count, sg_len; + dma_addr_t sg_addr; + int i, count = dma_map_sg(hi->host->device.parent, sg, + scsi_use_sg, dma_dir); + + cmd->dma_size = scsi_use_sg; + cmd->sge_buffer = sg; + + /* use page tables (s/g) */ + orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); orb->data_descriptor_lo = cmd->sge_dma; - dma_sync_single_for_device(dmadev, cmd->sge_dma, - sizeof(cmd->scatter_gather_element), - DMA_TO_DEVICE); + /* loop through and fill out our SBP-2 page tables + * (and split up anything too large) */ + for (i = 0, sg_count = 0; i < count; i++, sg = sg_next(sg)) { + sg_len = sg_dma_len(sg); + sg_addr = sg_dma_address(sg); + while (sg_len) { + sg_element[sg_count].segment_base_lo = sg_addr; + if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { + sg_element[sg_count].length_segment_base_hi = + PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); + sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; + sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; + } else { + sg_element[sg_count].length_segment_base_hi = + PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); + sg_len = 0; + } + sg_count++; + } + } + + orb->misc |= ORB_SET_DATA_SIZE(sg_count); + + sbp2util_cpu_to_be32_buffer(sg_element, + (sizeof(struct sbp2_unrestricted_page_table)) * + sg_count); } - return 0; } -static int sbp2_create_command_orb(struct sbp2_lu *lu, - struct sbp2_command_info *cmd, - struct scsi_cmnd *SCpnt) +static void sbp2_create_command_orb(struct sbp2_lu *lu, + struct sbp2_command_info *cmd, + struct scsi_cmnd *SCpnt) { - struct device *dmadev = lu->hi->host->device.parent; + struct sbp2_fwhost_info *hi = lu->hi; struct sbp2_command_orb *orb = &cmd->command_orb; + u32 orb_direction; unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt); enum dma_data_direction dma_dir = SCpnt->sc_data_direction; - u32 orb_direction; - int ret; - dma_sync_single_for_cpu(dmadev, cmd->command_orb_dma, - sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); /* * Set-up our command ORB. * @@ -1589,21 +1602,15 @@ static int sbp2_create_command_orb(struct sbp2_lu *lu, orb->data_descriptor_hi = 0x0; orb->data_descriptor_lo = 0x0; orb->misc |= ORB_SET_DIRECTION(1); - ret = 0; - } else { - ret = sbp2_prep_command_orb_sg(orb, lu->hi, cmd, - scsi_sg_count(SCpnt), - scsi_sglist(SCpnt), - orb_direction, dma_dir); - } + } else + sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt), + scsi_sglist(SCpnt), + orb_direction, dma_dir); + sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); memset(orb->cdb, 0, sizeof(orb->cdb)); memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len); - - dma_sync_single_for_device(dmadev, cmd->command_orb_dma, - sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); - return ret; } static void sbp2_link_orb_command(struct sbp2_lu *lu, @@ -1617,6 +1624,14 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu, size_t length; unsigned long flags; + dma_sync_single_for_device(hi->host->device.parent, + cmd->command_orb_dma, + sizeof(struct sbp2_command_orb), + DMA_TO_DEVICE); + dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma, + sizeof(cmd->scatter_gather_element), + DMA_TO_DEVICE); + /* check to see if there are any previous orbs to use */ spin_lock_irqsave(&lu->cmd_orb_lock, flags); last_orb = lu->last_orb; @@ -1684,10 +1699,9 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, if (!cmd) return -EIO; - if (sbp2_create_command_orb(lu, cmd, SCpnt)) - return -ENOMEM; - + sbp2_create_command_orb(lu, cmd, SCpnt); sbp2_link_orb_command(lu, cmd); + return 0; } @@ -1775,6 +1789,13 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, else cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo); if (cmd) { + dma_sync_single_for_cpu(hi->host->device.parent, + cmd->command_orb_dma, + sizeof(struct sbp2_command_orb), + DMA_TO_DEVICE); + dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma, + sizeof(cmd->scatter_gather_element), + DMA_TO_DEVICE); /* Grab SCSI command pointers and check status. */ /* * FIXME: If the src field in the status is 1, the ORB DMA must @@ -1891,6 +1912,7 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt, static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status) { + struct sbp2_fwhost_info *hi = lu->hi; struct list_head *lh; struct sbp2_command_info *cmd; unsigned long flags; @@ -1899,6 +1921,13 @@ static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status) while (!list_empty(&lu->cmd_orb_inuse)) { lh = lu->cmd_orb_inuse.next; cmd = list_entry(lh, struct sbp2_command_info, list); + dma_sync_single_for_cpu(hi->host->device.parent, + cmd->command_orb_dma, + sizeof(struct sbp2_command_orb), + DMA_TO_DEVICE); + dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma, + sizeof(cmd->scatter_gather_element), + DMA_TO_DEVICE); sbp2util_mark_command_completed(lu, cmd); if (cmd->Current_SCpnt) { cmd->Current_SCpnt->result = status << 16; @@ -2004,8 +2033,6 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) sdev->start_stop_pwr_cond = 1; if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); - - blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE); return 0; } @@ -2022,6 +2049,7 @@ static void sbp2scsi_slave_destroy(struct scsi_device *sdev) static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) { struct sbp2_lu *lu = (struct sbp2_lu *)SCpnt->device->host->hostdata[0]; + struct sbp2_fwhost_info *hi = lu->hi; struct sbp2_command_info *cmd; unsigned long flags; @@ -2035,6 +2063,14 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) spin_lock_irqsave(&lu->cmd_orb_lock, flags); cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt); if (cmd) { + dma_sync_single_for_cpu(hi->host->device.parent, + cmd->command_orb_dma, + sizeof(struct sbp2_command_orb), + DMA_TO_DEVICE); + dma_sync_single_for_cpu(hi->host->device.parent, + cmd->sge_dma, + sizeof(cmd->scatter_gather_element), + DMA_TO_DEVICE); sbp2util_mark_command_completed(lu, cmd); if (cmd->Current_SCpnt) { cmd->Current_SCpnt->result = DID_ABORT << 16; diff --git a/trunk/drivers/ieee1394/sbp2.h b/trunk/drivers/ieee1394/sbp2.h index c5036f1cc5b0..875428bc8d29 100644 --- a/trunk/drivers/ieee1394/sbp2.h +++ b/trunk/drivers/ieee1394/sbp2.h @@ -139,10 +139,13 @@ struct sbp2_logout_orb { u32 status_fifo_lo; } __attribute__((packed)); +#define PAGE_TABLE_SET_SEGMENT_BASE_HI(v) ((v) & 0xffff) +#define PAGE_TABLE_SET_SEGMENT_LENGTH(v) (((v) & 0xffff) << 16) + struct sbp2_unrestricted_page_table { - __be32 high; - __be32 low; -}; + u32 length_segment_base_hi; + u32 segment_base_lo; +} __attribute__((packed)); #define RESP_STATUS_REQUEST_COMPLETE 0x0 #define RESP_STATUS_TRANSPORT_FAILURE 0x1 @@ -213,18 +216,15 @@ struct sbp2_status_block { #define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e #define SBP2_SW_VERSION_ENTRY 0x00010483 + /* - * The default maximum s/g segment size of a FireWire controller is - * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to - * be quadlet-aligned, we set the length limit to 0xffff & ~3. + * SCSI specific definitions */ -#define SBP2_MAX_SEG_SIZE 0xfffc -/* - * There is no real limitation of the queue depth (i.e. length of the linked +#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 +/* There is no real limitation of the queue depth (i.e. length of the linked * list of command ORBs) at the target. The chosen depth is merely an - * implementation detail of the sbp2 driver. - */ + * implementation detail of the sbp2 driver. */ #define SBP2_MAX_CMDS 8 #define SBP2_SCSI_STATUS_GOOD 0x0 @@ -240,6 +240,12 @@ struct sbp2_status_block { * Representations of commands and devices */ +enum sbp2_dma_types { + CMD_DMA_NONE, + CMD_DMA_PAGE, + CMD_DMA_SINGLE +}; + /* Per SCSI command */ struct sbp2_command_info { struct list_head list; @@ -252,6 +258,11 @@ struct sbp2_command_info { struct sbp2_unrestricted_page_table scatter_gather_element[SG_ALL] __attribute__((aligned(8))); dma_addr_t sge_dma; + void *sge_buffer; + dma_addr_t cmd_dma; + enum sbp2_dma_types dma_type; + unsigned long dma_size; + enum dma_data_direction dma_dir; }; /* Per FireWire host */ diff --git a/trunk/drivers/ieee1394/video1394.c b/trunk/drivers/ieee1394/video1394.c index 679a918a5cc7..25db6e67fa4e 100644 --- a/trunk/drivers/ieee1394/video1394.c +++ b/trunk/drivers/ieee1394/video1394.c @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file *file, if (unlikely(d == NULL)) return -EFAULT; - if (unlikely(v.buffer >= d->num_desc - 1)) { + if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file *file, if (unlikely(d == NULL)) return -EFAULT; - if (unlikely(v.buffer > d->num_desc - 1)) { + if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file *file, d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); if (d == NULL) return -EFAULT; - if (v.buffer >= d->num_desc - 1) { + if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file *file, d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); if (d == NULL) return -EFAULT; - if (v.buffer >= d->num_desc - 1) { + if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -1341,8 +1341,9 @@ static void video1394_add_host (struct hpsb_host *host) hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; - device_create(hpsb_protocol_class, NULL, MKDEV(IEEE1394_MAJOR, minor), - NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + device_create_drvdata(hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, minor), NULL, + "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); } diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index a78d35aecee3..3cab0cedfca2 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -3691,9 +3691,9 @@ static void cm_add_one(struct ib_device *ib_device) cm_dev->ib_device = ib_device; cm_get_ack_delay(cm_dev); - cm_dev->device = device_create(&cm_class, &ib_device->dev, - MKDEV(0, 0), NULL, - "%s", ib_device->name); + cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev, + MKDEV(0, 0), NULL, + "%s", ib_device->name); if (!cm_dev->device) { kfree(cm_dev); return; diff --git a/trunk/drivers/infiniband/core/user_mad.c b/trunk/drivers/infiniband/core/user_mad.c index 8c46f2257098..268a2d23b7c9 100644 --- a/trunk/drivers/infiniband/core/user_mad.c +++ b/trunk/drivers/infiniband/core/user_mad.c @@ -1016,9 +1016,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, if (cdev_add(port->cdev, base_dev + port->dev_num, 1)) goto err_cdev; - port->dev = device_create(umad_class, device->dma_device, - port->cdev->dev, port, - "umad%d", port->dev_num); + port->dev = device_create_drvdata(umad_class, device->dma_device, + port->cdev->dev, port, + "umad%d", port->dev_num); if (IS_ERR(port->dev)) goto err_cdev; @@ -1036,9 +1036,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) goto err_sm_cdev; - port->sm_dev = device_create(umad_class, device->dma_device, - port->sm_cdev->dev, port, - "issm%d", port->dev_num); + port->sm_dev = device_create_drvdata(umad_class, device->dma_device, + port->sm_cdev->dev, port, + "issm%d", port->dev_num); if (IS_ERR(port->sm_dev)) goto err_sm_cdev; diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index d85af1b67027..aeee856c4060 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/drivers/infiniband/core/uverbs_main.c @@ -764,9 +764,12 @@ static void ib_uverbs_add_one(struct ib_device *device) if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) goto err_cdev; - uverbs_dev->dev = device_create(uverbs_class, device->dma_device, - uverbs_dev->cdev->dev, uverbs_dev, - "uverbs%d", uverbs_dev->devnum); + uverbs_dev->dev = device_create_drvdata(uverbs_class, + device->dma_device, + uverbs_dev->cdev->dev, + uverbs_dev, + "uverbs%d", + uverbs_dev->devnum); if (IS_ERR(uverbs_dev->dev)) goto err_cdev; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c b/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c index 1af1f3a907c6..56c0eda3c077 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -2455,7 +2455,7 @@ static int init_cdev(int minor, char *name, const struct file_operations *fops, goto err_cdev; } - device = device_create(ipath_class, NULL, dev, NULL, name); + device = device_create_drvdata(ipath_class, NULL, dev, NULL, name); if (IS_ERR(device)) { ret = PTR_ERR(device); diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index 5b8b533f2908..ed7c5f72cb8b 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -1683,7 +1683,7 @@ enum { SRP_OPT_SERVICE_ID), }; -static const match_table_t srp_opt_tokens = { +static match_table_t srp_opt_tokens = { { SRP_OPT_ID_EXT, "id_ext=%s" }, { SRP_OPT_IOC_GUID, "ioc_guid=%s" }, { SRP_OPT_DGID, "dgid=%s" }, diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c index 2880eaae157a..078e4eed0894 100644 --- a/trunk/drivers/input/gameport/gameport.c +++ b/trunk/drivers/input/gameport/gameport.c @@ -231,7 +231,6 @@ static void gameport_find_driver(struct gameport *gameport) enum gameport_event_type { GAMEPORT_REGISTER_PORT, GAMEPORT_REGISTER_DRIVER, - GAMEPORT_ATTACH_DRIVER, }; struct gameport_event { @@ -246,12 +245,11 @@ static LIST_HEAD(gameport_event_list); static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); static struct task_struct *gameport_task; -static int gameport_queue_event(void *object, struct module *owner, - enum gameport_event_type event_type) +static void gameport_queue_event(void *object, struct module *owner, + enum gameport_event_type event_type) { unsigned long flags; struct gameport_event *event; - int retval = 0; spin_lock_irqsave(&gameport_event_lock, flags); @@ -270,34 +268,24 @@ static int gameport_queue_event(void *object, struct module *owner, } } - event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); - if (!event) { - printk(KERN_ERR - "gameport: Not enough memory to queue event %d\n", - event_type); - retval = -ENOMEM; - goto out; - } - - if (!try_module_get(owner)) { - printk(KERN_WARNING - "gameport: Can't get module reference, dropping event %d\n", - event_type); - kfree(event); - retval = -EINVAL; - goto out; - } - - event->type = event_type; - event->object = object; - event->owner = owner; + if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) { + if (!try_module_get(owner)) { + printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type); + kfree(event); + goto out; + } - list_add_tail(&event->node, &gameport_event_list); - wake_up(&gameport_wait); + event->type = event_type; + event->object = object; + event->owner = owner; + list_add_tail(&event->node, &gameport_event_list); + wake_up(&gameport_wait); + } else { + printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type); + } out: spin_unlock_irqrestore(&gameport_event_lock, flags); - return retval; } static void gameport_free_event(struct gameport_event *event) @@ -390,10 +378,9 @@ static void gameport_handle_event(void) } /* - * Remove all events that have been submitted for a given object, - * be it a gameport port or a driver. + * Remove all events that have been submitted for a given gameport port. */ -static void gameport_remove_pending_events(void *object) +static void gameport_remove_pending_events(struct gameport *gameport) { struct list_head *node, *next; struct gameport_event *event; @@ -403,7 +390,7 @@ static void gameport_remove_pending_events(void *object) list_for_each_safe(node, next, &gameport_event_list) { event = list_entry(node, struct gameport_event, node); - if (event->object == object) { + if (event->object == gameport) { list_del_init(node); gameport_free_event(event); } @@ -718,40 +705,10 @@ static void gameport_add_driver(struct gameport_driver *drv) drv->driver.name, error); } -int __gameport_register_driver(struct gameport_driver *drv, struct module *owner, - const char *mod_name) +void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) { - int error; - drv->driver.bus = &gameport_bus; - drv->driver.owner = owner; - drv->driver.mod_name = mod_name; - - /* - * Temporarily disable automatic binding because probing - * takes long time and we are better off doing it in kgameportd - */ - drv->ignore = 1; - - error = driver_register(&drv->driver); - if (error) { - printk(KERN_ERR - "gameport: driver_register() failed for %s, error: %d\n", - drv->driver.name, error); - return error; - } - - /* - * Reset ignore flag and let kgameportd bind the driver to free ports - */ - drv->ignore = 0; - error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER); - if (error) { - driver_unregister(&drv->driver); - return error; - } - - return 0; + gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER); } void gameport_unregister_driver(struct gameport_driver *drv) @@ -759,9 +716,7 @@ void gameport_unregister_driver(struct gameport_driver *drv) struct gameport *gameport; mutex_lock(&gameport_mutex); - drv->ignore = 1; /* so gameport_find_driver ignores it */ - gameport_remove_pending_events(drv); start_over: list_for_each_entry(gameport, &gameport_list, node) { @@ -774,7 +729,6 @@ void gameport_unregister_driver(struct gameport_driver *drv) } driver_unregister(&drv->driver); - mutex_unlock(&gameport_mutex); } diff --git a/trunk/drivers/input/joystick/a3d.c b/trunk/drivers/input/joystick/a3d.c index 6489f4010c4f..92498d470b1f 100644 --- a/trunk/drivers/input/joystick/a3d.c +++ b/trunk/drivers/input/joystick/a3d.c @@ -414,7 +414,8 @@ static struct gameport_driver a3d_drv = { static int __init a3d_init(void) { - return gameport_register_driver(&a3d_drv); + gameport_register_driver(&a3d_drv); + return 0; } static void __exit a3d_exit(void) diff --git a/trunk/drivers/input/joystick/adi.c b/trunk/drivers/input/joystick/adi.c index 89c4c084d4ad..d1ca8a14950f 100644 --- a/trunk/drivers/input/joystick/adi.c +++ b/trunk/drivers/input/joystick/adi.c @@ -572,7 +572,8 @@ static struct gameport_driver adi_drv = { static int __init adi_init(void) { - return gameport_register_driver(&adi_drv); + gameport_register_driver(&adi_drv); + return 0; } static void __exit adi_exit(void) diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c index 356b3a25efa2..708c5ae13b24 100644 --- a/trunk/drivers/input/joystick/analog.c +++ b/trunk/drivers/input/joystick/analog.c @@ -761,7 +761,9 @@ static struct gameport_driver analog_drv = { static int __init analog_init(void) { analog_parse_options(); - return gameport_register_driver(&analog_drv); + gameport_register_driver(&analog_drv); + + return 0; } static void __exit analog_exit(void) diff --git a/trunk/drivers/input/joystick/cobra.c b/trunk/drivers/input/joystick/cobra.c index 3497b87c3d05..639b975a8ed7 100644 --- a/trunk/drivers/input/joystick/cobra.c +++ b/trunk/drivers/input/joystick/cobra.c @@ -263,7 +263,8 @@ static struct gameport_driver cobra_drv = { static int __init cobra_init(void) { - return gameport_register_driver(&cobra_drv); + gameport_register_driver(&cobra_drv); + return 0; } static void __exit cobra_exit(void) diff --git a/trunk/drivers/input/joystick/gf2k.c b/trunk/drivers/input/joystick/gf2k.c index 67c207f5b1a1..cb6eef1f2d99 100644 --- a/trunk/drivers/input/joystick/gf2k.c +++ b/trunk/drivers/input/joystick/gf2k.c @@ -375,7 +375,8 @@ static struct gameport_driver gf2k_drv = { static int __init gf2k_init(void) { - return gameport_register_driver(&gf2k_drv); + gameport_register_driver(&gf2k_drv); + return 0; } static void __exit gf2k_exit(void) diff --git a/trunk/drivers/input/joystick/grip.c b/trunk/drivers/input/joystick/grip.c index fc55899ba6c5..684e07cfccc8 100644 --- a/trunk/drivers/input/joystick/grip.c +++ b/trunk/drivers/input/joystick/grip.c @@ -426,7 +426,8 @@ static struct gameport_driver grip_drv = { static int __init grip_init(void) { - return gameport_register_driver(&grip_drv); + gameport_register_driver(&grip_drv); + return 0; } static void __exit grip_exit(void) diff --git a/trunk/drivers/input/joystick/grip_mp.c b/trunk/drivers/input/joystick/grip_mp.c index 2d47baf47769..8279481b16e7 100644 --- a/trunk/drivers/input/joystick/grip_mp.c +++ b/trunk/drivers/input/joystick/grip_mp.c @@ -689,7 +689,8 @@ static struct gameport_driver grip_drv = { static int __init grip_init(void) { - return gameport_register_driver(&grip_drv); + gameport_register_driver(&grip_drv); + return 0; } static void __exit grip_exit(void) diff --git a/trunk/drivers/input/joystick/guillemot.c b/trunk/drivers/input/joystick/guillemot.c index 4058d4b272fe..25ec3fad9f27 100644 --- a/trunk/drivers/input/joystick/guillemot.c +++ b/trunk/drivers/input/joystick/guillemot.c @@ -283,7 +283,8 @@ static struct gameport_driver guillemot_drv = { static int __init guillemot_init(void) { - return gameport_register_driver(&guillemot_drv); + gameport_register_driver(&guillemot_drv); + return 0; } static void __exit guillemot_exit(void) diff --git a/trunk/drivers/input/joystick/interact.c b/trunk/drivers/input/joystick/interact.c index 2478289aeeea..8c3290b68205 100644 --- a/trunk/drivers/input/joystick/interact.c +++ b/trunk/drivers/input/joystick/interact.c @@ -317,7 +317,8 @@ static struct gameport_driver interact_drv = { static int __init interact_init(void) { - return gameport_register_driver(&interact_drv); + gameport_register_driver(&interact_drv); + return 0; } static void __exit interact_exit(void) diff --git a/trunk/drivers/input/joystick/joydump.c b/trunk/drivers/input/joystick/joydump.c index cd894a0564a2..2a1b82c8b31c 100644 --- a/trunk/drivers/input/joystick/joydump.c +++ b/trunk/drivers/input/joystick/joydump.c @@ -161,7 +161,8 @@ static struct gameport_driver joydump_drv = { static int __init joydump_init(void) { - return gameport_register_driver(&joydump_drv); + gameport_register_driver(&joydump_drv); + return 0; } static void __exit joydump_exit(void) diff --git a/trunk/drivers/input/joystick/sidewinder.c b/trunk/drivers/input/joystick/sidewinder.c index ca13a6bec33e..7b4865fdee54 100644 --- a/trunk/drivers/input/joystick/sidewinder.c +++ b/trunk/drivers/input/joystick/sidewinder.c @@ -818,7 +818,8 @@ static struct gameport_driver sw_drv = { static int __init sw_init(void) { - return gameport_register_driver(&sw_drv); + gameport_register_driver(&sw_drv); + return 0; } static void __exit sw_exit(void) diff --git a/trunk/drivers/input/joystick/tmdc.c b/trunk/drivers/input/joystick/tmdc.c index d6c609807115..60c37bcb938d 100644 --- a/trunk/drivers/input/joystick/tmdc.c +++ b/trunk/drivers/input/joystick/tmdc.c @@ -438,7 +438,8 @@ static struct gameport_driver tmdc_drv = { static int __init tmdc_init(void) { - return gameport_register_driver(&tmdc_drv); + gameport_register_driver(&tmdc_drv); + return 0; } static void __exit tmdc_exit(void) diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/input/joystick/xpad.c index 839d1c9622f6..6791be81eb29 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/input/joystick/xpad.c @@ -455,10 +455,10 @@ static void xpad_bulk_out(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, urb->status); + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); break; default: - dbg("%s - nonzero urb status received: %d", __func__, urb->status); + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); } } diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 22016ca15351..b1ce10f50bcf 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio) } /* - * Most special keys (Fn+F?) on Dell laptops do not generate release + * Most special keys (Fn+F?) on Dell Latitudes do not generate release * events so we have to do it ourselves. */ -static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) +static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd) { const unsigned int forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, @@ -1207,13 +1207,15 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun { struct input_dev *old_dev, *new_dev; unsigned long value; + char *rest; int err; unsigned char old_extra, old_set; if (!atkbd->write) return -EIO; - if (strict_strtoul(buf, 10, &value) || value > 1) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) return -EINVAL; if (atkbd->extra != value) { @@ -1262,10 +1264,12 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou { struct input_dev *old_dev, *new_dev; unsigned long value; + char *rest; int err; unsigned char old_scroll; - if (strict_strtoul(buf, 10, &value) || value > 1) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) return -EINVAL; if (atkbd->scroll != value) { @@ -1306,13 +1310,15 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) { struct input_dev *old_dev, *new_dev; unsigned long value; + char *rest; int err; unsigned char old_set, old_extra; if (!atkbd->write) return -EIO; - if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3)) + value = simple_strtoul(buf, &rest, 10); + if (*rest || (value != 2 && value != 3)) return -EINVAL; if (atkbd->set != value) { @@ -1355,13 +1361,15 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t { struct input_dev *old_dev, *new_dev; unsigned long value; + char *rest; int err; unsigned char old_softrepeat, old_softraw; if (!atkbd->write) return -EIO; - if (strict_strtoul(buf, 10, &value) || value > 1) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) return -EINVAL; if (atkbd->softrepeat != value) { @@ -1405,10 +1413,12 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co { struct input_dev *old_dev, *new_dev; unsigned long value; + char *rest; int err; unsigned char old_softraw; - if (strict_strtoul(buf, 10, &value) || value > 1) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) return -EINVAL; if (atkbd->softraw != value) { @@ -1451,13 +1461,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id) static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { { - .ident = "Dell Laptop", + .ident = "Dell Latitude series", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), }, .callback = atkbd_setup_fixup, - .driver_data = atkbd_dell_laptop_keymap_fixup, + .driver_data = atkbd_latitude_keymap_fixup, }, { .ident = "HP 2133", diff --git a/trunk/drivers/input/keyboard/bf54x-keys.c b/trunk/drivers/input/keyboard/bf54x-keys.c index 19284016e0f4..e348cfccc17a 100644 --- a/trunk/drivers/input/keyboard/bf54x-keys.c +++ b/trunk/drivers/input/keyboard/bf54x-keys.c @@ -8,7 +8,7 @@ * * * Modified: - * Copyright 2007-2008 Analog Devices Inc. + * Copyright 2007 Analog Devices Inc. * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * @@ -81,9 +81,6 @@ struct bf54x_kpad { unsigned short *keycode; struct timer_list timer; unsigned int keyup_test_jiffies; - unsigned short kpad_msel; - unsigned short kpad_prescale; - unsigned short kpad_ctl; }; static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad, @@ -363,10 +360,6 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state) { struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); - bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL(); - bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE(); - bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL(); - if (device_may_wakeup(&pdev->dev)) enable_irq_wake(bf54x_kpad->irq); @@ -377,10 +370,6 @@ static int bfin_kpad_resume(struct platform_device *pdev) { struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); - bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel); - bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale); - bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl); - if (device_may_wakeup(&pdev->dev)) disable_irq_wake(bf54x_kpad->irq); diff --git a/trunk/drivers/input/keyboard/gpio_keys.c b/trunk/drivers/input/keyboard/gpio_keys.c index 05f3f43582c2..ec96b369dd7a 100644 --- a/trunk/drivers/input/keyboard/gpio_keys.c +++ b/trunk/drivers/input/keyboard/gpio_keys.c @@ -36,10 +36,9 @@ struct gpio_keys_drvdata { struct gpio_button_data data[0]; }; -static void gpio_keys_report_event(struct gpio_button_data *bdata) +static void gpio_keys_report_event(struct gpio_keys_button *button, + struct input_dev *input) { - struct gpio_keys_button *button = bdata->button; - struct input_dev *input = bdata->input; unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; @@ -51,23 +50,34 @@ static void gpio_check_button(unsigned long _data) { struct gpio_button_data *data = (struct gpio_button_data *)_data; - gpio_keys_report_event(data); + gpio_keys_report_event(data->button, data->input); } static irqreturn_t gpio_keys_isr(int irq, void *dev_id) { - struct gpio_button_data *bdata = dev_id; - struct gpio_keys_button *button = bdata->button; + struct platform_device *pdev = dev_id; + struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; + struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); + int i; - BUG_ON(irq != gpio_to_irq(button->gpio)); + for (i = 0; i < pdata->nbuttons; i++) { + struct gpio_keys_button *button = &pdata->buttons[i]; - if (button->debounce_interval) - mod_timer(&bdata->timer, - jiffies + msecs_to_jiffies(button->debounce_interval)); - else - gpio_keys_report_event(bdata); + if (irq == gpio_to_irq(button->gpio)) { + struct gpio_button_data *bdata = &ddata->data[i]; + + if (button->debounce_interval) + mod_timer(&bdata->timer, + jiffies + + msecs_to_jiffies(button->debounce_interval)); + else + gpio_keys_report_event(button, bdata->input); + + return IRQ_HANDLED; + } + } - return IRQ_HANDLED; + return IRQ_NONE; } static int __devinit gpio_keys_probe(struct platform_device *pdev) @@ -141,7 +151,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, button->desc ? button->desc : "gpio_keys", - bdata); + pdev); if (error) { pr_err("gpio-keys: Unable to claim irq %d; error %d\n", irq, error); @@ -168,7 +178,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) fail2: while (--i >= 0) { - free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); + free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); if (pdata->buttons[i].debounce_interval) del_timer_sync(&ddata->data[i].timer); gpio_free(pdata->buttons[i].gpio); @@ -193,7 +203,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) for (i = 0; i < pdata->nbuttons; i++) { int irq = gpio_to_irq(pdata->buttons[i].gpio); - free_irq(irq, &ddata->data[i]); + free_irq(irq, pdev); if (pdata->buttons[i].debounce_interval) del_timer_sync(&ddata->data[i].timer); gpio_free(pdata->buttons[i].gpio); diff --git a/trunk/drivers/input/keyboard/omap-keypad.c b/trunk/drivers/input/keyboard/omap-keypad.c index 69e674ecf19a..dcea87a0bc56 100644 --- a/trunk/drivers/input/keyboard/omap-keypad.c +++ b/trunk/drivers/input/keyboard/omap-keypad.c @@ -62,7 +62,7 @@ struct omap_kp { unsigned int debounce; }; -static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); +DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); static int *keymap; static unsigned int *row_gpios; @@ -72,9 +72,12 @@ static unsigned int *col_gpios; static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value) { int col; - - for (col = 0; col < omap_kp->cols; col++) - gpio_set_value(col_gpios[col], value & (1 << col)); + for (col = 0; col < omap_kp->cols; col++) { + if (value & (1 << col)) + omap_set_gpio_dataout(col_gpios[col], 1); + else + omap_set_gpio_dataout(col_gpios[col], 0); + } } static u8 get_row_gpio_val(struct omap_kp *omap_kp) @@ -83,7 +86,7 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) u8 value = 0; for (row = 0; row < omap_kp->rows; row++) { - if (gpio_get_value(row_gpios[row])) + if (omap_get_gpio_datain(row_gpios[row])) value |= (1 << row); } return value; @@ -330,23 +333,23 @@ static int __init omap_kp_probe(struct platform_device *pdev) if (cpu_is_omap24xx()) { /* Cols: outputs */ for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { - if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { + if (omap_request_gpio(col_gpios[col_idx]) < 0) { printk(KERN_ERR "Failed to request" "GPIO%d for keypad\n", col_gpios[col_idx]); goto err1; } - gpio_direction_output(col_gpios[col_idx], 0); + omap_set_gpio_direction(col_gpios[col_idx], 0); } /* Rows: inputs */ for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { - if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { + if (omap_request_gpio(row_gpios[row_idx]) < 0) { printk(KERN_ERR "Failed to request" "GPIO%d for keypad\n", row_gpios[row_idx]); goto err2; } - gpio_direction_input(row_gpios[row_idx]); + omap_set_gpio_direction(row_gpios[row_idx], 1); } } else { col_idx = 0; @@ -415,10 +418,10 @@ static int __init omap_kp_probe(struct platform_device *pdev) device_remove_file(&pdev->dev, &dev_attr_enable); err2: for (i = row_idx - 1; i >=0; i--) - gpio_free(row_gpios[i]); + omap_free_gpio(row_gpios[i]); err1: for (i = col_idx - 1; i >=0; i--) - gpio_free(col_gpios[i]); + omap_free_gpio(col_gpios[i]); kfree(omap_kp); input_free_device(input_dev); @@ -435,9 +438,9 @@ static int omap_kp_remove(struct platform_device *pdev) if (cpu_is_omap24xx()) { int i; for (i = 0; i < omap_kp->cols; i++) - gpio_free(col_gpios[i]); + omap_free_gpio(col_gpios[i]); for (i = 0; i < omap_kp->rows; i++) { - gpio_free(row_gpios[i]); + omap_free_gpio(row_gpios[i]); free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0); } } else { diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 199055db5082..e99b7882f382 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -180,19 +180,6 @@ config INPUT_YEALINK To compile this driver as a module, choose M here: the module will be called yealink. -config INPUT_CM109 - tristate "C-Media CM109 USB I/O Controller" - depends on EXPERIMENTAL - depends on USB_ARCH_HAS_HCD - select USB - help - Say Y here if you want to enable keyboard and buzzer functions of the - C-Media CM109 usb phones. The audio part is enabled by the generic - usb sound driver, so you might want to enable that as well. - - To compile this driver as a module, choose M here: the module will be - called cm109. - config INPUT_UINPUT tristate "User level driver support" help diff --git a/trunk/drivers/input/misc/Makefile b/trunk/drivers/input/misc/Makefile index d7db2aeb8a98..f48009b52226 100644 --- a/trunk/drivers/input/misc/Makefile +++ b/trunk/drivers/input/misc/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_POWERMATE) += powermate.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o -obj-$(CONFIG_INPUT_CM109) += cm109.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_APANEL) += apanel.o diff --git a/trunk/drivers/input/misc/ati_remote2.c b/trunk/drivers/input/misc/ati_remote2.c index 3c9988dc0e9f..a7fabafbd94c 100644 --- a/trunk/drivers/input/misc/ati_remote2.c +++ b/trunk/drivers/input/misc/ati_remote2.c @@ -1,8 +1,8 @@ /* * ati_remote2 - ATI/Philips USB RF remote driver * - * Copyright (C) 2005-2008 Ville Syrjala - * Copyright (C) 2007-2008 Peter Stokes + * Copyright (C) 2005 Ville Syrjala + * Copyright (C) 2007 Peter Stokes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -12,7 +12,7 @@ #include #define DRIVER_DESC "ATI/Philips USB RF remote driver" -#define DRIVER_VERSION "0.3" +#define DRIVER_VERSION "0.2" MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION); @@ -27,7 +27,7 @@ MODULE_LICENSE("GPL"); * A remote's "channel" may be altered by pressing and holding the "PC" button for * approximately 3 seconds, after which the button will slowly flash the count of the * currently configured "channel", using the numeric keypad enter a number between 1 and - * 16 and then press the "PC" button again, the button will slowly flash the count of the + * 16 and then the "PC" button again, the button will slowly flash the count of the * newly configured "channel". */ @@ -45,25 +45,9 @@ static struct usb_device_id ati_remote2_id_table[] = { }; MODULE_DEVICE_TABLE(usb, ati_remote2_id_table); -static DEFINE_MUTEX(ati_remote2_mutex); - -enum { - ATI_REMOTE2_OPENED = 0x1, - ATI_REMOTE2_SUSPENDED = 0x2, -}; - -enum { - ATI_REMOTE2_AUX1, - ATI_REMOTE2_AUX2, - ATI_REMOTE2_AUX3, - ATI_REMOTE2_AUX4, - ATI_REMOTE2_PC, - ATI_REMOTE2_MODES, -}; - -static const struct { - u8 hw_code; - u16 keycode; +static struct { + int hw_code; + int key_code; } ati_remote2_key_table[] = { { 0x00, KEY_0 }, { 0x01, KEY_1 }, @@ -89,7 +73,6 @@ static const struct { { 0x37, KEY_RECORD }, { 0x38, KEY_DVD }, { 0x39, KEY_TV }, - { 0x3f, KEY_PROG1 }, /* AUX1-AUX4 and PC */ { 0x54, KEY_MENU }, { 0x58, KEY_UP }, { 0x59, KEY_DOWN }, @@ -108,9 +91,15 @@ static const struct { { 0xa9, BTN_LEFT }, { 0xaa, BTN_RIGHT }, { 0xbe, KEY_QUESTION }, - { 0xd0, KEY_EDIT }, { 0xd5, KEY_FRONT }, + { 0xd0, KEY_EDIT }, { 0xf9, KEY_INFO }, + { (0x00 << 8) | 0x3f, KEY_PROG1 }, + { (0x01 << 8) | 0x3f, KEY_PROG2 }, + { (0x02 << 8) | 0x3f, KEY_PROG3 }, + { (0x03 << 8) | 0x3f, KEY_PROG4 }, + { (0x04 << 8) | 0x3f, KEY_PC }, + { 0, KEY_RESERVED } }; struct ati_remote2 { @@ -128,106 +117,46 @@ struct ati_remote2 { char name[64]; char phys[64]; - - /* Each mode (AUX1-AUX4 and PC) can have an independent keymap. */ - u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)]; - - unsigned int flags; }; static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); static void ati_remote2_disconnect(struct usb_interface *interface); -static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message); -static int ati_remote2_resume(struct usb_interface *interface); static struct usb_driver ati_remote2_driver = { .name = "ati_remote2", .probe = ati_remote2_probe, .disconnect = ati_remote2_disconnect, .id_table = ati_remote2_id_table, - .suspend = ati_remote2_suspend, - .resume = ati_remote2_resume, - .supports_autosuspend = 1, }; -static int ati_remote2_submit_urbs(struct ati_remote2 *ar2) +static int ati_remote2_open(struct input_dev *idev) { + struct ati_remote2 *ar2 = input_get_drvdata(idev); int r; r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); if (r) { dev_err(&ar2->intf[0]->dev, - "%s(): usb_submit_urb() = %d\n", __func__, r); + "%s: usb_submit_urb() = %d\n", __func__, r); return r; } r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); if (r) { usb_kill_urb(ar2->urb[0]); dev_err(&ar2->intf[1]->dev, - "%s(): usb_submit_urb() = %d\n", __func__, r); + "%s: usb_submit_urb() = %d\n", __func__, r); return r; } return 0; } -static void ati_remote2_kill_urbs(struct ati_remote2 *ar2) -{ - usb_kill_urb(ar2->urb[1]); - usb_kill_urb(ar2->urb[0]); -} - -static int ati_remote2_open(struct input_dev *idev) -{ - struct ati_remote2 *ar2 = input_get_drvdata(idev); - int r; - - dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); - - r = usb_autopm_get_interface(ar2->intf[0]); - if (r) { - dev_err(&ar2->intf[0]->dev, - "%s(): usb_autopm_get_interface() = %d\n", __func__, r); - goto fail1; - } - - mutex_lock(&ati_remote2_mutex); - - if (!(ar2->flags & ATI_REMOTE2_SUSPENDED)) { - r = ati_remote2_submit_urbs(ar2); - if (r) - goto fail2; - } - - ar2->flags |= ATI_REMOTE2_OPENED; - - mutex_unlock(&ati_remote2_mutex); - - usb_autopm_put_interface(ar2->intf[0]); - - return 0; - - fail2: - mutex_unlock(&ati_remote2_mutex); - usb_autopm_put_interface(ar2->intf[0]); - fail1: - return r; -} - static void ati_remote2_close(struct input_dev *idev) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); - - mutex_lock(&ati_remote2_mutex); - - if (!(ar2->flags & ATI_REMOTE2_SUSPENDED)) - ati_remote2_kill_urbs(ar2); - - ar2->flags &= ~ATI_REMOTE2_OPENED; - - mutex_unlock(&ati_remote2_mutex); + usb_kill_urb(ar2->urb[0]); + usb_kill_urb(ar2->urb[1]); } static void ati_remote2_input_mouse(struct ati_remote2 *ar2) @@ -243,7 +172,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2) mode = data[0] & 0x0F; - if (mode > ATI_REMOTE2_PC) { + if (mode > 4) { dev_err(&ar2->intf[0]->dev, "Unknown mode byte (%02x %02x %02x %02x)\n", data[3], data[2], data[1], data[0]); @@ -262,7 +191,7 @@ static int ati_remote2_lookup(unsigned int hw_code) { int i; - for (i = 0; i < ARRAY_SIZE(ati_remote2_key_table); i++) + for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) if (ati_remote2_key_table[i].hw_code == hw_code) return i; @@ -282,7 +211,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) mode = data[0] & 0x0F; - if (mode > ATI_REMOTE2_PC) { + if (mode > 4) { dev_err(&ar2->intf[1]->dev, "Unknown mode byte (%02x %02x %02x %02x)\n", data[3], data[2], data[1], data[0]); @@ -290,6 +219,10 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) } hw_code = data[2]; + /* + * Mode keys (AUX1-AUX4, PC) all generate the same code byte. + * Use the mode byte to figure out which one was pressed. + */ if (hw_code == 0x3f) { /* * For some incomprehensible reason the mouse pad generates @@ -303,6 +236,8 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) if (data[1] == 0) ar2->mode = mode; + + hw_code |= mode << 8; } if (!((1 << mode) & mode_mask)) @@ -325,8 +260,8 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) case 2: /* repeat */ /* No repeat for mouse buttons. */ - if (ar2->keycode[mode][index] == BTN_LEFT || - ar2->keycode[mode][index] == BTN_RIGHT) + if (ati_remote2_key_table[index].key_code == BTN_LEFT || + ati_remote2_key_table[index].key_code == BTN_RIGHT) return; if (!time_after_eq(jiffies, ar2->jiffies)) @@ -341,7 +276,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) return; } - input_event(idev, EV_KEY, ar2->keycode[mode][index], data[1]); + input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]); input_sync(idev); } @@ -352,7 +287,6 @@ static void ati_remote2_complete_mouse(struct urb *urb) switch (urb->status) { case 0: - usb_mark_last_busy(ar2->udev); ati_remote2_input_mouse(ar2); break; case -ENOENT: @@ -363,7 +297,6 @@ static void ati_remote2_complete_mouse(struct urb *urb) "%s(): urb status = %d\n", __func__, urb->status); return; default: - usb_mark_last_busy(ar2->udev); dev_err(&ar2->intf[0]->dev, "%s(): urb status = %d\n", __func__, urb->status); } @@ -381,7 +314,6 @@ static void ati_remote2_complete_key(struct urb *urb) switch (urb->status) { case 0: - usb_mark_last_busy(ar2->udev); ati_remote2_input_key(ar2); break; case -ENOENT: @@ -392,7 +324,6 @@ static void ati_remote2_complete_key(struct urb *urb) "%s(): urb status = %d\n", __func__, urb->status); return; default: - usb_mark_last_busy(ar2->udev); dev_err(&ar2->intf[1]->dev, "%s(): urb status = %d\n", __func__, urb->status); } @@ -403,60 +334,10 @@ static void ati_remote2_complete_key(struct urb *urb) "%s(): usb_submit_urb() = %d\n", __func__, r); } -static int ati_remote2_getkeycode(struct input_dev *idev, - int scancode, int *keycode) -{ - struct ati_remote2 *ar2 = input_get_drvdata(idev); - int index, mode; - - mode = scancode >> 8; - if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask)) - return -EINVAL; - - index = ati_remote2_lookup(scancode & 0xFF); - if (index < 0) - return -EINVAL; - - *keycode = ar2->keycode[mode][index]; - return 0; -} - -static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) -{ - struct ati_remote2 *ar2 = input_get_drvdata(idev); - int index, mode, old_keycode; - - mode = scancode >> 8; - if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask)) - return -EINVAL; - - index = ati_remote2_lookup(scancode & 0xFF); - if (index < 0) - return -EINVAL; - - if (keycode < KEY_RESERVED || keycode > KEY_MAX) - return -EINVAL; - - old_keycode = ar2->keycode[mode][index]; - ar2->keycode[mode][index] = keycode; - set_bit(keycode, idev->keybit); - - for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { - for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { - if (ar2->keycode[mode][index] == old_keycode) - return 0; - } - } - - clear_bit(old_keycode, idev->keybit); - - return 0; -} - static int ati_remote2_input_init(struct ati_remote2 *ar2) { struct input_dev *idev; - int index, mode, retval; + int i, retval; idev = input_allocate_device(); if (!idev) @@ -469,26 +350,8 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - - for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { - for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { - ar2->keycode[mode][index] = ati_remote2_key_table[index].keycode; - set_bit(ar2->keycode[mode][index], idev->keybit); - } - } - - /* AUX1-AUX4 and PC generate the same scancode. */ - index = ati_remote2_lookup(0x3f); - ar2->keycode[ATI_REMOTE2_AUX1][index] = KEY_PROG1; - ar2->keycode[ATI_REMOTE2_AUX2][index] = KEY_PROG2; - ar2->keycode[ATI_REMOTE2_AUX3][index] = KEY_PROG3; - ar2->keycode[ATI_REMOTE2_AUX4][index] = KEY_PROG4; - ar2->keycode[ATI_REMOTE2_PC][index] = KEY_PC; - set_bit(KEY_PROG1, idev->keybit); - set_bit(KEY_PROG2, idev->keybit); - set_bit(KEY_PROG3, idev->keybit); - set_bit(KEY_PROG4, idev->keybit); - set_bit(KEY_PC, idev->keybit); + for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) + set_bit(ati_remote2_key_table[i].key_code, idev->keybit); idev->rep[REP_DELAY] = 250; idev->rep[REP_PERIOD] = 33; @@ -496,9 +359,6 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) idev->open = ati_remote2_open; idev->close = ati_remote2_close; - idev->getkeycode = ati_remote2_getkeycode; - idev->setkeycode = ati_remote2_setkeycode; - idev->name = ar2->name; idev->phys = ar2->phys; @@ -630,8 +490,6 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d usb_set_intfdata(interface, ar2); - interface->needs_remote_wakeup = 1; - return 0; fail2: @@ -664,57 +522,6 @@ static void ati_remote2_disconnect(struct usb_interface *interface) kfree(ar2); } -static int ati_remote2_suspend(struct usb_interface *interface, - pm_message_t message) -{ - struct ati_remote2 *ar2; - struct usb_host_interface *alt = interface->cur_altsetting; - - if (alt->desc.bInterfaceNumber) - return 0; - - ar2 = usb_get_intfdata(interface); - - dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); - - mutex_lock(&ati_remote2_mutex); - - if (ar2->flags & ATI_REMOTE2_OPENED) - ati_remote2_kill_urbs(ar2); - - ar2->flags |= ATI_REMOTE2_SUSPENDED; - - mutex_unlock(&ati_remote2_mutex); - - return 0; -} - -static int ati_remote2_resume(struct usb_interface *interface) -{ - struct ati_remote2 *ar2; - struct usb_host_interface *alt = interface->cur_altsetting; - int r = 0; - - if (alt->desc.bInterfaceNumber) - return 0; - - ar2 = usb_get_intfdata(interface); - - dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); - - mutex_lock(&ati_remote2_mutex); - - if (ar2->flags & ATI_REMOTE2_OPENED) - r = ati_remote2_submit_urbs(ar2); - - if (!r) - ar2->flags &= ~ATI_REMOTE2_SUSPENDED; - - mutex_unlock(&ati_remote2_mutex); - - return r; -} - static int __init ati_remote2_init(void) { int r; diff --git a/trunk/drivers/input/misc/cm109.c b/trunk/drivers/input/misc/cm109.c deleted file mode 100644 index bce160f4349b..000000000000 --- a/trunk/drivers/input/misc/cm109.c +++ /dev/null @@ -1,882 +0,0 @@ -/* - * Driver for the VoIP USB phones with CM109 chipsets. - * - * Copyright (C) 2007 - 2008 Alfred E. Heggestad - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ - -/* - * Tested devices: - * - Komunikate KIP1000 - * - Genius G-talk - * - Allied-Telesis Corega USBPH01 - * - ... - * - * This driver is based on the yealink.c driver - * - * Thanks to: - * - Authors of yealink.c - * - Thomas Reitmayr - * - Oliver Neukum for good review comments and code - * - Shaun Jackman for Genius G-talk keymap - * - Dmitry Torokhov for valuable input and review - * - * Todo: - * - Read/write EEPROM - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_VERSION "20080805" -#define DRIVER_AUTHOR "Alfred E. Heggestad" -#define DRIVER_DESC "CM109 phone driver" - -static char *phone = "kip1000"; -module_param(phone, charp, S_IRUSR); -MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01}"); - -enum { - /* HID Registers */ - HID_IR0 = 0x00, /* Record/Playback-mute button, Volume up/down */ - HID_IR1 = 0x01, /* GPI, generic registers or EEPROM_DATA0 */ - HID_IR2 = 0x02, /* Generic registers or EEPROM_DATA1 */ - HID_IR3 = 0x03, /* Generic registers or EEPROM_CTRL */ - HID_OR0 = 0x00, /* Mapping control, buzzer, SPDIF (offset 0x04) */ - HID_OR1 = 0x01, /* GPO - General Purpose Output */ - HID_OR2 = 0x02, /* Set GPIO to input/output mode */ - HID_OR3 = 0x03, /* SPDIF status channel or EEPROM_CTRL */ - - /* HID_IR0 */ - RECORD_MUTE = 1 << 3, - PLAYBACK_MUTE = 1 << 2, - VOLUME_DOWN = 1 << 1, - VOLUME_UP = 1 << 0, - - /* HID_OR0 */ - /* bits 7-6 - 0: HID_OR1-2 are used for GPO; HID_OR0, 3 are used for buzzer - and SPDIF - 1: HID_OR0-3 are used as generic HID registers - 2: Values written to HID_OR0-3 are also mapped to MCU_CTRL, - EEPROM_DATA0-1, EEPROM_CTRL (see Note) - 3: Reserved - */ - HID_OR_GPO_BUZ_SPDIF = 0 << 6, - HID_OR_GENERIC_HID_REG = 1 << 6, - HID_OR_MAP_MCU_EEPROM = 2 << 6, - - BUZZER_ON = 1 << 5, - - /* up to 256 normal keys, up to 16 special keys */ - KEYMAP_SIZE = 256 + 16, -}; - -/* CM109 protocol packet */ -struct cm109_ctl_packet { - u8 byte[4]; -} __attribute__ ((packed)); - -enum { USB_PKT_LEN = sizeof(struct cm109_ctl_packet) }; - -/* CM109 device structure */ -struct cm109_dev { - struct input_dev *idev; /* input device */ - struct usb_device *udev; /* usb device */ - struct usb_interface *intf; - - /* irq input channel */ - struct cm109_ctl_packet *irq_data; - dma_addr_t irq_dma; - struct urb *urb_irq; - - /* control output channel */ - struct cm109_ctl_packet *ctl_data; - dma_addr_t ctl_dma; - struct usb_ctrlrequest *ctl_req; - dma_addr_t ctl_req_dma; - struct urb *urb_ctl; - /* - * The 3 bitfields below are protected by ctl_submit_lock. - * They have to be separate since they are accessed from IRQ - * context. - */ - unsigned irq_urb_pending:1; /* irq_urb is in flight */ - unsigned ctl_urb_pending:1; /* ctl_urb is in flight */ - unsigned buzzer_pending:1; /* need to issue buzz command */ - spinlock_t ctl_submit_lock; - - unsigned char buzzer_state; /* on/off */ - - /* flags */ - unsigned open:1; - unsigned resetting:1; - unsigned shutdown:1; - - /* This mutex protects writes to the above flags */ - struct mutex pm_mutex; - - unsigned short keymap[KEYMAP_SIZE]; - - char phys[64]; /* physical device path */ - int key_code; /* last reported key */ - int keybit; /* 0=new scan 1,2,4,8=scan columns */ - u8 gpi; /* Cached value of GPI (high nibble) */ -}; - -/****************************************************************************** - * CM109 key interface - *****************************************************************************/ - -static unsigned short special_keymap(int code) -{ - if (code > 0xff) { - switch (code - 0xff) { - case RECORD_MUTE: return KEY_MUTE; - case PLAYBACK_MUTE: return KEY_MUTE; - case VOLUME_DOWN: return KEY_VOLUMEDOWN; - case VOLUME_UP: return KEY_VOLUMEUP; - } - } - return KEY_RESERVED; -} - -/* Map device buttons to internal key events. - * - * The "up" and "down" keys, are symbolised by arrows on the button. - * The "pickup" and "hangup" keys are symbolised by a green and red phone - * on the button. - - Komunikate KIP1000 Keyboard Matrix - - -> -- 1 -- 2 -- 3 --> GPI pin 4 (0x10) - | | | | - <- -- 4 -- 5 -- 6 --> GPI pin 5 (0x20) - | | | | - END - 7 -- 8 -- 9 --> GPI pin 6 (0x40) - | | | | - OK -- * -- 0 -- # --> GPI pin 7 (0x80) - | | | | - - /|\ /|\ /|\ /|\ - | | | | -GPO -pin: 3 2 1 0 - 0x8 0x4 0x2 0x1 - - */ -static unsigned short keymap_kip1000(int scancode) -{ - switch (scancode) { /* phone key: */ - case 0x82: return KEY_NUMERIC_0; /* 0 */ - case 0x14: return KEY_NUMERIC_1; /* 1 */ - case 0x12: return KEY_NUMERIC_2; /* 2 */ - case 0x11: return KEY_NUMERIC_3; /* 3 */ - case 0x24: return KEY_NUMERIC_4; /* 4 */ - case 0x22: return KEY_NUMERIC_5; /* 5 */ - case 0x21: return KEY_NUMERIC_6; /* 6 */ - case 0x44: return KEY_NUMERIC_7; /* 7 */ - case 0x42: return KEY_NUMERIC_8; /* 8 */ - case 0x41: return KEY_NUMERIC_9; /* 9 */ - case 0x81: return KEY_NUMERIC_POUND; /* # */ - case 0x84: return KEY_NUMERIC_STAR; /* * */ - case 0x88: return KEY_ENTER; /* pickup */ - case 0x48: return KEY_ESC; /* hangup */ - case 0x28: return KEY_LEFT; /* IN */ - case 0x18: return KEY_RIGHT; /* OUT */ - default: return special_keymap(scancode); - } -} - -/* - Contributed by Shaun Jackman - - Genius G-Talk keyboard matrix - 0 1 2 3 - 4: 0 4 8 Talk - 5: 1 5 9 End - 6: 2 6 # Up - 7: 3 7 * Down -*/ -static unsigned short keymap_gtalk(int scancode) -{ - switch (scancode) { - case 0x11: return KEY_NUMERIC_0; - case 0x21: return KEY_NUMERIC_1; - case 0x41: return KEY_NUMERIC_2; - case 0x81: return KEY_NUMERIC_3; - case 0x12: return KEY_NUMERIC_4; - case 0x22: return KEY_NUMERIC_5; - case 0x42: return KEY_NUMERIC_6; - case 0x82: return KEY_NUMERIC_7; - case 0x14: return KEY_NUMERIC_8; - case 0x24: return KEY_NUMERIC_9; - case 0x44: return KEY_NUMERIC_POUND; /* # */ - case 0x84: return KEY_NUMERIC_STAR; /* * */ - case 0x18: return KEY_ENTER; /* Talk (green handset) */ - case 0x28: return KEY_ESC; /* End (red handset) */ - case 0x48: return KEY_UP; /* Menu up (rocker switch) */ - case 0x88: return KEY_DOWN; /* Menu down (rocker switch) */ - default: return special_keymap(scancode); - } -} - -/* - * Keymap for Allied-Telesis Corega USBPH01 - * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html - * - * Contributed by july@nat.bg - */ -static unsigned short keymap_usbph01(int scancode) -{ - switch (scancode) { - case 0x11: return KEY_NUMERIC_0; /* 0 */ - case 0x21: return KEY_NUMERIC_1; /* 1 */ - case 0x41: return KEY_NUMERIC_2; /* 2 */ - case 0x81: return KEY_NUMERIC_3; /* 3 */ - case 0x12: return KEY_NUMERIC_4; /* 4 */ - case 0x22: return KEY_NUMERIC_5; /* 5 */ - case 0x42: return KEY_NUMERIC_6; /* 6 */ - case 0x82: return KEY_NUMERIC_7; /* 7 */ - case 0x14: return KEY_NUMERIC_8; /* 8 */ - case 0x24: return KEY_NUMERIC_9; /* 9 */ - case 0x44: return KEY_NUMERIC_POUND; /* # */ - case 0x84: return KEY_NUMERIC_STAR; /* * */ - case 0x18: return KEY_ENTER; /* pickup */ - case 0x28: return KEY_ESC; /* hangup */ - case 0x48: return KEY_LEFT; /* IN */ - case 0x88: return KEY_RIGHT; /* OUT */ - default: return special_keymap(scancode); - } -} - -static unsigned short (*keymap)(int) = keymap_kip1000; - -/* - * Completes a request by converting the data into events for the - * input subsystem. - */ -static void report_key(struct cm109_dev *dev, int key) -{ - struct input_dev *idev = dev->idev; - - if (dev->key_code >= 0) { - /* old key up */ - input_report_key(idev, dev->key_code, 0); - } - - dev->key_code = key; - if (key >= 0) { - /* new valid key */ - input_report_key(idev, key, 1); - } - - input_sync(idev); -} - -/****************************************************************************** - * CM109 usb communication interface - *****************************************************************************/ - -static void cm109_submit_buzz_toggle(struct cm109_dev *dev) -{ - int error; - - if (dev->buzzer_state) - dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; - else - dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; - - error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC); - if (error) - err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error); -} - -/* - * IRQ handler - */ -static void cm109_urb_irq_callback(struct urb *urb) -{ - struct cm109_dev *dev = urb->context; - const int status = urb->status; - int error; - - dev_dbg(&urb->dev->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n", - dev->irq_data->byte[0], - dev->irq_data->byte[1], - dev->irq_data->byte[2], - dev->irq_data->byte[3], - dev->keybit); - - if (status) { - if (status == -ESHUTDOWN) - return; - err("%s: urb status %d", __func__, status); - } - - /* Special keys */ - if (dev->irq_data->byte[HID_IR0] & 0x0f) { - const int code = (dev->irq_data->byte[HID_IR0] & 0x0f); - report_key(dev, dev->keymap[0xff + code]); - } - - /* Scan key column */ - if (dev->keybit == 0xf) { - - /* Any changes ? */ - if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0)) - goto out; - - dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0; - dev->keybit = 0x1; - } else { - report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]); - - dev->keybit <<= 1; - if (dev->keybit > 0x8) - dev->keybit = 0xf; - } - - out: - - spin_lock(&dev->ctl_submit_lock); - - dev->irq_urb_pending = 0; - - if (likely(!dev->shutdown)) { - - if (dev->buzzer_state) - dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; - else - dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; - - dev->ctl_data->byte[HID_OR1] = dev->keybit; - dev->ctl_data->byte[HID_OR2] = dev->keybit; - - dev->buzzer_pending = 0; - dev->ctl_urb_pending = 1; - - error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC); - if (error) - err("%s: usb_submit_urb (urb_ctl) failed %d", - __func__, error); - } - - spin_unlock(&dev->ctl_submit_lock); -} - -static void cm109_urb_ctl_callback(struct urb *urb) -{ - struct cm109_dev *dev = urb->context; - const int status = urb->status; - int error; - - dev_dbg(&urb->dev->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n", - dev->ctl_data->byte[0], - dev->ctl_data->byte[1], - dev->ctl_data->byte[2], - dev->ctl_data->byte[3]); - - if (status) - err("%s: urb status %d", __func__, status); - - spin_lock(&dev->ctl_submit_lock); - - dev->ctl_urb_pending = 0; - - if (likely(!dev->shutdown)) { - - if (dev->buzzer_pending) { - dev->buzzer_pending = 0; - dev->ctl_urb_pending = 1; - cm109_submit_buzz_toggle(dev); - } else if (likely(!dev->irq_urb_pending)) { - /* ask for key data */ - dev->irq_urb_pending = 1; - error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC); - if (error) - err("%s: usb_submit_urb (urb_irq) failed %d", - __func__, error); - } - } - - spin_unlock(&dev->ctl_submit_lock); -} - -static void cm109_toggle_buzzer_async(struct cm109_dev *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->ctl_submit_lock, flags); - - if (dev->ctl_urb_pending) { - /* URB completion will resubmit */ - dev->buzzer_pending = 1; - } else { - dev->ctl_urb_pending = 1; - cm109_submit_buzz_toggle(dev); - } - - spin_unlock_irqrestore(&dev->ctl_submit_lock, flags); -} - -static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on) -{ - int error; - - if (on) - dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; - else - dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; - - error = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - dev->ctl_req->bRequest, - dev->ctl_req->bRequestType, - le16_to_cpu(dev->ctl_req->wValue), - le16_to_cpu(dev->ctl_req->wIndex), - dev->ctl_data, - USB_PKT_LEN, USB_CTRL_SET_TIMEOUT); - if (error && error != EINTR) - err("%s: usb_control_msg() failed %d", __func__, error); -} - -static void cm109_stop_traffic(struct cm109_dev *dev) -{ - dev->shutdown = 1; - /* - * Make sure other CPUs see this - */ - smp_wmb(); - - usb_kill_urb(dev->urb_ctl); - usb_kill_urb(dev->urb_irq); - - cm109_toggle_buzzer_sync(dev, 0); - - dev->shutdown = 0; - smp_wmb(); -} - -static void cm109_restore_state(struct cm109_dev *dev) -{ - if (dev->open) { - /* - * Restore buzzer state. - * This will also kick regular URB submission - */ - cm109_toggle_buzzer_async(dev); - } -} - -/****************************************************************************** - * input event interface - *****************************************************************************/ - -static int cm109_input_open(struct input_dev *idev) -{ - struct cm109_dev *dev = input_get_drvdata(idev); - int error; - - error = usb_autopm_get_interface(dev->intf); - if (error < 0) { - err("%s - cannot autoresume, result %d", - __func__, error); - return error; - } - - mutex_lock(&dev->pm_mutex); - - dev->buzzer_state = 0; - dev->key_code = -1; /* no keys pressed */ - dev->keybit = 0xf; - - /* issue INIT */ - dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF; - dev->ctl_data->byte[HID_OR1] = dev->keybit; - dev->ctl_data->byte[HID_OR2] = dev->keybit; - dev->ctl_data->byte[HID_OR3] = 0x00; - - error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); - if (error) - err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error); - else - dev->open = 1; - - mutex_unlock(&dev->pm_mutex); - - if (error) - usb_autopm_put_interface(dev->intf); - - return error; -} - -static void cm109_input_close(struct input_dev *idev) -{ - struct cm109_dev *dev = input_get_drvdata(idev); - - mutex_lock(&dev->pm_mutex); - - /* - * Once we are here event delivery is stopped so we - * don't need to worry about someone starting buzzer - * again - */ - cm109_stop_traffic(dev); - dev->open = 0; - - mutex_unlock(&dev->pm_mutex); - - usb_autopm_put_interface(dev->intf); -} - -static int cm109_input_ev(struct input_dev *idev, unsigned int type, - unsigned int code, int value) -{ - struct cm109_dev *dev = input_get_drvdata(idev); - - dev_dbg(&dev->udev->dev, - "input_ev: type=%u code=%u value=%d\n", type, code, value); - - if (type != EV_SND) - return -EINVAL; - - switch (code) { - case SND_TONE: - case SND_BELL: - dev->buzzer_state = !!value; - if (!dev->resetting) - cm109_toggle_buzzer_async(dev); - return 0; - - default: - return -EINVAL; - } -} - - -/****************************************************************************** - * Linux interface and usb initialisation - *****************************************************************************/ - -struct driver_info { - char *name; -}; - -static const struct driver_info info_cm109 = { - .name = "CM109 USB driver", -}; - -enum { - VENDOR_ID = 0x0d8c, /* C-Media Electronics */ - PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */ -}; - -/* table of devices that work with this driver */ -static const struct usb_device_id cm109_usb_table[] = { - { - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = VENDOR_ID, - .idProduct = PRODUCT_ID_CM109, - .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .driver_info = (kernel_ulong_t) &info_cm109 - }, - /* you can add more devices here with product ID 0x0008 - 0x000f */ - { } -}; - -static void cm109_usb_cleanup(struct cm109_dev *dev) -{ - if (dev->ctl_req) - usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)), - dev->ctl_req, dev->ctl_req_dma); - if (dev->ctl_data) - usb_buffer_free(dev->udev, USB_PKT_LEN, - dev->ctl_data, dev->ctl_dma); - if (dev->irq_data) - usb_buffer_free(dev->udev, USB_PKT_LEN, - dev->irq_data, dev->irq_dma); - - usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */ - usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */ - kfree(dev); -} - -static void cm109_usb_disconnect(struct usb_interface *interface) -{ - struct cm109_dev *dev = usb_get_intfdata(interface); - - usb_set_intfdata(interface, NULL); - input_unregister_device(dev->idev); - cm109_usb_cleanup(dev); -} - -static int cm109_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct driver_info *nfo = (struct driver_info *)id->driver_info; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - struct cm109_dev *dev; - struct input_dev *input_dev = NULL; - int ret, pipe, i; - int error = -ENOMEM; - - interface = intf->cur_altsetting; - endpoint = &interface->endpoint[0].desc; - - if (!usb_endpoint_is_int_in(endpoint)) - return -ENODEV; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - spin_lock_init(&dev->ctl_submit_lock); - mutex_init(&dev->pm_mutex); - - dev->udev = udev; - dev->intf = intf; - - dev->idev = input_dev = input_allocate_device(); - if (!input_dev) - goto err_out; - - /* allocate usb buffers */ - dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, - GFP_KERNEL, &dev->irq_dma); - if (!dev->irq_data) - goto err_out; - - dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN, - GFP_KERNEL, &dev->ctl_dma); - if (!dev->ctl_data) - goto err_out; - - dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)), - GFP_KERNEL, &dev->ctl_req_dma); - if (!dev->ctl_req) - goto err_out; - - /* allocate urb structures */ - dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->urb_irq) - goto err_out; - - dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->urb_ctl) - goto err_out; - - /* get a handle to the interrupt data pipe */ - pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); - ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (ret != USB_PKT_LEN) - err("invalid payload size %d, expected %d", ret, USB_PKT_LEN); - - /* initialise irq urb */ - usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data, - USB_PKT_LEN, - cm109_urb_irq_callback, dev, endpoint->bInterval); - dev->urb_irq->transfer_dma = dev->irq_dma; - dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - dev->urb_irq->dev = udev; - - /* initialise ctl urb */ - dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | - USB_DIR_OUT; - dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION; - dev->ctl_req->wValue = cpu_to_le16(0x200); - dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); - dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN); - - usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0), - (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN, - cm109_urb_ctl_callback, dev); - dev->urb_ctl->setup_dma = dev->ctl_req_dma; - dev->urb_ctl->transfer_dma = dev->ctl_dma; - dev->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP | - URB_NO_TRANSFER_DMA_MAP; - dev->urb_ctl->dev = udev; - - /* find out the physical bus location */ - usb_make_path(udev, dev->phys, sizeof(dev->phys)); - strlcat(dev->phys, "/input0", sizeof(dev->phys)); - - /* register settings for the input device */ - input_dev->name = nfo->name; - input_dev->phys = dev->phys; - usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, dev); - input_dev->open = cm109_input_open; - input_dev->close = cm109_input_close; - input_dev->event = cm109_input_ev; - - input_dev->keycode = dev->keymap; - input_dev->keycodesize = sizeof(unsigned char); - input_dev->keycodemax = ARRAY_SIZE(dev->keymap); - - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND); - input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); - - /* register available key events */ - for (i = 0; i < KEYMAP_SIZE; i++) { - unsigned short k = keymap(i); - dev->keymap[i] = k; - __set_bit(k, input_dev->keybit); - } - __clear_bit(KEY_RESERVED, input_dev->keybit); - - error = input_register_device(dev->idev); - if (error) - goto err_out; - - usb_set_intfdata(intf, dev); - - return 0; - - err_out: - input_free_device(input_dev); - cm109_usb_cleanup(dev); - return error; -} - -static int cm109_usb_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct cm109_dev *dev = usb_get_intfdata(intf); - - dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event); - - mutex_lock(&dev->pm_mutex); - cm109_stop_traffic(dev); - mutex_unlock(&dev->pm_mutex); - - return 0; -} - -static int cm109_usb_resume(struct usb_interface *intf) -{ - struct cm109_dev *dev = usb_get_intfdata(intf); - - dev_info(&intf->dev, "cm109: usb_resume\n"); - - mutex_lock(&dev->pm_mutex); - cm109_restore_state(dev); - mutex_unlock(&dev->pm_mutex); - - return 0; -} - -static int cm109_usb_pre_reset(struct usb_interface *intf) -{ - struct cm109_dev *dev = usb_get_intfdata(intf); - - mutex_lock(&dev->pm_mutex); - - /* - * Make sure input events don't try to toggle buzzer - * while we are resetting - */ - dev->resetting = 1; - smp_wmb(); - - cm109_stop_traffic(dev); - - return 0; -} - -static int cm109_usb_post_reset(struct usb_interface *intf) -{ - struct cm109_dev *dev = usb_get_intfdata(intf); - - dev->resetting = 0; - smp_wmb(); - - cm109_restore_state(dev); - - mutex_unlock(&dev->pm_mutex); - - return 0; -} - -static struct usb_driver cm109_driver = { - .name = "cm109", - .probe = cm109_usb_probe, - .disconnect = cm109_usb_disconnect, - .suspend = cm109_usb_suspend, - .resume = cm109_usb_resume, - .reset_resume = cm109_usb_resume, - .pre_reset = cm109_usb_pre_reset, - .post_reset = cm109_usb_post_reset, - .id_table = cm109_usb_table, - .supports_autosuspend = 1, -}; - -static int __init cm109_select_keymap(void) -{ - /* Load the phone keymap */ - if (!strcasecmp(phone, "kip1000")) { - keymap = keymap_kip1000; - printk(KERN_INFO KBUILD_MODNAME ": " - "Keymap for Komunikate KIP1000 phone loaded\n"); - } else if (!strcasecmp(phone, "gtalk")) { - keymap = keymap_gtalk; - printk(KERN_INFO KBUILD_MODNAME ": " - "Keymap for Genius G-talk phone loaded\n"); - } else if (!strcasecmp(phone, "usbph01")) { - keymap = keymap_usbph01; - printk(KERN_INFO KBUILD_MODNAME ": " - "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n"); - } else { - printk(KERN_ERR KBUILD_MODNAME ": " - "Unsupported phone: %s\n", phone); - return -EINVAL; - } - - return 0; -} - -static int __init cm109_init(void) -{ - int err; - - err = cm109_select_keymap(); - if (err) - return err; - - err = usb_register(&cm109_driver); - if (err) - return err; - - printk(KERN_INFO KBUILD_MODNAME ": " - DRIVER_DESC ": " DRIVER_VERSION " (C) " DRIVER_AUTHOR "\n"); - - return 0; -} - -static void __exit cm109_exit(void) -{ - usb_deregister(&cm109_driver); -} - -module_init(cm109_init); -module_exit(cm109_exit); - -MODULE_DEVICE_TABLE(usb, cm109_usb_table); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/misc/hp_sdc_rtc.c b/trunk/drivers/input/misc/hp_sdc_rtc.c index 82ec6b1b6467..daa9d4220331 100644 --- a/trunk/drivers/input/misc/hp_sdc_rtc.c +++ b/trunk/drivers/input/misc/hp_sdc_rtc.c @@ -458,35 +458,35 @@ static int hp_sdc_rtc_proc_output (char *buf) p += sprintf(p, "i8042 rtc\t: READ FAILED!\n"); } else { p += sprintf(p, "i8042 rtc\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + tv.tv_sec, tv.tv_usec/1000); } if (hp_sdc_rtc_read_fhs(&tv)) { p += sprintf(p, "handshake\t: READ FAILED!\n"); } else { p += sprintf(p, "handshake\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + tv.tv_sec, tv.tv_usec/1000); } if (hp_sdc_rtc_read_mt(&tv)) { p += sprintf(p, "alarm\t\t: READ FAILED!\n"); } else { p += sprintf(p, "alarm\t\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + tv.tv_sec, tv.tv_usec/1000); } if (hp_sdc_rtc_read_dt(&tv)) { p += sprintf(p, "delay\t\t: READ FAILED!\n"); } else { p += sprintf(p, "delay\t\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + tv.tv_sec, tv.tv_usec/1000); } if (hp_sdc_rtc_read_ct(&tv)) { p += sprintf(p, "periodic\t: READ FAILED!\n"); } else { p += sprintf(p, "periodic\t: %ld.%02d seconds\n", - tv.tv_sec, (int)tv.tv_usec/1000); + tv.tv_sec, tv.tv_usec/1000); } p += sprintf(p, diff --git a/trunk/include/linux/map_to_7segment.h b/trunk/drivers/input/misc/map_to_7segment.h similarity index 98% rename from trunk/include/linux/map_to_7segment.h rename to trunk/drivers/input/misc/map_to_7segment.h index 7df8432c4402..a424094d9fe2 100644 --- a/trunk/include/linux/map_to_7segment.h +++ b/trunk/drivers/input/misc/map_to_7segment.h @@ -1,4 +1,6 @@ /* + * drivers/usb/input/map_to_7segment.h + * * Copyright (c) 2005 Henk Vergonet * * This program is free software; you can redistribute it and/or @@ -34,7 +36,7 @@ * Usage: * * Register a map variable, and fill it with a character set: - * static SEG7_DEFAULT_MAP(map_seg7); + * static SEG7_DEFAULT_MAP(map_seg7); * * * Then use for conversion: diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index 7c8957dd22c0..fe268be3293b 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -277,16 +277,6 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { { KE_END, 0 } }; -static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, /* Fn+F1 */ - { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */ - { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */ - { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */ - { KE_KEY, 0x36, {KEY_WWW} }, /* www button */ - { KE_WIFI, 0x78 }, /* satelite dish button */ - { KE_END, 0 } -}; - static struct key_entry keymap_fujitsu_n3510[] __initdata = { { KE_KEY, 0x11, {KEY_PROG1} }, { KE_KEY, 0x12, {KEY_PROG2} }, @@ -626,15 +616,6 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, .driver_data = keymap_fs_amilo_pro_v2000 }, - { - .callback = dmi_matched, - .ident = "Fujitsu-Siemens Amilo Pro Edition V3505", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), - }, - .driver_data = keymap_fs_amilo_pro_v3505 - }, { .callback = dmi_matched, .ident = "Fujitsu-Siemens Amilo M7400", diff --git a/trunk/drivers/input/misc/yealink.c b/trunk/drivers/input/misc/yealink.c index 11b5c7e84ed1..facefd3dba29 100644 --- a/trunk/drivers/input/misc/yealink.c +++ b/trunk/drivers/input/misc/yealink.c @@ -52,8 +52,8 @@ #include #include #include -#include +#include "map_to_7segment.h" #include "yealink.h" #define DRIVER_VERSION "yld-20051230" diff --git a/trunk/drivers/input/mouse/Kconfig b/trunk/drivers/input/mouse/Kconfig index f488b6852baf..f996546fc443 100644 --- a/trunk/drivers/input/mouse/Kconfig +++ b/trunk/drivers/input/mouse/Kconfig @@ -96,16 +96,6 @@ config MOUSE_PS2_TOUCHKIT If unsure, say N. -config MOUSE_PS2_OLPC - bool "OLPC PS/2 mouse protocol extension" - depends on MOUSE_PS2 && OLPC - help - Say Y here if you have an OLPC XO-1 laptop (with built-in - PS/2 touchpad/tablet device). The manufacturer calls the - touchpad an HGPK. - - If unsure, say N. - config MOUSE_SERIAL tristate "Serial mouse" select SERIO diff --git a/trunk/drivers/input/mouse/Makefile b/trunk/drivers/input/mouse/Makefile index 8e6e69097801..d4d202516090 100644 --- a/trunk/drivers/input/mouse/Makefile +++ b/trunk/drivers/input/mouse/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o psmouse-objs := psmouse-base.o synaptics.o psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o -psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index cbedf957cc58..385e32bcf6a6 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -54,7 +54,6 @@ static const struct alps_model_info alps_model_data[] = { { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ - { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ }; diff --git a/trunk/drivers/input/mouse/appletouch.c b/trunk/drivers/input/mouse/appletouch.c index 079816e6b23b..1f41ae94f26b 100644 --- a/trunk/drivers/input/mouse/appletouch.c +++ b/trunk/drivers/input/mouse/appletouch.c @@ -136,28 +136,12 @@ MODULE_DEVICE_TABLE(usb, atp_table); #define ATP_GEYSER_MODE_REQUEST_INDEX 0 #define ATP_GEYSER_MODE_VENDOR_VALUE 0x04 -/** - * enum atp_status_bits - status bit meanings - * - * These constants represent the meaning of the status bits. - * (only Geyser 3/4) - * - * @ATP_STATUS_BUTTON: The button was pressed - * @ATP_STATUS_BASE_UPDATE: Update of the base values (untouched pad) - * @ATP_STATUS_FROM_RESET: Reset previously performed - */ -enum atp_status_bits { - ATP_STATUS_BUTTON = BIT(0), - ATP_STATUS_BASE_UPDATE = BIT(2), - ATP_STATUS_FROM_RESET = BIT(4), -}; - /* Structure to hold all of our device specific stuff */ struct atp { char phys[64]; struct usb_device *udev; /* usb device */ struct urb *urb; /* usb request block */ - u8 *data; /* transferred data */ + signed char *data; /* transferred data */ struct input_dev *input; /* input dev */ enum atp_touchpad_type type; /* type of touchpad */ bool open; @@ -267,6 +251,8 @@ static void atp_reinit(struct work_struct *work) int retval; dprintk("appletouch: putting appletouch to sleep (reinit)\n"); + dev->idlecount = 0; + atp_geyser_init(udev); retval = usb_submit_urb(dev->urb, GFP_ATOMIC); @@ -341,14 +327,11 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers) input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); } -/* Check URB status and for correct length of data package */ - -#define ATP_URB_STATUS_SUCCESS 0 -#define ATP_URB_STATUS_ERROR 1 -#define ATP_URB_STATUS_ERROR_FATAL 2 - -static int atp_status_check(struct urb *urb) +static void atp_complete(struct urb *urb) { + int x, y, x_z, y_z, x_f, y_f; + int retval, i, j; + int key; struct atp *dev = urb->context; switch (urb->status) { @@ -368,12 +351,11 @@ static int atp_status_check(struct urb *urb) /* This urb is terminated, clean up */ dbg("atp_complete: urb shutting down with status: %d", urb->status); - return ATP_URB_STATUS_ERROR_FATAL; - + return; default: dbg("atp_complete: nonzero urb status received: %d", urb->status); - return ATP_URB_STATUS_ERROR; + goto exit; } /* drop incomplete datasets */ @@ -381,33 +363,30 @@ static int atp_status_check(struct urb *urb) dprintk("appletouch: incomplete data package" " (first byte: %d, length: %d).\n", dev->data[0], dev->urb->actual_length); - return ATP_URB_STATUS_ERROR; + goto exit; } - return ATP_URB_STATUS_SUCCESS; -} - -/* - * USB interrupt callback functions - */ - -/* Interrupt function for older touchpads: FOUNTAIN/GEYSER1/GEYSER2 */ - -static void atp_complete_geyser_1_2(struct urb *urb) -{ - int x, y, x_z, y_z, x_f, y_f; - int retval, i, j; - int key; - struct atp *dev = urb->context; - int status = atp_status_check(urb); + /* reorder the sensors values */ + if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { + memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); - if (status == ATP_URB_STATUS_ERROR_FATAL) - return; - else if (status == ATP_URB_STATUS_ERROR) - goto exit; + /* + * The values are laid out like this: + * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ... + * '-' is an unused value. + */ - /* reorder the sensors values */ - if (dev->type == ATP_GEYSER2) { + /* read X values */ + for (i = 0, j = 19; i < 20; i += 2, j += 3) { + dev->xy_cur[i] = dev->data[j + 1]; + dev->xy_cur[i + 1] = dev->data[j + 2]; + } + /* read Y values */ + for (i = 0, j = 1; i < 9; i += 2, j += 3) { + dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; + dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; + } + } else if (dev->type == ATP_GEYSER2) { memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); /* @@ -448,40 +427,34 @@ static void atp_complete_geyser_1_2(struct urb *urb) /* first sample */ dev->valid = true; dev->x_old = dev->y_old = -1; - - /* Store first sample */ memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); - /* Perform size detection, if not done already */ - if (!dev->size_detect_done) { - - /* 17" Powerbooks have extra X sensors */ - for (i = (dev->type == ATP_GEYSER2 ? 15 : 16); - i < ATP_XSENSORS; i++) { - if (!dev->xy_cur[i]) - continue; - - printk(KERN_INFO - "appletouch: 17\" model detected.\n"); - - if (dev->type == ATP_GEYSER2) - input_set_abs_params(dev->input, ABS_X, - 0, - (20 - 1) * - ATP_XFACT - 1, - ATP_FUZZ, 0); - else - input_set_abs_params(dev->input, ABS_X, - 0, - (26 - 1) * - ATP_XFACT - 1, - ATP_FUZZ, 0); - break; - } - - dev->size_detect_done = 1; + if (dev->size_detect_done || + dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */ goto exit; + + /* 17" Powerbooks have extra X sensors */ + for (i = (dev->type == ATP_GEYSER2 ? 15 : 16); + i < ATP_XSENSORS; i++) { + if (!dev->xy_cur[i]) + continue; + + printk(KERN_INFO "appletouch: 17\" model detected.\n"); + if (dev->type == ATP_GEYSER2) + input_set_abs_params(dev->input, ABS_X, 0, + (20 - 1) * + ATP_XFACT - 1, + ATP_FUZZ, 0); + else + input_set_abs_params(dev->input, ABS_X, 0, + (ATP_XSENSORS - 1) * + ATP_XFACT - 1, + ATP_FUZZ, 0); + break; } + + dev->size_detect_done = 1; + goto exit; } for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { @@ -502,118 +475,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) ATP_XFACT, &x_z, &x_f); y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, ATP_YFACT, &y_z, &y_f); - key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON; - - if (x && y) { - if (dev->x_old != -1) { - x = (dev->x_old * 3 + x) >> 2; - y = (dev->y_old * 3 + y) >> 2; - dev->x_old = x; - dev->y_old = y; - - if (debug > 1) - printk(KERN_DEBUG "appletouch: " - "X: %3d Y: %3d Xz: %3d Yz: %3d\n", - x, y, x_z, y_z); - - input_report_key(dev->input, BTN_TOUCH, 1); - input_report_abs(dev->input, ABS_X, x); - input_report_abs(dev->input, ABS_Y, y); - input_report_abs(dev->input, ABS_PRESSURE, - min(ATP_PRESSURE, x_z + y_z)); - atp_report_fingers(dev->input, max(x_f, y_f)); - } - dev->x_old = x; - dev->y_old = y; - - } else if (!x && !y) { - - dev->x_old = dev->y_old = -1; - input_report_key(dev->input, BTN_TOUCH, 0); - input_report_abs(dev->input, ABS_PRESSURE, 0); - atp_report_fingers(dev->input, 0); - - /* reset the accumulator on release */ - memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); - } - - input_report_key(dev->input, BTN_LEFT, key); - input_sync(dev->input); - - exit: - retval = usb_submit_urb(dev->urb, GFP_ATOMIC); - if (retval) - err("atp_complete: usb_submit_urb failed with result %d", - retval); -} - -/* Interrupt function for older touchpads: GEYSER3/GEYSER4 */ - -static void atp_complete_geyser_3_4(struct urb *urb) -{ - int x, y, x_z, y_z, x_f, y_f; - int retval, i, j; - int key; - struct atp *dev = urb->context; - int status = atp_status_check(urb); - - if (status == ATP_URB_STATUS_ERROR_FATAL) - return; - else if (status == ATP_URB_STATUS_ERROR) - goto exit; - - /* Reorder the sensors values: - * - * The values are laid out like this: - * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ... - * '-' is an unused value. - */ - - /* read X values */ - for (i = 0, j = 19; i < 20; i += 2, j += 3) { - dev->xy_cur[i] = dev->data[j + 1]; - dev->xy_cur[i + 1] = dev->data[j + 2]; - } - /* read Y values */ - for (i = 0, j = 1; i < 9; i += 2, j += 3) { - dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; - dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; - } - - dbg_dump("sample", dev->xy_cur); - - /* Just update the base values (i.e. touchpad in untouched state) */ - if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) { - - dprintk(KERN_DEBUG "appletouch: updated base values\n"); - - memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); - goto exit; - } - - for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { - /* calculate the change */ - dev->xy_acc[i] = dev->xy_cur[i] - dev->xy_old[i]; - - /* this is a round-robin value, so couple with that */ - if (dev->xy_acc[i] > 127) - dev->xy_acc[i] -= 256; - - if (dev->xy_acc[i] < -127) - dev->xy_acc[i] += 256; - - /* prevent down drifting */ - if (dev->xy_acc[i] < 0) - dev->xy_acc[i] = 0; - } - - dbg_dump("accumulator", dev->xy_acc); - - x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, - ATP_XFACT, &x_z, &x_f); - y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, - ATP_YFACT, &y_z, &y_f); - key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON; + key = dev->data[dev->datalen - 1] & 1; if (x && y) { if (dev->x_old != -1) { @@ -652,27 +514,28 @@ static void atp_complete_geyser_3_4(struct urb *urb) input_sync(dev->input); /* - * Geysers 3/4 will continue to send packets continually after + * Many Geysers will continue to send packets continually after * the first touch unless reinitialised. Do so if it's been * idle for a while in order to avoid waking the kernel up - * several hundred times a second. - */ - - /* - * Button must not be pressed when entering suspend, - * otherwise we will never release the button. + * several hundred times a second. Re-initialization does not + * work on Fountain touchpads. */ - if (!x && !y && !key) { - dev->idlecount++; - if (dev->idlecount == 10) { - dev->x_old = dev->y_old = -1; + if (dev->type != ATP_FOUNTAIN) { + /* + * Button must not be pressed when entering suspend, + * otherwise we will never release the button. + */ + if (!x && !y && !key) { + dev->idlecount++; + if (dev->idlecount == 10) { + dev->valid = false; + schedule_work(&dev->work); + /* Don't resubmit urb here, wait for reinit */ + return; + } + } else dev->idlecount = 0; - schedule_work(&dev->work); - /* Don't resubmit urb here, wait for reinit */ - return; - } - } else - dev->idlecount = 0; + } exit: retval = usb_submit_urb(dev->urb, GFP_ATOMIC); @@ -769,19 +632,9 @@ static int atp_probe(struct usb_interface *iface, if (!dev->data) goto err_free_urb; - /* Select the USB complete (callback) function */ - if (dev->type == ATP_FOUNTAIN || - dev->type == ATP_GEYSER1 || - dev->type == ATP_GEYSER2) - usb_fill_int_urb(dev->urb, udev, - usb_rcvintpipe(udev, int_in_endpointAddr), - dev->data, dev->datalen, - atp_complete_geyser_1_2, dev, 1); - else - usb_fill_int_urb(dev->urb, udev, - usb_rcvintpipe(udev, int_in_endpointAddr), - dev->data, dev->datalen, - atp_complete_geyser_3_4, dev, 1); + usb_fill_int_urb(dev->urb, udev, + usb_rcvintpipe(udev, int_in_endpointAddr), + dev->data, dev->datalen, atp_complete, dev, 1); error = atp_handle_geyser(dev); if (error) @@ -898,6 +751,8 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message) struct atp *dev = usb_get_intfdata(iface); usb_kill_urb(dev->urb); + dev->valid = false; + return 0; } diff --git a/trunk/drivers/input/mouse/hgpk.c b/trunk/drivers/input/mouse/hgpk.c deleted file mode 100644 index e82d34201e97..000000000000 --- a/trunk/drivers/input/mouse/hgpk.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * OLPC HGPK (XO-1) touchpad PS/2 mouse driver - * - * Copyright (c) 2006-2008 One Laptop Per Child - * Authors: - * Zephaniah E. Hull - * Andres Salomon - * - * This driver is partly based on the ALPS driver, which is: - * - * Copyright (c) 2003 Neil Brown - * Copyright (c) 2003-2005 Peter Osterlund - * Copyright (c) 2004 Dmitry Torokhov - * Copyright (c) 2005 Vojtech Pavlik - * - * 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. - */ - -/* - * The spec from ALPS is available from - * . It refers to this - * device as HGPK (Hybrid GS, PT, and Keymatrix). - * - * The earliest versions of the device had simultaneous reporting; that - * was removed. After that, the device used the Advanced Mode GS/PT streaming - * stuff. That turned out to be too buggy to support, so we've finally - * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad). - */ - -#define DEBUG -#include -#include -#include -#include -#include - -#include "psmouse.h" -#include "hgpk.h" - -static int tpdebug; -module_param(tpdebug, int, 0644); -MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); - -static int recalib_delta = 100; -module_param(recalib_delta, int, 0644); -MODULE_PARM_DESC(recalib_delta, - "packets containing a delta this large will cause a recalibration."); - -/* - * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" - * above the pad and still have it send packets. This causes a jump cursor - * when one places their finger on the pad. We can probably detect the - * jump as we see a large deltas (>= 100px). In mouse mode, I've been - * unable to even come close to 100px deltas during normal usage, so I think - * this threshold is safe. If a large delta occurs, trigger a recalibration. - */ -static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y) -{ - struct hgpk_data *priv = psmouse->private; - - if (abs(x) > recalib_delta || abs(y) > recalib_delta) { - hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n", - recalib_delta, x, y); - /* My car gets forty rods to the hogshead and that's the - * way I likes it! */ - psmouse_queue_work(psmouse, &priv->recalib_wq, - msecs_to_jiffies(1000)); - } -} - -/* - * We have no idea why this particular hardware bug occurs. The touchpad - * will randomly start spewing packets without anything touching the - * pad. This wouldn't necessarily be bad, but it's indicative of a - * severely miscalibrated pad; attempting to use the touchpad while it's - * spewing means the cursor will jump all over the place, and act "drunk". - * - * The packets that are spewed tend to all have deltas between -2 and 2, and - * the cursor will move around without really going very far. It will - * tend to end up in the same location; if we tally up the changes over - * 100 packets, we end up w/ a final delta of close to 0. This happens - * pretty regularly when the touchpad is spewing, and is pretty hard to - * manually trigger (at least for *my* fingers). So, it makes a perfect - * scheme for detecting spews. - */ -static void hgpk_spewing_hack(struct psmouse *psmouse, - int l, int r, int x, int y) -{ - struct hgpk_data *priv = psmouse->private; - - /* ignore button press packets; many in a row could trigger - * a false-positive! */ - if (l || r) - return; - - priv->x_tally += x; - priv->y_tally += y; - - if (++priv->count > 100) { - if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { - hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n", - priv->x_tally, priv->y_tally); - psmouse_queue_work(psmouse, &priv->recalib_wq, - msecs_to_jiffies(1000)); - } - /* reset every 100 packets */ - priv->count = 0; - priv->x_tally = 0; - priv->y_tally = 0; - } -} - -/* - * HGPK Mouse Mode format (standard mouse format, sans middle button) - * - * byte 0: y-over x-over y-neg x-neg 1 0 swr swl - * byte 1: x7 x6 x5 x4 x3 x2 x1 x0 - * byte 2: y7 y6 y5 y4 y3 y2 y1 y0 - * - * swr/swl are the left/right buttons. - * x-neg/y-neg are the x and y delta negative bits - * x-over/y-over are the x and y overflow bits - */ -static int hgpk_validate_byte(unsigned char *packet) -{ - return (packet[0] & 0x0C) == 0x08; -} - -static void hgpk_process_packet(struct psmouse *psmouse) -{ - struct input_dev *dev = psmouse->dev; - unsigned char *packet = psmouse->packet; - int x, y, left, right; - - left = packet[0] & 1; - right = (packet[0] >> 1) & 1; - - x = packet[1] - ((packet[0] << 4) & 0x100); - y = ((packet[0] << 3) & 0x100) - packet[2]; - - hgpk_jumpy_hack(psmouse, x, y); - hgpk_spewing_hack(psmouse, left, right, x, y); - - if (tpdebug) - hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); - - input_report_key(dev, BTN_LEFT, left); - input_report_key(dev, BTN_RIGHT, right); - - input_report_rel(dev, REL_X, x); - input_report_rel(dev, REL_Y, y); - - input_sync(dev); -} - -static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) -{ - struct hgpk_data *priv = psmouse->private; - - if (hgpk_validate_byte(psmouse->packet)) { - hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n", - __func__, psmouse->pktcnt, psmouse->packet[0], - psmouse->packet[1], psmouse->packet[2]); - return PSMOUSE_BAD_DATA; - } - - if (psmouse->pktcnt >= psmouse->pktsize) { - hgpk_process_packet(psmouse); - return PSMOUSE_FULL_PACKET; - } - - if (priv->recalib_window) { - if (time_before(jiffies, priv->recalib_window)) { - /* - * ugh, got a packet inside our recalibration - * window, schedule another recalibration. - */ - hgpk_dbg(psmouse, - "packet inside calibration window, " - "queueing another recalibration\n"); - psmouse_queue_work(psmouse, &priv->recalib_wq, - msecs_to_jiffies(1000)); - } - priv->recalib_window = 0; - } - - return PSMOUSE_GOOD_DATA; -} - -static int hgpk_force_recalibrate(struct psmouse *psmouse) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - struct hgpk_data *priv = psmouse->private; - - /* C-series touchpads added the recalibrate command */ - if (psmouse->model < HGPK_MODEL_C) - return 0; - - /* we don't want to race with the irq handler, nor with resyncs */ - psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); - - /* start by resetting the device */ - psmouse_reset(psmouse); - - /* send the recalibrate request */ - if (ps2_command(ps2dev, NULL, 0xf5) || - ps2_command(ps2dev, NULL, 0xf5) || - ps2_command(ps2dev, NULL, 0xe6) || - ps2_command(ps2dev, NULL, 0xf5)) { - return -1; - } - - /* according to ALPS, 150mS is required for recalibration */ - msleep(150); - - /* XXX: If a finger is down during this delay, recalibration will - * detect capacitance incorrectly. This is a hardware bug, and - * we don't have a good way to deal with it. The 2s window stuff - * (below) is our best option for now. - */ - - if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) - return -1; - - psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); - - /* After we recalibrate, we shouldn't get any packets for 2s. If - * we do, it's likely that someone's finger was on the touchpad. - * If someone's finger *was* on the touchpad, it's probably - * miscalibrated. So, we should schedule another recalibration - */ - priv->recalib_window = jiffies + msecs_to_jiffies(2000); - - return 0; -} - -/* - * This kills power to the touchpad; according to ALPS, current consumption - * goes down to 50uA after running this. To turn power back on, we drive - * MS-DAT low. - */ -static int hgpk_toggle_power(struct psmouse *psmouse, int enable) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - int timeo; - - /* Added on D-series touchpads */ - if (psmouse->model < HGPK_MODEL_D) - return 0; - - if (enable) { - psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); - - /* - * Sending a byte will drive MS-DAT low; this will wake up - * the controller. Once we get an ACK back from it, it - * means we can continue with the touchpad re-init. ALPS - * tells us that 1s should be long enough, so set that as - * the upper bound. - */ - for (timeo = 20; timeo > 0; timeo--) { - if (!ps2_sendbyte(&psmouse->ps2dev, - PSMOUSE_CMD_DISABLE, 20)) - break; - msleep(50); - } - - psmouse_reset(psmouse); - - /* should be all set, enable the touchpad */ - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); - psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); - - } else { - hgpk_dbg(psmouse, "Powering off touchpad.\n"); - psmouse_set_state(psmouse, PSMOUSE_IGNORE); - - if (ps2_command(ps2dev, NULL, 0xec) || - ps2_command(ps2dev, NULL, 0xec) || - ps2_command(ps2dev, NULL, 0xea)) { - return -1; - } - - /* probably won't see an ACK, the touchpad will be off */ - ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); - } - - return 0; -} - -static int hgpk_poll(struct psmouse *psmouse) -{ - /* We can't poll, so always return failure. */ - return -1; -} - -static int hgpk_reconnect(struct psmouse *psmouse) -{ - /* During suspend/resume the ps2 rails remain powered. We don't want - * to do a reset because it's flush data out of buffers; however, - * earlier prototypes (B1) had some brokenness that required a reset. */ - if (olpc_board_at_least(olpc_board(0xb2))) - if (psmouse->ps2dev.serio->dev.power.power_state.event != - PM_EVENT_ON) - return 0; - - psmouse_reset(psmouse); - - return 0; -} - -static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) -{ - struct hgpk_data *priv = psmouse->private; - - return sprintf(buf, "%d\n", priv->powered); -} - -static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, - const char *buf, size_t count) -{ - struct hgpk_data *priv = psmouse->private; - unsigned long value; - int err; - - err = strict_strtoul(buf, 10, &value); - if (err || value > 1) - return -EINVAL; - - if (value != priv->powered) { - /* - * hgpk_toggle_power will deal w/ state so - * we're not racing w/ irq - */ - err = hgpk_toggle_power(psmouse, value); - if (!err) - priv->powered = value; - } - - return err ? err : count; -} - -__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, - hgpk_show_powered, hgpk_set_powered, 0); - -static void hgpk_disconnect(struct psmouse *psmouse) -{ - struct hgpk_data *priv = psmouse->private; - - device_remove_file(&psmouse->ps2dev.serio->dev, - &psmouse_attr_powered.dattr); - psmouse_reset(psmouse); - kfree(priv); -} - -static void hgpk_recalib_work(struct work_struct *work) -{ - struct delayed_work *w = container_of(work, struct delayed_work, work); - struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); - struct psmouse *psmouse = priv->psmouse; - - hgpk_dbg(psmouse, "recalibrating touchpad..\n"); - - if (hgpk_force_recalibrate(psmouse)) - hgpk_err(psmouse, "recalibration failed!\n"); -} - -static int hgpk_register(struct psmouse *psmouse) -{ - struct input_dev *dev = psmouse->dev; - int err; - - /* unset the things that psmouse-base sets which we don't have */ - __clear_bit(BTN_MIDDLE, dev->keybit); - - /* set the things we do have */ - __set_bit(EV_KEY, dev->evbit); - __set_bit(EV_REL, dev->evbit); - - __set_bit(REL_X, dev->relbit); - __set_bit(REL_Y, dev->relbit); - - __set_bit(BTN_LEFT, dev->keybit); - __set_bit(BTN_RIGHT, dev->keybit); - - /* register handlers */ - psmouse->protocol_handler = hgpk_process_byte; - psmouse->poll = hgpk_poll; - psmouse->disconnect = hgpk_disconnect; - psmouse->reconnect = hgpk_reconnect; - psmouse->pktsize = 3; - - /* Disable the idle resync. */ - psmouse->resync_time = 0; - /* Reset after a lot of bad bytes. */ - psmouse->resetafter = 1024; - - err = device_create_file(&psmouse->ps2dev.serio->dev, - &psmouse_attr_powered.dattr); - if (err) - hgpk_err(psmouse, "Failed to create sysfs attribute\n"); - - return err; -} - -int hgpk_init(struct psmouse *psmouse) -{ - struct hgpk_data *priv; - int err = -ENOMEM; - - priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); - if (!priv) - goto alloc_fail; - - psmouse->private = priv; - priv->psmouse = psmouse; - priv->powered = 1; - INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); - - err = psmouse_reset(psmouse); - if (err) - goto init_fail; - - err = hgpk_register(psmouse); - if (err) - goto init_fail; - - return 0; - -init_fail: - kfree(priv); -alloc_fail: - return err; -} - -static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - unsigned char param[3]; - - /* E7, E7, E7, E9 gets us a 3 byte identifier */ - if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || - ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || - ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || - ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { - return -EIO; - } - - hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]); - - /* HGPK signature: 0x67, 0x00, 0x */ - if (param[0] != 0x67 || param[1] != 0x00) - return -ENODEV; - - hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]); - - return param[2]; -} - -int hgpk_detect(struct psmouse *psmouse, int set_properties) -{ - int version; - - version = hgpk_get_model(psmouse); - if (version < 0) - return version; - - if (set_properties) { - psmouse->vendor = "ALPS"; - psmouse->name = "HGPK"; - psmouse->model = version; - } - - return 0; -} diff --git a/trunk/drivers/input/mouse/hgpk.h b/trunk/drivers/input/mouse/hgpk.h deleted file mode 100644 index a4b2a96f5f54..000000000000 --- a/trunk/drivers/input/mouse/hgpk.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * OLPC HGPK (XO-1) touchpad PS/2 mouse driver - */ - -#ifndef _HGPK_H -#define _HGPK_H - -enum hgpk_model_t { - HGPK_MODEL_PREA = 0x0a, /* pre-B1s */ - HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */ - HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */ - HGPK_MODEL_C = 0x3c, - HGPK_MODEL_D = 0x50, /* C1, mass production */ -}; - -struct hgpk_data { - struct psmouse *psmouse; - int powered; - int count, x_tally, y_tally; /* hardware workaround stuff */ - unsigned long recalib_window; - struct delayed_work recalib_wq; -}; - -#define hgpk_dbg(psmouse, format, arg...) \ - dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg) -#define hgpk_err(psmouse, format, arg...) \ - dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg) -#define hgpk_info(psmouse, format, arg...) \ - dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg) -#define hgpk_warn(psmouse, format, arg...) \ - dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg) -#define hgpk_notice(psmouse, format, arg...) \ - dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) - -#ifdef CONFIG_MOUSE_PS2_OLPC -int hgpk_detect(struct psmouse *psmouse, int set_properties); -int hgpk_init(struct psmouse *psmouse); -#else -static inline int hgpk_detect(struct psmouse *psmouse, int set_properties) -{ - return -ENODEV; -} -static inline int hgpk_init(struct psmouse *psmouse) -{ - return -ENODEV; -} -#endif - -#endif diff --git a/trunk/drivers/input/mouse/logips2pp.c b/trunk/drivers/input/mouse/logips2pp.c index 390f1dbb98a4..0c5660d28caa 100644 --- a/trunk/drivers/input/mouse/logips2pp.c +++ b/trunk/drivers/input/mouse/logips2pp.c @@ -157,8 +157,10 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned long value; + char *rest; - if (strict_strtoul(buf, 10, &value) || value > 1) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) return -EINVAL; ps2pp_set_smartscroll(psmouse, value); diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index 126e977e199e..f5a6be1d3c46 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -25,7 +25,6 @@ #include "synaptics.h" #include "logips2pp.h" #include "alps.h" -#include "hgpk.h" #include "lifebook.h" #include "trackpoint.h" #include "touchkit_ps2.h" @@ -202,12 +201,6 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) return PSMOUSE_FULL_PACKET; } -void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, - unsigned long delay) -{ - queue_delayed_work(kpsmoused_wq, work, delay); -} - /* * __psmouse_set_state() sets new psmouse state and resets all flags. */ @@ -227,7 +220,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta * is not a concern. */ -void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) +static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) { serio_pause_rx(psmouse->ps2dev.serio); __psmouse_set_state(psmouse, new_state); @@ -312,7 +305,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, psmouse->name, psmouse->phys, psmouse->pktcnt); psmouse->badbyte = psmouse->packet[0]; __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); - psmouse_queue_work(psmouse, &psmouse->resync_work, 0); + queue_work(kpsmoused_wq, &psmouse->resync_work); goto out; } @@ -349,7 +342,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { psmouse->badbyte = psmouse->packet[0]; __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); - psmouse_queue_work(psmouse, &psmouse->resync_work, 0); + queue_work(kpsmoused_wq, &psmouse->resync_work); goto out; } @@ -637,20 +630,8 @@ static int psmouse_extensions(struct psmouse *psmouse, } } -/* - * Try OLPC HGPK touchpad. - */ - if (max_proto > PSMOUSE_IMEX && - hgpk_detect(psmouse, set_properties) == 0) { - if (!set_properties || hgpk_init(psmouse) == 0) - return PSMOUSE_HGPK; -/* - * Init failed, try basic relative protocols - */ - max_proto = PSMOUSE_IMEX; - } - if (max_proto > PSMOUSE_IMEX) { + if (genius_detect(psmouse, set_properties) == 0) return PSMOUSE_GENPS; @@ -780,14 +761,6 @@ static const struct psmouse_protocol psmouse_protocols[] = { .alias = "touchkit", .detect = touchkit_ps2_detect, }, -#endif -#ifdef CONFIG_MOUSE_PS2_OLPC - { - .type = PSMOUSE_HGPK, - .name = "OLPC HGPK", - .alias = "hgpk", - .detect = hgpk_detect, - }, #endif { .type = PSMOUSE_CORTRON, @@ -962,7 +935,7 @@ static int psmouse_poll(struct psmouse *psmouse) static void psmouse_resync(struct work_struct *work) { struct psmouse *parent = NULL, *psmouse = - container_of(work, struct psmouse, resync_work.work); + container_of(work, struct psmouse, resync_work); struct serio *serio = psmouse->ps2dev.serio; psmouse_ret_t rc = PSMOUSE_GOOD_DATA; int failed = 0, enabled = 0; @@ -1221,7 +1194,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) goto err_free; ps2_init(&psmouse->ps2dev, serio); - INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync); + INIT_WORK(&psmouse->resync_work, psmouse_resync); psmouse->dev = input_dev; snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); @@ -1422,29 +1395,25 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev psmouse = serio_get_drvdata(serio); - if (attr->protect) { - if (psmouse->state == PSMOUSE_IGNORE) { - retval = -ENODEV; - goto out_unlock; - } - - if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); - psmouse_deactivate(parent); - } + if (psmouse->state == PSMOUSE_IGNORE) { + retval = -ENODEV; + goto out_unlock; + } - psmouse_deactivate(psmouse); + if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { + parent = serio_get_drvdata(serio->parent); + psmouse_deactivate(parent); } + psmouse_deactivate(psmouse); + retval = attr->set(psmouse, attr->data, buf, count); - if (attr->protect) { - if (retval != -ENODEV) - psmouse_activate(psmouse); + if (retval != -ENODEV) + psmouse_activate(psmouse); - if (parent) - psmouse_activate(parent); - } + if (parent) + psmouse_activate(parent); out_unlock: mutex_unlock(&psmouse_mutex); @@ -1464,8 +1433,10 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const { unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); unsigned long value; + char *rest; - if (strict_strtoul(buf, 10, &value)) + value = simple_strtoul(buf, &rest, 10); + if (*rest) return -EINVAL; if ((unsigned int)value != value) @@ -1578,8 +1549,10 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned long value; + char *rest; - if (strict_strtoul(buf, 10, &value)) + value = simple_strtoul(buf, &rest, 10); + if (*rest) return -EINVAL; psmouse->set_rate(psmouse, value); @@ -1589,8 +1562,10 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned long value; + char *rest; - if (strict_strtoul(buf, 10, &value)) + value = simple_strtoul(buf, &rest, 10); + if (*rest) return -EINVAL; psmouse->set_resolution(psmouse, value); diff --git a/trunk/drivers/input/mouse/psmouse.h b/trunk/drivers/input/mouse/psmouse.h index 8b608a1cdd12..1317bdd8cc7c 100644 --- a/trunk/drivers/input/mouse/psmouse.h +++ b/trunk/drivers/input/mouse/psmouse.h @@ -39,7 +39,7 @@ struct psmouse { void *private; struct input_dev *dev; struct ps2dev ps2dev; - struct delayed_work resync_work; + struct work_struct resync_work; char *vendor; char *name; unsigned char packet[8]; @@ -89,24 +89,20 @@ enum psmouse_type { PSMOUSE_TRACKPOINT, PSMOUSE_TOUCHKIT_PS2, PSMOUSE_CORTRON, - PSMOUSE_HGPK, PSMOUSE_AUTO /* This one should always be last */ }; -void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, - unsigned long delay); int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); int psmouse_reset(struct psmouse *psmouse); -void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state); void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); + struct psmouse_attribute { struct device_attribute dattr; void *data; ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); ssize_t (*set)(struct psmouse *psmouse, void *data, const char *buf, size_t count); - int protect; }; #define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) @@ -115,7 +111,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \ +#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ static ssize_t _show(struct psmouse *, void *data, char *); \ static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \ static struct psmouse_attribute psmouse_attr_##_name = { \ @@ -130,10 +126,6 @@ static struct psmouse_attribute psmouse_attr_##_name = { \ .data = _data, \ .show = _show, \ .set = _set, \ - .protect = _protect, \ } -#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ - __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1) - #endif /* _PSMOUSE_H */ diff --git a/trunk/drivers/input/mouse/trackpoint.c b/trunk/drivers/input/mouse/trackpoint.c index e68c814c4361..26b845fc186a 100644 --- a/trunk/drivers/input/mouse/trackpoint.c +++ b/trunk/drivers/input/mouse/trackpoint.c @@ -89,8 +89,10 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, struct trackpoint_attr_data *attr = data; unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); unsigned long value; + char *rest; - if (strict_strtoul(buf, 10, &value) || value > 255) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 255) return -EINVAL; *field = value; @@ -115,8 +117,10 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, struct trackpoint_attr_data *attr = data; unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); unsigned long value; + char *rest; - if (strict_strtoul(buf, 10, &value) || value > 1) + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) return -EINVAL; if (attr->inverted) diff --git a/trunk/drivers/input/serio/hp_sdc.c b/trunk/drivers/input/serio/hp_sdc.c index bfe49243f38b..0d395979b2d1 100644 --- a/trunk/drivers/input/serio/hp_sdc.c +++ b/trunk/drivers/input/serio/hp_sdc.c @@ -323,7 +323,7 @@ static void hp_sdc_tasklet(unsigned long foo) * it back to the application. and be less verbose. */ printk(KERN_WARNING PREFIX "read timeout (%ius)!\n", - (int)(tv.tv_usec - hp_sdc.rtv.tv_usec)); + tv.tv_usec - hp_sdc.rtv.tv_usec); curr->idx += hp_sdc.rqty; hp_sdc.rqty = 0; tmp = curr->seq[curr->actidx]; diff --git a/trunk/drivers/input/serio/i8042-io.h b/trunk/drivers/input/serio/i8042-io.h index 847f4aad7ed5..f451c7351a9d 100644 --- a/trunk/drivers/input/serio/i8042-io.h +++ b/trunk/drivers/input/serio/i8042-io.h @@ -67,7 +67,7 @@ static inline int i8042_platform_init(void) * On some platforms touching the i8042 data register region can do really * bad things. Because of this the region is always reserved on such boxes. */ -#if defined(CONFIG_PPC) +#if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(I8042_DATA_REG)) return -ENODEV; #endif diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index a321aea2c7b5..5aafe24984c5 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -322,13 +322,6 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), }, }, - { - .ident = "IBM 2656", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "2656"), - }, - }, { } }; diff --git a/trunk/drivers/input/serio/serio_raw.c b/trunk/drivers/input/serio/serio_raw.c index 470770c09260..c9397c8ee97e 100644 --- a/trunk/drivers/input/serio/serio_raw.c +++ b/trunk/drivers/input/serio/serio_raw.c @@ -373,12 +373,6 @@ static struct serio_device_id serio_raw_serio_ids[] = { .id = SERIO_ANY, .extra = SERIO_ANY, }, - { - .type = SERIO_8042_XL, - .proto = SERIO_ANY, - .id = SERIO_ANY, - .extra = SERIO_ANY, - }, { 0 } }; diff --git a/trunk/drivers/input/tablet/aiptek.c b/trunk/drivers/input/tablet/aiptek.c index e53c838f1866..8f037a1d44a6 100644 --- a/trunk/drivers/input/tablet/aiptek.c +++ b/trunk/drivers/input/tablet/aiptek.c @@ -1202,22 +1202,16 @@ static ssize_t store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - long x; - - if (strict_strtol(buf, 10, &x)) { - size_t len = buf[count - 1] == '\n' ? count - 1 : count; - - if (strncmp(buf, "disable", len)) - return -EINVAL; + int x; + if (strcmp(buf, "disable") == 0) { aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; } else { - if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX) - return -EINVAL; - - aiptek->newSetting.xTilt = x; + x = (int)simple_strtol(buf, NULL, 10); + if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) { + aiptek->newSetting.xTilt = x; + } } - return count; } @@ -1244,22 +1238,16 @@ static ssize_t store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - long y; - - if (strict_strtol(buf, 10, &y)) { - size_t len = buf[count - 1] == '\n' ? count - 1 : count; - - if (strncmp(buf, "disable", len)) - return -EINVAL; + int y; + if (strcmp(buf, "disable") == 0) { aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; } else { - if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX) - return -EINVAL; - - aiptek->newSetting.yTilt = y; + y = (int)simple_strtol(buf, NULL, 10); + if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) { + aiptek->newSetting.yTilt = y; + } } - return count; } @@ -1281,12 +1269,8 @@ static ssize_t store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - long j; - - if (strict_strtol(buf, 10, &j)) - return -EINVAL; - aiptek->newSetting.jitterDelay = (int)j; + aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1310,12 +1294,8 @@ static ssize_t store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - long d; - if (strict_strtol(buf, 10, &d)) - return -EINVAL; - - aiptek->newSetting.programmableDelay = (int)d; + aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1561,11 +1541,8 @@ static ssize_t store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - long w; - - if (strict_strtol(buf, 10, &w)) return -EINVAL; - aiptek->newSetting.wheel = (int)w; + aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); return count; } diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index b9b7fc6ff1eb..8583c766d565 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -69,17 +69,6 @@ struct ts_event { int ignore; }; -/* - * We allocate this separately to avoid cache line sharing issues when - * driver is used with DMA-based SPI controllers (like atmel_spi) on - * systems where main memory is not DMA-coherent (most non-x86 boards). - */ -struct ads7846_packet { - u8 read_x, read_y, read_z1, read_z2, pwrdown; - u16 dummy; /* for the pwrdown read */ - struct ts_event tc; -}; - struct ads7846 { struct input_dev *input; char phys[32]; @@ -97,7 +86,9 @@ struct ads7846 { u16 x_plate_ohms; u16 pressure_max; - struct ads7846_packet *packet; + u8 read_x, read_y, read_z1, read_z2, pwrdown; + u16 dummy; /* for the pwrdown read */ + struct ts_event tc; struct spi_transfer xfer[18]; struct spi_message msg[5]; @@ -472,11 +463,10 @@ static ssize_t ads7846_disable_store(struct device *dev, const char *buf, size_t count) { struct ads7846 *ts = dev_get_drvdata(dev); - long i; - - if (strict_strtoul(buf, 10, &i)) - return -EINVAL; + char *endp; + int i; + i = simple_strtoul(buf, &endp, 10); spin_lock_irq(&ts->lock); if (i) @@ -522,17 +512,16 @@ static int get_pendown_state(struct ads7846 *ts) static void ads7846_rx(void *ads) { struct ads7846 *ts = ads; - struct ads7846_packet *packet = ts->packet; unsigned Rt; u16 x, y, z1, z2; /* ads7846_rx_val() did in-place conversion (including byteswap) from * on-the-wire format as part of debouncing to get stable readings. */ - x = packet->tc.x; - y = packet->tc.y; - z1 = packet->tc.z1; - z2 = packet->tc.z2; + x = ts->tc.x; + y = ts->tc.y; + z1 = ts->tc.z1; + z2 = ts->tc.z2; /* range filtering */ if (x == MAX_12BIT) @@ -556,10 +545,10 @@ static void ads7846_rx(void *ads) * the maximum. Don't report it to user space, repeat at least * once more the measurement */ - if (packet->tc.ignore || Rt > ts->pressure_max) { + if (ts->tc.ignore || Rt > ts->pressure_max) { #ifdef VERBOSE pr_debug("%s: ignored %d pressure %d\n", - ts->spi->dev.bus_id, packet->tc.ignore, Rt); + ts->spi->dev.bus_id, ts->tc.ignore, Rt); #endif hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); @@ -652,7 +641,6 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val) static void ads7846_rx_val(void *ads) { struct ads7846 *ts = ads; - struct ads7846_packet *packet = ts->packet; struct spi_message *m; struct spi_transfer *t; int val; @@ -672,7 +660,7 @@ static void ads7846_rx_val(void *ads) case ADS7846_FILTER_REPEAT: break; case ADS7846_FILTER_IGNORE: - packet->tc.ignore = 1; + ts->tc.ignore = 1; /* Last message will contain ads7846_rx() as the * completion function. */ @@ -680,7 +668,7 @@ static void ads7846_rx_val(void *ads) break; case ADS7846_FILTER_OK: *(u16 *)t->rx_buf = val; - packet->tc.ignore = 0; + ts->tc.ignore = 0; m = &ts->msg[++ts->msg_idx]; break; default: @@ -785,6 +773,7 @@ static void ads7846_disable(struct ads7846 *ts) /* we know the chip's in lowpower mode since we always * leave it that way after every request */ + } /* Must be called with ts->lock held */ @@ -860,7 +849,6 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) static int __devinit ads7846_probe(struct spi_device *spi) { struct ads7846 *ts; - struct ads7846_packet *packet; struct input_dev *input_dev; struct ads7846_platform_data *pdata = spi->dev.platform_data; struct spi_message *m; @@ -896,16 +884,14 @@ static int __devinit ads7846_probe(struct spi_device *spi) return err; ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); - packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); input_dev = input_allocate_device(); - if (!ts || !packet || !input_dev) { + if (!ts || !input_dev) { err = -ENOMEM; goto err_free_mem; } dev_set_drvdata(&spi->dev, ts); - ts->packet = packet; ts->spi = spi; ts->input = input_dev; ts->vref_mv = pdata->vref_mv; @@ -977,13 +963,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) spi_message_init(m); /* y- still on; turn on only y+ (and ADC) */ - packet->read_y = READ_Y(vref); - x->tx_buf = &packet->read_y; + ts->read_y = READ_Y(vref); + x->tx_buf = &ts->read_y; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.y; + x->rx_buf = &ts->tc.y; x->len = 2; spi_message_add_tail(x, m); @@ -995,12 +981,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->delay_usecs = pdata->settle_delay_usecs; x++; - x->tx_buf = &packet->read_y; + x->tx_buf = &ts->read_y; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.y; + x->rx_buf = &ts->tc.y; x->len = 2; spi_message_add_tail(x, m); } @@ -1013,13 +999,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) /* turn y- off, x+ on, then leave in lowpower */ x++; - packet->read_x = READ_X(vref); - x->tx_buf = &packet->read_x; + ts->read_x = READ_X(vref); + x->tx_buf = &ts->read_x; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.x; + x->rx_buf = &ts->tc.x; x->len = 2; spi_message_add_tail(x, m); @@ -1028,12 +1014,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->delay_usecs = pdata->settle_delay_usecs; x++; - x->tx_buf = &packet->read_x; + x->tx_buf = &ts->read_x; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.x; + x->rx_buf = &ts->tc.x; x->len = 2; spi_message_add_tail(x, m); } @@ -1047,13 +1033,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) spi_message_init(m); x++; - packet->read_z1 = READ_Z1(vref); - x->tx_buf = &packet->read_z1; + ts->read_z1 = READ_Z1(vref); + x->tx_buf = &ts->read_z1; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.z1; + x->rx_buf = &ts->tc.z1; x->len = 2; spi_message_add_tail(x, m); @@ -1062,12 +1048,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->delay_usecs = pdata->settle_delay_usecs; x++; - x->tx_buf = &packet->read_z1; + x->tx_buf = &ts->read_z1; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.z1; + x->rx_buf = &ts->tc.z1; x->len = 2; spi_message_add_tail(x, m); } @@ -1079,13 +1065,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) spi_message_init(m); x++; - packet->read_z2 = READ_Z2(vref); - x->tx_buf = &packet->read_z2; + ts->read_z2 = READ_Z2(vref); + x->tx_buf = &ts->read_z2; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.z2; + x->rx_buf = &ts->tc.z2; x->len = 2; spi_message_add_tail(x, m); @@ -1094,12 +1080,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) x->delay_usecs = pdata->settle_delay_usecs; x++; - x->tx_buf = &packet->read_z2; + x->tx_buf = &ts->read_z2; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->tc.z2; + x->rx_buf = &ts->tc.z2; x->len = 2; spi_message_add_tail(x, m); } @@ -1113,13 +1099,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) spi_message_init(m); x++; - packet->pwrdown = PWRDOWN; - x->tx_buf = &packet->pwrdown; + ts->pwrdown = PWRDOWN; + x->tx_buf = &ts->pwrdown; x->len = 1; spi_message_add_tail(x, m); x++; - x->rx_buf = &packet->dummy; + x->rx_buf = &ts->dummy; x->len = 2; CS_CHANGE(*x); spi_message_add_tail(x, m); @@ -1172,7 +1158,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->filter_cleanup(ts->filter_data); err_free_mem: input_free_device(input_dev); - kfree(packet); kfree(ts); return err; } @@ -1198,7 +1183,6 @@ static int __devexit ads7846_remove(struct spi_device *spi) if (ts->filter_cleanup) ts->filter_cleanup(ts->filter_data); - kfree(ts->packet); kfree(ts); dev_dbg(&spi->dev, "unregistered touchscreen\n"); diff --git a/trunk/drivers/input/touchscreen/atmel_tsadcc.c b/trunk/drivers/input/touchscreen/atmel_tsadcc.c index a89a6a8f05e6..eee126b19e8b 100644 --- a/trunk/drivers/input/touchscreen/atmel_tsadcc.c +++ b/trunk/drivers/input/touchscreen/atmel_tsadcc.c @@ -91,9 +91,6 @@ struct atmel_tsadcc { char phys[32]; struct clk *clk; int irq; - unsigned int prev_absx; - unsigned int prev_absy; - unsigned char bufferedmeasure; }; static void __iomem *tsc_base; @@ -103,9 +100,10 @@ static void __iomem *tsc_base; static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) { - struct atmel_tsadcc *ts_dev = (struct atmel_tsadcc *)dev; - struct input_dev *input_dev = ts_dev->input; + struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input; + unsigned int absx; + unsigned int absy; unsigned int status; unsigned int reg; @@ -123,7 +121,6 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); input_report_key(input_dev, BTN_TOUCH, 0); - ts_dev->bufferedmeasure = 0; input_sync(input_dev); } else if (status & ATMEL_TSADCC_PENCNT) { @@ -141,23 +138,16 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) } else if (status & ATMEL_TSADCC_EOC(3)) { /* Conversion finished */ - if (ts_dev->bufferedmeasure) { - /* Last measurement is always discarded, since it can - * be erroneous. - * Always report previous measurement */ - input_report_abs(input_dev, ABS_X, ts_dev->prev_absx); - input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy); - input_report_key(input_dev, BTN_TOUCH, 1); - input_sync(input_dev); - } else - ts_dev->bufferedmeasure = 1; - - /* Now make new measurement */ - ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; - ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); - - ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; - ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); + absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; + absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); + + absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; + absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); + + input_report_abs(input_dev, ABS_X, absx); + input_report_abs(input_dev, ABS_Y, absy); + input_report_key(input_dev, BTN_TOUCH, 1); + input_sync(input_dev); } return IRQ_HANDLED; @@ -233,7 +223,6 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) } ts_dev->input = input_dev; - ts_dev->bufferedmeasure = 0; snprintf(ts_dev->phys, sizeof(ts_dev->phys), "%s/input0", pdev->dev.bus_id); diff --git a/trunk/drivers/input/touchscreen/mainstone-wm97xx.c b/trunk/drivers/input/touchscreen/mainstone-wm97xx.c index ba648750a8d9..37a555f37306 100644 --- a/trunk/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/trunk/drivers/input/touchscreen/mainstone-wm97xx.c @@ -3,7 +3,8 @@ * Wolfson WM97xx AC97 Codecs. * * Copyright 2004, 2007 Wolfson Microelectronics PLC. - * Author: Liam Girdwood + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com * Parts Copyright : Ian Molton * Andrew Zabolotny * @@ -295,6 +296,6 @@ module_init(mainstone_wm97xx_init); module_exit(mainstone_wm97xx_exit); /* Module information */ -MODULE_AUTHOR("Liam Girdwood "); +MODULE_AUTHOR("Liam Girdwood "); MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm9705.c b/trunk/drivers/input/touchscreen/wm9705.c index 6b5be742c27d..372efbc694ff 100644 --- a/trunk/drivers/input/touchscreen/wm9705.c +++ b/trunk/drivers/input/touchscreen/wm9705.c @@ -2,7 +2,8 @@ * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. * * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. - * Author: Liam Girdwood + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com * Parts Copyright : Ian Molton * Andrew Zabolotny * Russell King @@ -346,6 +347,6 @@ struct wm97xx_codec_drv wm9705_codec = { EXPORT_SYMBOL_GPL(wm9705_codec); /* Module information */ -MODULE_AUTHOR("Liam Girdwood "); +MODULE_AUTHOR("Liam Girdwood "); MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm9712.c b/trunk/drivers/input/touchscreen/wm9712.c index 7490b05c3566..c8bb1e7335fc 100644 --- a/trunk/drivers/input/touchscreen/wm9712.c +++ b/trunk/drivers/input/touchscreen/wm9712.c @@ -2,7 +2,8 @@ * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. * * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. - * Author: Liam Girdwood + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com * Parts Copyright : Ian Molton * Andrew Zabolotny * Russell King @@ -461,6 +462,6 @@ struct wm97xx_codec_drv wm9712_codec = { EXPORT_SYMBOL_GPL(wm9712_codec); /* Module information */ -MODULE_AUTHOR("Liam Girdwood "); +MODULE_AUTHOR("Liam Girdwood "); MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm9713.c b/trunk/drivers/input/touchscreen/wm9713.c index 238b5132712e..781ee83547e6 100644 --- a/trunk/drivers/input/touchscreen/wm9713.c +++ b/trunk/drivers/input/touchscreen/wm9713.c @@ -2,7 +2,8 @@ * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. * * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. - * Author: Liam Girdwood + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com * Parts Copyright : Ian Molton * Andrew Zabolotny * Russell King @@ -475,6 +476,6 @@ struct wm97xx_codec_drv wm9713_codec = { EXPORT_SYMBOL_GPL(wm9713_codec); /* Module information */ -MODULE_AUTHOR("Liam Girdwood "); +MODULE_AUTHOR("Liam Girdwood "); MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/wm97xx-core.c b/trunk/drivers/input/touchscreen/wm97xx-core.c index d15aa11d7056..d589ab0e3adc 100644 --- a/trunk/drivers/input/touchscreen/wm97xx-core.c +++ b/trunk/drivers/input/touchscreen/wm97xx-core.c @@ -3,7 +3,8 @@ * and WM9713 AC97 Codecs. * * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. - * Author: Liam Girdwood + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com * Parts Copyright : Ian Molton * Andrew Zabolotny * Russell King @@ -823,6 +824,6 @@ module_init(wm97xx_init); module_exit(wm97xx_exit); /* Module information */ -MODULE_AUTHOR("Liam Girdwood "); +MODULE_AUTHOR("Liam Girdwood "); MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index 1b5bf87c4cf4..871b0cbca5e4 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -1231,7 +1231,7 @@ static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file, int error = 0; switch (cmd) { default: - error = n_tty_ioctl_helper(tty, file, cmd, arg); + error = n_tty_ioctl (tty, file, cmd, arg); break; } return error; @@ -1553,7 +1553,8 @@ static int __init capi_init(void) return PTR_ERR(capi_class); } - device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); + device_create_drvdata(capi_class, NULL, MKDEV(capi_major, 0), NULL, + "capi"); #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE if (capinc_tty_init() < 0) { diff --git a/trunk/drivers/isdn/gigaset/ser-gigaset.c b/trunk/drivers/isdn/gigaset/ser-gigaset.c index 07052ed2a0c5..5e89fa177816 100644 --- a/trunk/drivers/isdn/gigaset/ser-gigaset.c +++ b/trunk/drivers/isdn/gigaset/ser-gigaset.c @@ -571,7 +571,6 @@ gigaset_tty_close(struct tty_struct *tty) } /* prevent other callers from entering ldisc methods */ - /* FIXME: should use the tty state flags */ tty->disc_data = NULL; if (!cs->hw.ser) @@ -643,11 +642,10 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, return -ENXIO; switch (cmd) { - - case FIONREAD: - /* unused, always return zero */ - val = 0; - rc = put_user(val, p); + case TCGETS: + case TCGETA: + /* pass through to underlying serial device */ + rc = n_tty_ioctl(tty, file, cmd, arg); break; case TCFLSH: @@ -661,13 +659,20 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, flush_send_queue(cs); break; } - /* Pass through */ + /* flush the serial port's buffer */ + rc = n_tty_ioctl(tty, file, cmd, arg); + break; - default: - /* pass through to underlying serial device */ - rc = n_tty_ioctl_helper(tty, file, cmd, arg); + case FIONREAD: + /* unused, always return zero */ + val = 0; + rc = put_user(val, p); break; + + default: + rc = -ENOIOCTLCMD; } + cs_put(cs); return rc; } @@ -675,8 +680,6 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, /* * Poll on the tty. * Unused, always return zero. - * - * FIXME: should probably return an exception - especially on hangup */ static unsigned int gigaset_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) diff --git a/trunk/drivers/isdn/hardware/avm/avm_cs.c b/trunk/drivers/isdn/hardware/avm/avm_cs.c index c72565520e41..a5b941c327f7 100644 --- a/trunk/drivers/isdn/hardware/avm/avm_cs.c +++ b/trunk/drivers/isdn/hardware/avm/avm_cs.c @@ -154,50 +154,83 @@ static void avmcs_detach(struct pcmcia_device *link) ======================================================================*/ -static int avmcs_configcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) { - if (cf->io.nwin <= 0) - return -ENODEV; - - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.NumPorts1 = cf->io.win[0].len; - p_dev->io.NumPorts2 = 0; - printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", - p_dev->io.BasePort1, - p_dev->io.BasePort1+p_dev->io.NumPorts1-1); - return pcmcia_request_io(p_dev, &p_dev->io); + int i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) return i; + return pcmcia_parse_tuple(handle, tuple, parse); +} + +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_first_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_next_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); } static int avmcs_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; + u_char buf[64]; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); dev = link->priv; - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); + do { + devname[0] = 0; + if (link->prod_id[1]) + strlcpy(devname, link->prod_id[1], sizeof(devname)); - /* - * find IO port - */ - if (pcmcia_loop_config(link, avmcs_configcheck, NULL)) - return -ENODEV; + /* + * find IO port + */ + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + i = first_tuple(link, &tuple, &parse); + while (i == CS_SUCCESS) { + if (cf->io.nwin > 0) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.NumPorts1 = cf->io.win[0].len; + link->io.NumPorts2 = 0; + printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", + link->io.BasePort1, + link->io.BasePort1+link->io.NumPorts1-1); + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) goto found_port; + } + i = next_tuple(link, &tuple, &parse); + } + +found_port: + if (i != CS_SUCCESS) { + cs_error(link, RequestIO, i); + break; + } - do { /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); @@ -208,7 +241,7 @@ static int avmcs_config(struct pcmcia_device *link) * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; diff --git a/trunk/drivers/isdn/hisax/avma1_cs.c b/trunk/drivers/isdn/hisax/avma1_cs.c index 23560c897ec3..fc6cc2c065b8 100644 --- a/trunk/drivers/isdn/hisax/avma1_cs.c +++ b/trunk/drivers/isdn/hisax/avma1_cs.c @@ -174,29 +174,38 @@ static void avma1cs_detach(struct pcmcia_device *link) ======================================================================*/ -static int avma1cs_configcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) { - if (cf->io.nwin <= 0) - return -ENODEV; - - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.NumPorts1 = cf->io.win[0].len; - p_dev->io.NumPorts2 = 0; - printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", - p_dev->io.BasePort1, - p_dev->io.BasePort1+p_dev->io.NumPorts1-1); - return pcmcia_request_io(p_dev, &p_dev->io); + int i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) return i; + return pcmcia_parse_tuple(handle, tuple, parse); } +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_first_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_next_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); +} static int avma1cs_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; + u_char buf[64]; char devname[128]; IsdnCard_t icard; int busy = 0; @@ -205,19 +214,45 @@ static int avma1cs_config(struct pcmcia_device *link) DEBUG(0, "avma1cs_config(0x%p)\n", link); - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); + do { + devname[0] = 0; + if (link->prod_id[1]) + strlcpy(devname, link->prod_id[1], sizeof(devname)); - if (pcmcia_loop_config(link, avma1cs_configcheck, NULL)) - return -ENODEV; + /* + * find IO port + */ + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + i = first_tuple(link, &tuple, &parse); + while (i == CS_SUCCESS) { + if (cf->io.nwin > 0) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.NumPorts1 = cf->io.win[0].len; + link->io.NumPorts2 = 0; + printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", + link->io.BasePort1, + link->io.BasePort1+link->io.NumPorts1 - 1); + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) goto found_port; + } + i = next_tuple(link, &tuple, &parse); + } - do { +found_port: + if (i != CS_SUCCESS) { + cs_error(link, RequestIO, i); + break; + } + /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); @@ -228,7 +263,7 @@ static int avma1cs_config(struct pcmcia_device *link) * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; diff --git a/trunk/drivers/isdn/hisax/elsa_cs.c b/trunk/drivers/isdn/hisax/elsa_cs.c index f4d0fe29bcf8..db7e64424afe 100644 --- a/trunk/drivers/isdn/hisax/elsa_cs.c +++ b/trunk/drivers/isdn/hisax/elsa_cs.c @@ -203,55 +203,82 @@ static void elsa_cs_detach(struct pcmcia_device *link) device available to the system. ======================================================================*/ +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) return i; + return pcmcia_parse_tuple(handle, tuple, parse); +} -static int elsa_cs_configcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) { - int j; - - if ((cf->io.nwin > 0) && cf->io.win[0].base) { - printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); - p_dev->io.BasePort1 = cf->io.win[0].base; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } else { - printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); - for (j = 0x2f0; j > 0x100; j -= 0x10) { - p_dev->io.BasePort1 = j; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - } - return -ENODEV; + int i = pcmcia_get_first_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_next_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); } static int elsa_cs_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; local_info_t *dev; - int i, last_fn; + int i, j, last_fn; + u_short buf[128]; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; - i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); - if (i != 0) { + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + i = first_tuple(link, &tuple, &parse); + while (i == CS_SUCCESS) { + if ( (cf->io.nwin > 0) && cf->io.win[0].base) { + printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } else { + printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); + link->conf.ConfigIndex = cf->index; + for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { + link->io.BasePort1 = j; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } + break; + } + i = next_tuple(link, &tuple, &parse); + } + + if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } diff --git a/trunk/drivers/isdn/hisax/sedlbauer_cs.c b/trunk/drivers/isdn/hisax/sedlbauer_cs.c index 9a3c9f5e4fe8..439cb530def8 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer_cs.c +++ b/trunk/drivers/isdn/hisax/sedlbauer_cs.c @@ -217,61 +217,101 @@ static void sedlbauer_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int sedlbauer_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int sedlbauer_config(struct pcmcia_device *link) { - win_req_t *req = priv_data; + local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_fn, last_ret; + u8 buf[64]; + config_info_t conf; + win_req_t req; + memreq_t map; + IsdnCard_t icard; + + DEBUG(0, "sedlbauer_config(0x%p)\n", link); + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; - if (cfg->index == 0) - return -ENODEV; + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); + /* + In this loop, we scan the CIS for configuration table entries, + each of which describes a valid card configuration, including + voltage, IO window, memory window, and interrupt settings. + + We make no assumptions about the card to be configured: we use + just the information available in the CIS. In an ideal world, + this would work for any PCMCIA card, but it requires a complete + and accurate CIS. In practice, a driver usually "knows" most of + these things without consulting the CIS, and most client drivers + will only use the CIS to fill in implementation-defined details. + */ + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t dflt = { 0 }; + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; + if (cfg->index == 0) goto next_entry; + link->conf.ConfigIndex = cfg->index; + /* Does this card need audio output? */ if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - p_dev->conf.Attributes |= CONF_ENABLE_SPKR; - p_dev->conf.Status = CCSR_AUDIO_ENA; + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; } - + /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) - return -ENODEV; - } else if (dflt->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) - return -ENODEV; + if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) + goto next_entry; + } else if (dflt.vcc.present & (1<vpp1.present & (1<conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt->vpp1.present & (1<conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - + link->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vpp1.present & (1<conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; + /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) + link->conf.Attributes |= CONF_ENABLE_IRQ; + /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) - return -ENODEV; + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; +/* new in dummy.cs 2001/01/28 MN + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; +*/ + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; } /* @@ -285,54 +325,30 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, needs to be mapped to virtual space with ioremap() before it is used. */ - if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { - cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; - memreq_t map; - req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; - req->Attributes |= WIN_ENABLE; - req->Base = mem->win[0].host_addr; - req->Size = mem->win[0].len; - req->AccessSpeed = 0; - if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0) - return -ENODEV; - map.Page = 0; - map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(p_dev->win, &map) != 0) - return -ENODEV; + if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; + req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; + req.Attributes |= WIN_ENABLE; + req.Base = mem->win[0].host_addr; + req.Size = mem->win[0].len; +/* new in dummy.cs 2001/01/28 MN + if (req.Size < 0x1000) + req.Size = 0x1000; +*/ + req.AccessSpeed = 0; + if (pcmcia_request_window(&link, &req, &link->win) != 0) + goto next_entry; + map.Page = 0; map.CardOffset = mem->win[0].card_addr; + if (pcmcia_map_mem_page(link->win, &map) != 0) + goto next_entry; } - return 0; -} - - - -static int sedlbauer_config(struct pcmcia_device *link) -{ - local_info_t *dev = link->priv; - win_req_t *req; - int last_fn, last_ret; - IsdnCard_t icard; - - DEBUG(0, "sedlbauer_config(0x%p)\n", link); - - req = kzalloc(sizeof(win_req_t), GFP_KERNEL); - if (!req) - return -ENOMEM; + /* If we got this far, we're cool! */ + break; - /* - In this loop, we scan the CIS for configuration table entries, - each of which describes a valid card configuration, including - voltage, IO window, memory window, and interrupt settings. - - We make no assumptions about the card to be configured: we use - just the information available in the CIS. In an ideal world, - this would work for any PCMCIA card, but it requires a complete - and accurate CIS. In practice, a driver usually "knows" most of - these things without consulting the CIS, and most client drivers - will only use the CIS to fill in implementation-defined details. - */ - last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req); - if (last_ret) - goto failed; + next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } /* Allocate an interrupt line. Note that this does not assign a @@ -371,8 +387,8 @@ static int sedlbauer_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) - printk(", mem 0x%06lx-0x%06lx", req->Base, - req->Base+req->Size-1); + printk(", mem 0x%06lx-0x%06lx", req.Base, + req.Base+req.Size-1); printk("\n"); icard.para[0] = link->irq.AssignedIRQ; @@ -393,7 +409,6 @@ static int sedlbauer_config(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); -failed: sedlbauer_release(link); return -ENODEV; diff --git a/trunk/drivers/isdn/hisax/teles_cs.c b/trunk/drivers/isdn/hisax/teles_cs.c index 623d111544d4..ab4bd455450e 100644 --- a/trunk/drivers/isdn/hisax/teles_cs.c +++ b/trunk/drivers/isdn/hisax/teles_cs.c @@ -193,55 +193,82 @@ static void teles_detach(struct pcmcia_device *link) device available to the system. ======================================================================*/ +static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) return i; + return pcmcia_parse_tuple(handle, tuple, parse); +} -static int teles_cs_configcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) { - int j; - - if ((cf->io.nwin > 0) && cf->io.win[0].base) { - printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); - p_dev->io.BasePort1 = cf->io.win[0].base; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } else { - printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); - for (j = 0x2f0; j > 0x100; j -= 0x10) { - p_dev->io.BasePort1 = j; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - } - return -ENODEV; + int i = pcmcia_get_first_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); +} + +static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i = pcmcia_get_next_tuple(handle, tuple); + if (i != CS_SUCCESS) return i; + return get_tuple(handle, tuple, parse); } static int teles_cs_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; local_info_t *dev; - int i, last_fn; + int i, j, last_fn; + u_short buf[128]; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; IsdnCard_t icard; DEBUG(0, "teles_config(0x%p)\n", link); dev = link->priv; - i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); - if (i != 0) { + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + i = first_tuple(link, &tuple, &parse); + while (i == CS_SUCCESS) { + if ( (cf->io.nwin > 0) && cf->io.win[0].base) { + printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } else { + printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); + link->conf.ConfigIndex = cf->index; + for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { + link->io.BasePort1 = j; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } + break; + } + i = next_tuple(link, &tuple, &parse); + } + + if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } diff --git a/trunk/drivers/isdn/mISDN/dsp_cmx.c b/trunk/drivers/isdn/mISDN/dsp_cmx.c index c2f51cc50760..e92b1ba4b45e 100644 --- a/trunk/drivers/isdn/mISDN/dsp_cmx.c +++ b/trunk/drivers/isdn/mISDN/dsp_cmx.c @@ -452,10 +452,10 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp) if (finddsp->features.pcm_id == dsp->features.pcm_id) { if (finddsp->pcm_slot_rx >= 0 && finddsp->pcm_slot_rx < sizeof(freeslots)) - freeslots[finddsp->pcm_slot_rx] = 0; + freeslots[finddsp->pcm_slot_tx] = 0; if (finddsp->pcm_slot_tx >= 0 && finddsp->pcm_slot_tx < sizeof(freeslots)) - freeslots[finddsp->pcm_slot_tx] = 0; + freeslots[finddsp->pcm_slot_rx] = 0; } } i = 0; diff --git a/trunk/drivers/isdn/mISDN/timerdev.c b/trunk/drivers/isdn/mISDN/timerdev.c index 875fabe16e36..e7462924b505 100644 --- a/trunk/drivers/isdn/mISDN/timerdev.c +++ b/trunk/drivers/isdn/mISDN/timerdev.c @@ -61,7 +61,7 @@ mISDN_open(struct inode *ino, struct file *filep) init_waitqueue_head(&dev->wait); filep->private_data = dev; __module_get(THIS_MODULE); - return nonseekable_open(ino, filep); + return 0; } static int diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c index ee74ee7b2acc..559a40861c39 100644 --- a/trunk/drivers/leds/led-class.c +++ b/trunk/drivers/leds/led-class.c @@ -103,8 +103,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { int rc; - led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, - "%s", led_cdev->name); + led_cdev->dev = device_create_drvdata(leds_class, parent, 0, led_cdev, + "%s", led_cdev->name); if (IS_ERR(led_cdev->dev)) return PTR_ERR(led_cdev->dev); diff --git a/trunk/drivers/macintosh/adb.c b/trunk/drivers/macintosh/adb.c index 23741cec45e3..cae52485208a 100644 --- a/trunk/drivers/macintosh/adb.c +++ b/trunk/drivers/macintosh/adb.c @@ -862,7 +862,8 @@ adbdev_init(void) adb_dev_class = class_create(THIS_MODULE, "adb"); if (IS_ERR(adb_dev_class)) return; - device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb"); + device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, + "adb"); platform_device_register(&adb_pfdev); platform_driver_probe(&adb_pfdrv, adb_dummy_probe); diff --git a/trunk/drivers/md/Kconfig b/trunk/drivers/md/Kconfig index 2281b5098e95..07d92c11b5d8 100644 --- a/trunk/drivers/md/Kconfig +++ b/trunk/drivers/md/Kconfig @@ -30,20 +30,6 @@ config BLK_DEV_MD If unsure, say N. -config MD_AUTODETECT - bool "Autodetect RAID arrays during kernel boot" - depends on BLK_DEV_MD=y - default y - ---help--- - If you say Y here, then the kernel will try to autodetect raid - arrays as part of its boot process. - - If you don't use raid and say Y, this autodetection can cause - a several-second delay in the boot time due to various - synchronisation steps that are part of this step. - - If unsure, say Y. - config MD_LINEAR tristate "Linear (append) mode" depends on BLK_DEV_MD diff --git a/trunk/drivers/md/faulty.c b/trunk/drivers/md/faulty.c index f26c1f9a475b..268547dbfbd3 100644 --- a/trunk/drivers/md/faulty.c +++ b/trunk/drivers/md/faulty.c @@ -287,8 +287,6 @@ static int run(mddev_t *mddev) int i; conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); - if (!conf) - return -ENOMEM; for (i=0; icounters[i], 0); diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index 190147c79e79..b9cbee688fae 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -16,8 +16,16 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + +#include +#include #include +#define MAJOR_NR MD_MAJOR +#define MD_DRIVER +#define MD_PERSONALITY + /* * find which device holds a particular offset */ @@ -25,15 +33,16 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) { dev_info_t *hash; linear_conf_t *conf = mddev_to_conf(mddev); + sector_t block = sector >> 1; /* * sector_div(a,b) returns the remainer and sets a to a/b */ - sector >>= conf->sector_shift; - (void)sector_div(sector, conf->spacing); - hash = conf->hash_table[sector]; + block >>= conf->preshift; + (void)sector_div(block, conf->hash_spacing); + hash = conf->hash_table[block]; - while (sector >= hash->num_sectors + hash->start_sector) + while ((sector>>1) >= (hash->size + hash->offset)) hash++; return hash; } @@ -56,7 +65,7 @@ static int linear_mergeable_bvec(struct request_queue *q, sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); dev0 = which_dev(mddev, sector); - maxsectors = dev0->num_sectors - (sector - dev0->start_sector); + maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); if (maxsectors < bio_sectors) maxsectors = 0; @@ -103,8 +112,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) dev_info_t **table; mdk_rdev_t *rdev; int i, nb_zone, cnt; - sector_t min_sectors; - sector_t curr_sector; + sector_t min_spacing; + sector_t curr_offset; struct list_head *tmp; conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), @@ -136,7 +145,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) mddev->queue->max_sectors > (PAGE_SIZE>>9)) blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); - disk->num_sectors = rdev->size * 2; + disk->size = rdev->size; conf->array_sectors += rdev->size * 2; cnt++; @@ -146,34 +155,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) goto out; } - min_sectors = conf->array_sectors; - sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *)); + min_spacing = conf->array_sectors / 2; + sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); - /* min_sectors is the minimum spacing that will fit the hash + /* min_spacing is the minimum spacing that will fit the hash * table in one PAGE. This may be much smaller than needed. * We find the smallest non-terminal set of consecutive devices - * that is larger than min_sectors and use the size of that as + * that is larger than min_spacing as use the size of that as * the actual spacing */ - conf->spacing = conf->array_sectors; + conf->hash_spacing = conf->array_sectors / 2; for (i=0; i < cnt-1 ; i++) { - sector_t tmp = 0; + sector_t sz = 0; int j; - for (j = i; j < cnt - 1 && tmp < min_sectors; j++) - tmp += conf->disks[j].num_sectors; - if (tmp >= min_sectors && tmp < conf->spacing) - conf->spacing = tmp; + for (j = i; j < cnt - 1 && sz < min_spacing; j++) + sz += conf->disks[j].size; + if (sz >= min_spacing && sz < conf->hash_spacing) + conf->hash_spacing = sz; } - /* spacing may be too large for sector_div to work with, + /* hash_spacing may be too large for sector_div to work with, * so we might need to pre-shift */ - conf->sector_shift = 0; + conf->preshift = 0; if (sizeof(sector_t) > sizeof(u32)) { - sector_t space = conf->spacing; + sector_t space = conf->hash_spacing; while (space > (sector_t)(~(u32)0)) { space >>= 1; - conf->sector_shift++; + conf->preshift++; } } /* @@ -185,9 +194,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) unsigned round; unsigned long base; - sz = conf->array_sectors >> conf->sector_shift; + sz = conf->array_sectors >> (conf->preshift + 1); sz += 1; /* force round-up */ - base = conf->spacing >> conf->sector_shift; + base = conf->hash_spacing >> conf->preshift; round = sector_div(sz, base); nb_zone = sz + (round ? 1 : 0); } @@ -202,31 +211,32 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) * Here we generate the linear hash table * First calculate the device offsets. */ - conf->disks[0].start_sector = 0; + conf->disks[0].offset = 0; for (i = 1; i < raid_disks; i++) - conf->disks[i].start_sector = - conf->disks[i-1].start_sector + - conf->disks[i-1].num_sectors; + conf->disks[i].offset = + conf->disks[i-1].offset + + conf->disks[i-1].size; table = conf->hash_table; + curr_offset = 0; i = 0; - for (curr_sector = 0; - curr_sector < conf->array_sectors; - curr_sector += conf->spacing) { + for (curr_offset = 0; + curr_offset < conf->array_sectors / 2; + curr_offset += conf->hash_spacing) { while (i < raid_disks-1 && - curr_sector >= conf->disks[i+1].start_sector) + curr_offset >= conf->disks[i+1].offset) i++; *table ++ = conf->disks + i; } - if (conf->sector_shift) { - conf->spacing >>= conf->sector_shift; - /* round spacing up so that when we divide by it, + if (conf->preshift) { + conf->hash_spacing >>= conf->preshift; + /* round hash_spacing up so that when we divide by it, * we err on the side of "too-low", which is safest. */ - conf->spacing++; + conf->hash_spacing++; } BUG_ON(table - conf->hash_table > nb_zone); @@ -307,6 +317,7 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) const int rw = bio_data_dir(bio); mddev_t *mddev = q->queuedata; dev_info_t *tmp_dev; + sector_t block; int cpu; if (unlikely(bio_barrier(bio))) { @@ -321,33 +332,29 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) part_stat_unlock(); tmp_dev = which_dev(mddev, bio->bi_sector); + block = bio->bi_sector >> 1; - if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors + - tmp_dev->start_sector) - || (bio->bi_sector < - tmp_dev->start_sector))) { + if (unlikely(block >= (tmp_dev->size + tmp_dev->offset) + || block < tmp_dev->offset)) { char b[BDEVNAME_SIZE]; - printk("linear_make_request: Sector %llu out of bounds on " - "dev %s: %llu sectors, offset %llu\n", - (unsigned long long)bio->bi_sector, + printk("linear_make_request: Block %llu out of bounds on " + "dev %s size %llu offset %llu\n", + (unsigned long long)block, bdevname(tmp_dev->rdev->bdev, b), - (unsigned long long)tmp_dev->num_sectors, - (unsigned long long)tmp_dev->start_sector); + (unsigned long long)tmp_dev->size, + (unsigned long long)tmp_dev->offset); bio_io_error(bio); return 0; } if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > - tmp_dev->start_sector + tmp_dev->num_sectors)) { + (tmp_dev->offset + tmp_dev->size)<<1)) { /* This bio crosses a device boundary, so we have to * split it. */ struct bio_pair *bp; - bp = bio_split(bio, - tmp_dev->start_sector + tmp_dev->num_sectors - - bio->bi_sector); - + ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector); if (linear_make_request(q, &bp->bio1)) generic_make_request(&bp->bio1); if (linear_make_request(q, &bp->bio2)) @@ -357,8 +364,7 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) } bio->bi_bdev = tmp_dev->rdev->bdev; - bio->bi_sector = bio->bi_sector - tmp_dev->start_sector - + tmp_dev->rdev->data_offset; + bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset; return 1; } @@ -366,6 +372,29 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) static void linear_status (struct seq_file *seq, mddev_t *mddev) { +#undef MD_DEBUG +#ifdef MD_DEBUG + int j; + linear_conf_t *conf = mddev_to_conf(mddev); + sector_t s = 0; + + seq_printf(seq, " "); + for (j = 0; j < mddev->raid_disks; j++) + { + char b[BDEVNAME_SIZE]; + s += conf->smallest_size; + seq_printf(seq, "[%s", + bdevname(conf->hash_table[j][0].rdev->bdev,b)); + + while (s > conf->hash_table[j][0].offset + + conf->hash_table[j][0].size) + seq_printf(seq, "/%s] ", + bdevname(conf->hash_table[j][1].rdev->bdev,b)); + else + seq_printf(seq, "] "); + } + seq_printf(seq, "\n"); +#endif seq_printf(seq, " %dk rounding", mddev->chunk_size/1024); } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index aaa3d465de4e..0a3a4bdcd4af 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -32,21 +32,31 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include #include +#include #include #include #include #include /* for invalidate_bdev */ #include +#include #include -#include -#include -#include -#include +#include + +#include + #include -#include + +#ifdef CONFIG_KMOD +#include +#endif + +#include #define MAJOR_NR MD_MAJOR +#define MD_DRIVER /* 63 partitions with the alternate major number (mdp) */ #define MdpMinorShift 6 @@ -56,7 +66,7 @@ #ifndef MODULE -static void autostart_arrays(int part); +static void autostart_arrays (int part); #endif static LIST_HEAD(pers_list); @@ -202,7 +212,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock); ) -static int md_fail_request(struct request_queue *q, struct bio *bio) +static int md_fail_request (struct request_queue *q, struct bio *bio) { bio_io_error(bio); return 0; @@ -2096,6 +2106,8 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) if (strict_strtoull(buf, 10, &size) < 0) return -EINVAL; + if (size < my_mddev->size) + return -EINVAL; if (my_mddev->pers && rdev->raid_disk >= 0) { if (my_mddev->persistent) { size = super_types[my_mddev->major_version]. @@ -2106,9 +2118,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) size = (rdev->bdev->bd_inode->i_size >> 10); size -= rdev->data_offset/2; } + if (size < my_mddev->size) + return -EINVAL; /* component must fit device */ } - if (size < my_mddev->size) - return -EINVAL; /* component must fit device */ rdev->size = size; if (size > oldsize && my_mddev->external) { @@ -2394,11 +2406,12 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) int i; unsigned long msec; char buf[30]; - + char *e; /* remove a period, and count digits after it */ if (len >= sizeof(buf)) return -EINVAL; - strlcpy(buf, cbuf, sizeof(buf)); + strlcpy(buf, cbuf, len); + buf[len] = 0; for (i=0; ipers) { - if (mddev->ro == 0) + if (mddev->ro != 1) err = do_md_stop(mddev, 1, 0); - else if (mddev->ro == 1) + else err = restart_array(mddev); if (err == 0) { mddev->ro = 2; @@ -2931,13 +2945,7 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len) { int major, minor; char *e; - /* Changing the details of 'external' metadata is - * always permitted. Otherwise there must be - * no devices attached to the array. - */ - if (mddev->external && strncmp(buf, "external:", 9) == 0) - ; - else if (!list_empty(&mddev->disks)) + if (!list_empty(&mddev->disks)) return -EBUSY; if (cmd_match(buf, "none")) { @@ -3519,12 +3527,17 @@ static int do_md_run(mddev_t * mddev) return -EINVAL; } /* - * chunk-size has to be a power of 2 + * chunk-size has to be a power of 2 and multiples of PAGE_SIZE */ if ( (1 << ffz(~chunk_size)) != chunk_size) { printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); return -EINVAL; } + if (chunk_size < PAGE_SIZE) { + printk(KERN_ERR "too small chunk_size: %d < %ld\n", + chunk_size, PAGE_SIZE); + return -EINVAL; + } /* devices must have minimum size of one chunk */ rdev_for_each(rdev, tmp, mddev) { @@ -3542,10 +3555,12 @@ static int do_md_run(mddev_t * mddev) } } +#ifdef CONFIG_KMOD if (mddev->level != LEVEL_NONE) request_module("md-level-%d", mddev->level); else if (mddev->clevel[0]) request_module("md-%s", mddev->clevel); +#endif /* * Drop all container device buffers, from now on @@ -3956,10 +3971,10 @@ static void autorun_array(mddev_t *mddev) } printk("\n"); - err = do_md_run(mddev); + err = do_md_run (mddev); if (err) { printk(KERN_WARNING "md: do_md_run() returned %d\n", err); - do_md_stop(mddev, 0, 0); + do_md_stop (mddev, 0, 0); } } @@ -4318,7 +4333,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) if (!(info->state & (1<pers) { - mddev->pers->status(seq, mddev); + mddev->pers->status (seq, mddev); seq_printf(seq, "\n "); if (mddev->pers->sync_request) { if (mddev->curr_resync > 2) { - status_resync(seq, mddev); + status_resync (seq, mddev); seq_printf(seq, "\n "); } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) seq_printf(seq, "\tresync=DELAYED\n "); @@ -6245,7 +6260,7 @@ static int md_notify_reboot(struct notifier_block *this, * appears to still be in use. Hence * the '100'. */ - do_md_stop(mddev, 1, 100); + do_md_stop (mddev, 1, 100); mddev_unlock(mddev); } /* @@ -6289,7 +6304,7 @@ static int __init md_init(void) raid_table_header = register_sysctl_table(raid_root_table); md_geninit(); - return 0; + return (0); } diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index 8744014b9d80..8bb8794129b3 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -19,7 +19,16 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include +#include #include +#include +#include + +#define MAJOR_NR MD_MAJOR +#define MD_DRIVER +#define MD_PERSONALITY #define MAX_WORK_PER_DISK 128 diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index 8ac6488ad0dc..53508a8a981d 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -18,8 +18,13 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include +#define MAJOR_NR MD_MAJOR +#define MD_DRIVER +#define MD_PERSONALITY + static void raid0_unplug(struct request_queue *q) { mddev_t *mddev = q->queuedata; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 9c788e2489b1..b9764429d856 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -32,7 +32,6 @@ */ #include "dm-bio-list.h" -#include #include #include diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index da5129a24b18..8bdc9bfc2887 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -19,7 +19,6 @@ */ #include "dm-bio-list.h" -#include #include #include @@ -2029,9 +2028,8 @@ static int run(mddev_t *mddev) int nc, fc, fo; sector_t stride, size; - if (mddev->chunk_size < PAGE_SIZE) { - printk(KERN_ERR "md/raid10: chunk size must be " - "at least PAGE_SIZE(%ld).\n", PAGE_SIZE); + if (mddev->chunk_size == 0) { + printk(KERN_ERR "md/raid10: non-zero chunk size required.\n"); return -EINVAL; } diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index a36a7435edf5..ae16794bef20 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -43,7 +43,12 @@ * miss any bits. */ +#include +#include +#include +#include #include +#include #include "raid6.h" #include @@ -270,7 +275,7 @@ static int grow_buffers(struct stripe_head *sh, int num) return 0; } -static void raid5_build_block(struct stripe_head *sh, int i); +static void raid5_build_block (struct stripe_head *sh, int i); static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) { @@ -1146,7 +1151,7 @@ static void raid5_end_read_request(struct bio * bi, int error) release_stripe(sh); } -static void raid5_end_write_request(struct bio *bi, int error) +static void raid5_end_write_request (struct bio *bi, int error) { struct stripe_head *sh = bi->bi_private; raid5_conf_t *conf = sh->raid_conf; @@ -1178,7 +1183,7 @@ static void raid5_end_write_request(struct bio *bi, int error) static sector_t compute_blocknr(struct stripe_head *sh, int i); -static void raid5_build_block(struct stripe_head *sh, int i) +static void raid5_build_block (struct stripe_head *sh, int i) { struct r5dev *dev = &sh->dev[i]; @@ -1216,10 +1221,10 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) set_bit(MD_RECOVERY_INTR, &mddev->recovery); } set_bit(Faulty, &rdev->flags); - printk(KERN_ALERT - "raid5: Disk failure on %s, disabling device.\n" - "raid5: Operation continuing on %d devices.\n", - bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); + printk (KERN_ALERT + "raid5: Disk failure on %s, disabling device.\n" + "raid5: Operation continuing on %d devices.\n", + bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); } } @@ -1315,8 +1320,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; break; default: - printk(KERN_CRIT "raid6: unsupported algorithm %d\n", - conf->algorithm); + printk (KERN_CRIT "raid6: unsupported algorithm %d\n", + conf->algorithm); } break; } @@ -1391,8 +1396,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) } break; default: - printk(KERN_CRIT "raid6: unsupported algorithm %d\n", - conf->algorithm); + printk (KERN_CRIT "raid6: unsupported algorithm %d\n", + conf->algorithm); } break; } @@ -1400,7 +1405,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) chunk_number = stripe * data_disks + i; r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; - check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); + check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { printk(KERN_ERR "compute_blocknr: map not correct\n"); return 0; @@ -4007,13 +4012,6 @@ static int run(mddev_t *mddev) return -EIO; } - if (mddev->chunk_size < PAGE_SIZE) { - printk(KERN_ERR "md/raid5: chunk_size must be at least " - "PAGE_SIZE but %d < %ld\n", - mddev->chunk_size, PAGE_SIZE); - return -EINVAL; - } - if (mddev->reshape_position != MaxSector) { /* Check that we can continue the reshape. * Currently only disks can change, it must @@ -4291,7 +4289,7 @@ static int stop(mddev_t *mddev) } #ifdef DEBUG -static void print_sh(struct seq_file *seq, struct stripe_head *sh) +static void print_sh (struct seq_file *seq, struct stripe_head *sh) { int i; @@ -4307,7 +4305,7 @@ static void print_sh(struct seq_file *seq, struct stripe_head *sh) seq_printf(seq, "\n"); } -static void printall(struct seq_file *seq, raid5_conf_t *conf) +static void printall (struct seq_file *seq, raid5_conf_t *conf) { struct stripe_head *sh; struct hlist_node *hn; @@ -4325,7 +4323,7 @@ static void printall(struct seq_file *seq, raid5_conf_t *conf) } #endif -static void status(struct seq_file *seq, mddev_t *mddev) +static void status (struct seq_file *seq, mddev_t *mddev) { raid5_conf_t *conf = (raid5_conf_t *) mddev->private; int i; diff --git a/trunk/drivers/md/raid6.h b/trunk/drivers/md/raid6.h index 98dcde88470e..31cbee71365f 100644 --- a/trunk/drivers/md/raid6.h +++ b/trunk/drivers/md/raid6.h @@ -18,6 +18,15 @@ /* Set to 1 to use kernel-wide empty_zero_page */ #define RAID6_USE_EMPTY_ZERO_PAGE 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index 4952aeb5dd80..8fa91f846d59 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -103,56 +103,6 @@ IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt); -/* Mauro Carvalho Chehab */ -IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { - [0x00] = KEY_POWER2, - [0x2e] = KEY_DOT, /* '.' */ - [0x01] = KEY_MODE, /* TV/FM */ - - [0x05] = KEY_1, - [0x06] = KEY_2, - [0x07] = KEY_3, - [0x09] = KEY_4, - [0x0a] = KEY_5, - [0x0b] = KEY_6, - [0x0d] = KEY_7, - [0x0e] = KEY_8, - [0x0f] = KEY_9, - [0x11] = KEY_0, - - [0x13] = KEY_RIGHT, /* -> */ - [0x12] = KEY_LEFT, /* <- */ - - [0x17] = KEY_SLEEP, /* Capturar Imagem */ - [0x10] = KEY_SHUFFLE, /* Amostra */ - - /* FIXME: The keys bellow aren't ok */ - - [0x43] = KEY_CHANNELUP, - [0x42] = KEY_CHANNELDOWN, - [0x1f] = KEY_VOLUMEUP, - [0x1e] = KEY_VOLUMEDOWN, - [0x0c] = KEY_ENTER, - - [0x14] = KEY_MUTE, - [0x08] = KEY_AUDIO, - - [0x03] = KEY_TEXT, - [0x04] = KEY_EPG, - [0x2b] = KEY_TV2, /* TV2 */ - - [0x1d] = KEY_RED, - [0x1c] = KEY_YELLOW, - [0x41] = KEY_GREEN, - [0x40] = KEY_BLUE, - - [0x1a] = KEY_PLAYPAUSE, - [0x19] = KEY_RECORD, - [0x18] = KEY_PLAY, - [0x1b] = KEY_STOP, -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); - /* Attila Kondoros */ IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { @@ -517,8 +467,7 @@ EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci); /* ---------------------------------------------------------------------- */ -/* MSI TV@nywhere MASTER remote */ - +/* MSI TV@nywhere remote */ IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { /* Keys 0 to 9 */ [ 0x00 ] = KEY_0, @@ -552,95 +501,6 @@ EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere); /* ---------------------------------------------------------------------- */ -/* - Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card - is marked "KS003". The controller is I2C at address 0x30, but does not seem - to respond to probes until a read is performed from a valid device. - I don't know why... - - Note: This remote may be of similar or identical design to the - Pixelview remote (?). The raw codes and duplicate button codes - appear to be the same. - - Henry Wong - Some changes to formatting and keycodes by Mark Schultz - -*/ - -IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = { - -/* ---- Remote Button Layout ---- - - POWER SOURCE SCAN MUTE - TV/FM 1 2 3 - |> 4 5 6 - <| 7 8 9 - ^^UP 0 + RECALL - vvDN RECORD STOP PLAY - - MINIMIZE ZOOM - - CH+ - VOL- VOL+ - CH- - - SNAPSHOT MTS - - << FUNC >> RESET -*/ - - [0x01] = KEY_KP1, /* 1 */ - [0x0b] = KEY_KP2, /* 2 */ - [0x1b] = KEY_KP3, /* 3 */ - [0x05] = KEY_KP4, /* 4 */ - [0x09] = KEY_KP5, /* 5 */ - [0x15] = KEY_KP6, /* 6 */ - [0x06] = KEY_KP7, /* 7 */ - [0x0a] = KEY_KP8, /* 8 */ - [0x12] = KEY_KP9, /* 9 */ - [0x02] = KEY_KP0, /* 0 */ - [0x10] = KEY_KPPLUS, /* + */ - [0x13] = KEY_AGAIN, /* Recall */ - - [0x1e] = KEY_POWER, /* Power */ - [0x07] = KEY_TUNER, /* Source */ - [0x1c] = KEY_SEARCH, /* Scan */ - [0x18] = KEY_MUTE, /* Mute */ - - [0x03] = KEY_RADIO, /* TV/FM */ - /* The next four keys are duplicates that appear to send the - same IR code as Ch+, Ch-, >>, and << . The raw code assigned - to them is the actual code + 0x20 - they will never be - detected as such unless some way is discovered to distinguish - these buttons from those that have the same code. */ - [0x3f] = KEY_RIGHT, /* |> and Ch+ */ - [0x37] = KEY_LEFT, /* <| and Ch- */ - [0x2c] = KEY_UP, /* ^^Up and >> */ - [0x24] = KEY_DOWN, /* vvDn and << */ - - [0x00] = KEY_RECORD, /* Record */ - [0x08] = KEY_STOP, /* Stop */ - [0x11] = KEY_PLAY, /* Play */ - - [0x0f] = KEY_CLOSE, /* Minimize */ - [0x19] = KEY_ZOOM, /* Zoom */ - [0x1a] = KEY_SHUFFLE, /* Snapshot */ - [0x0d] = KEY_LANGUAGE, /* MTS */ - - [0x14] = KEY_VOLUMEDOWN, /* Vol- */ - [0x16] = KEY_VOLUMEUP, /* Vol+ */ - [0x17] = KEY_CHANNELDOWN, /* Ch- */ - [0x1f] = KEY_CHANNELUP, /* Ch+ */ - - [0x04] = KEY_REWIND, /* << */ - [0x0e] = KEY_MENU, /* Function */ - [0x0c] = KEY_FASTFORWARD, /* >> */ - [0x1d] = KEY_RESTART, /* Reset */ -}; -EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus); - -/* ---------------------------------------------------------------------- */ - /* Cinergy 1400 DVB-T */ IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { [ 0x01 ] = KEY_POWER, @@ -1932,60 +1792,11 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = { [ 0x41 ] = KEY_GREEN, /* AP2 */ [ 0x47 ] = KEY_YELLOW, /* AP3 */ [ 0x57 ] = KEY_BLUE, /* AP4 */ -}; -EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); -/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton - Mauro Carvalho Chehab */ -IR_KEYTAB_TYPE ir_codes_encore_enltv2[IR_KEYTAB_SIZE] = { - [0x4c] = KEY_POWER2, - [0x4a] = KEY_TUNER, - [0x40] = KEY_1, - [0x60] = KEY_2, - [0x50] = KEY_3, - [0x70] = KEY_4, - [0x48] = KEY_5, - [0x68] = KEY_6, - [0x58] = KEY_7, - [0x78] = KEY_8, - [0x44] = KEY_9, - [0x54] = KEY_0, - - [0x64] = KEY_LAST, /* +100 */ - [0x4e] = KEY_AGAIN, /* Recall */ - - [0x6c] = KEY_SWITCHVIDEOMODE, /* Video Source */ - [0x5e] = KEY_MENU, - [0x56] = KEY_SCREEN, - [0x7a] = KEY_SETUP, - - [0x46] = KEY_MUTE, - [0x5c] = KEY_MODE, /* Stereo */ - [0x74] = KEY_INFO, - [0x7c] = KEY_CLEAR, - - [0x55] = KEY_UP, - [0x49] = KEY_DOWN, - [0x7e] = KEY_LEFT, - [0x59] = KEY_RIGHT, - [0x6a] = KEY_ENTER, - - [0x42] = KEY_VOLUMEUP, - [0x62] = KEY_VOLUMEDOWN, - [0x52] = KEY_CHANNELUP, - [0x72] = KEY_CHANNELDOWN, - - [0x41] = KEY_RECORD, - [0x51] = KEY_SHUFFLE, /* Snapshot */ - [0x75] = KEY_TIME, /* Timeshift */ - [0x71] = KEY_TV2, /* PIP */ - - [0x45] = KEY_REWIND, - [0x6f] = KEY_PAUSE, - [0x7d] = KEY_FORWARD, - [0x79] = KEY_STOP, + }; -EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2); + +EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); /* for the Technotrend 1500 bundled remotes (grey and black): */ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = { @@ -2428,86 +2239,3 @@ IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { [0x2a] = KEY_MENU, }; EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d); - -/* Encore ENLTV-FM v5.3 - Mauro Carvalho Chehab - */ -IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE] = { - [0x10] = KEY_POWER2, - [0x06] = KEY_MUTE, - - [0x09] = KEY_1, - [0x1d] = KEY_2, - [0x1f] = KEY_3, - [0x19] = KEY_4, - [0x1b] = KEY_5, - [0x11] = KEY_6, - [0x17] = KEY_7, - [0x12] = KEY_8, - [0x16] = KEY_9, - [0x48] = KEY_0, - - [0x04] = KEY_LIST, /* -/-- */ - [0x40] = KEY_LAST, /* recall */ - - [0x02] = KEY_MODE, /* TV/AV */ - [0x05] = KEY_SHUFFLE, /* SNAPSHOT */ - - [0x4c] = KEY_CHANNELUP, /* UP */ - [0x00] = KEY_CHANNELDOWN, /* DOWN */ - [0x0d] = KEY_VOLUMEUP, /* RIGHT */ - [0x15] = KEY_VOLUMEDOWN, /* LEFT */ - [0x49] = KEY_ENTER, /* OK */ - - [0x54] = KEY_RECORD, - [0x4d] = KEY_PLAY, /* pause */ - - [0x1e] = KEY_UP, /* video setting */ - [0x0e] = KEY_RIGHT, /* <- */ - [0x1a] = KEY_LEFT, /* -> */ - - [0x0a] = KEY_DOWN, /* video default */ - [0x0c] = KEY_ZOOM, /* hide pannel */ - [0x47] = KEY_SLEEP, /* shutdown */ -}; -EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53); - -/* Zogis Real Audio 220 - 32 keys IR */ -IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE] = { - [0x1c] = KEY_RADIO, - [0x12] = KEY_POWER2, - - [0x01] = KEY_1, - [0x02] = KEY_2, - [0x03] = KEY_3, - [0x04] = KEY_4, - [0x05] = KEY_5, - [0x06] = KEY_6, - [0x07] = KEY_7, - [0x08] = KEY_8, - [0x09] = KEY_9, - [0x00] = KEY_0, - - [0x0c] = KEY_VOLUMEUP, - [0x18] = KEY_VOLUMEDOWN, - [0x0b] = KEY_CHANNELUP, - [0x15] = KEY_CHANNELDOWN, - [0x16] = KEY_ENTER, - - [0x11] = KEY_LIST, /* Source */ - [0x0d] = KEY_AUDIO, /* stereo */ - - [0x0f] = KEY_PREVIOUS, /* Prev */ - [0x1b] = KEY_PAUSE, /* Timeshift */ - [0x1a] = KEY_NEXT, /* Next */ - - [0x0e] = KEY_STOP, - [0x1f] = KEY_PLAY, - [0x1e] = KEY_PLAYPAUSE, /* Pause */ - - [0x1d] = KEY_RECORD, - [0x13] = KEY_MUTE, - [0x19] = KEY_SHUFFLE, /* Snapshot */ - -}; -EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys); diff --git a/trunk/drivers/media/common/saa7146_core.c b/trunk/drivers/media/common/saa7146_core.c index d599d360da3f..d01965e96927 100644 --- a/trunk/drivers/media/common/saa7146_core.c +++ b/trunk/drivers/media/common/saa7146_core.c @@ -234,7 +234,7 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) { __le32 *cpu; - dma_addr_t dma_addr = 0; + dma_addr_t dma_addr; cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr); if (NULL == cpu) { diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c index 5b34c134aa25..cf6a817d5059 100644 --- a/trunk/drivers/media/common/saa7146_fops.c +++ b/trunk/drivers/media/common/saa7146_fops.c @@ -533,7 +533,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, memcpy(vfd, &device_template, sizeof(struct video_device)); strlcpy(vfd->name, name, sizeof(vfd->name)); vfd->release = video_device_release; - video_set_drvdata(vfd, dev); + vfd->priv = dev; // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr"); if (video_register_device(vfd, type, -1) < 0) { diff --git a/trunk/drivers/media/common/tuners/mt2060.c b/trunk/drivers/media/common/tuners/mt2060.c index 12206d75dd4e..1305b0e63ce5 100644 --- a/trunk/drivers/media/common/tuners/mt2060.c +++ b/trunk/drivers/media/common/tuners/mt2060.c @@ -170,9 +170,6 @@ static int mt2060_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame b[0] = REG_LO1B1; b[1] = 0xFF; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - mt2060_writeregs(priv,b,2); freq = params->frequency / 1000; // Hz -> kHz @@ -236,9 +233,6 @@ static int mt2060_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame i++; } while (i<10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - return ret; } @@ -302,35 +296,13 @@ static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) static int mt2060_init(struct dvb_frontend *fe) { struct mt2060_priv *priv = fe->tuner_priv; - int ret; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = mt2060_writereg(priv, REG_VGAG, - (priv->cfg->clock_out << 6) | 0x33); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - return ret; + return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x33); } static int mt2060_sleep(struct dvb_frontend *fe) { struct mt2060_priv *priv = fe->tuner_priv; - int ret; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = mt2060_writereg(priv, REG_VGAG, - (priv->cfg->clock_out << 6) | 0x30); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - return ret; + return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30); } static int mt2060_release(struct dvb_frontend *fe) @@ -372,9 +344,6 @@ struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter priv->i2c = i2c; priv->if1_freq = if1; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) { kfree(priv); return NULL; @@ -391,9 +360,6 @@ struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter mt2060_calibrate(priv); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - return fe; } EXPORT_SYMBOL(mt2060_attach); diff --git a/trunk/drivers/media/common/tuners/mxl5007t.c b/trunk/drivers/media/common/tuners/mxl5007t.c index 64379f2bf237..cb25e43502fe 100644 --- a/trunk/drivers/media/common/tuners/mxl5007t.c +++ b/trunk/drivers/media/common/tuners/mxl5007t.c @@ -979,6 +979,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, switch (instance) { case 0: goto fail; + break; case 1: /* new tuner instance */ state->config = cfg; diff --git a/trunk/drivers/media/common/tuners/tda18271-fe.c b/trunk/drivers/media/common/tuners/tda18271-fe.c index 1b48b5d0bf1e..93063c6fbbf6 100644 --- a/trunk/drivers/media/common/tuners/tda18271-fe.c +++ b/trunk/drivers/media/common/tuners/tda18271-fe.c @@ -1155,6 +1155,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, switch (instance) { case 0: goto fail; + break; case 1: /* new tuner instance */ priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; diff --git a/trunk/drivers/media/common/tuners/tda827x.c b/trunk/drivers/media/common/tuners/tda827x.c index 4a74f65e759a..8555d9cf9051 100644 --- a/trunk/drivers/media/common/tuners/tda827x.c +++ b/trunk/drivers/media/common/tuners/tda827x.c @@ -447,19 +447,17 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, else arg = 0; } - if (fe->callback) - fe->callback(priv->i2c_adap->algo_data, - DVB_FRONTEND_COMPONENT_TUNER, - gp_func, arg); + if (priv->cfg->tuner_callback) + priv->cfg->tuner_callback(priv->i2c_adap->algo_data, + gp_func, arg); buf[1] = high ? 0 : 1; if (priv->cfg->config == 2) buf[1] = high ? 1 : 0; i2c_transfer(priv->i2c_adap, &msg, 1); break; case 3: /* switch with GPIO of saa713x */ - if (fe->callback) - fe->callback(priv->i2c_adap->algo_data, - DVB_FRONTEND_COMPONENT_TUNER, 0, high); + if (priv->cfg->tuner_callback) + priv->cfg->tuner_callback(priv->i2c_adap->algo_data, 0, high); break; } } diff --git a/trunk/drivers/media/common/tuners/tda827x.h b/trunk/drivers/media/common/tuners/tda827x.h index 7d72ce0a0c2d..7850a9a1dc8f 100644 --- a/trunk/drivers/media/common/tuners/tda827x.h +++ b/trunk/drivers/media/common/tuners/tda827x.h @@ -36,6 +36,7 @@ struct tda827x_config /* interface to tda829x driver */ unsigned int config; int switch_addr; + int (*tuner_callback) (void *dev, int command, int arg); void (*agcf)(struct dvb_frontend *fe); }; diff --git a/trunk/drivers/media/common/tuners/tda8290.c b/trunk/drivers/media/common/tuners/tda8290.c index c112bdd4e0f0..91204d3f282d 100644 --- a/trunk/drivers/media/common/tuners/tda8290.c +++ b/trunk/drivers/media/common/tuners/tda8290.c @@ -672,8 +672,10 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, priv->i2c_props.addr = i2c_addr; priv->i2c_props.adap = i2c_adap; priv->i2c_props.name = "tda829x"; - if (cfg) + if (cfg) { priv->cfg.config = cfg->lna_cfg; + priv->cfg.tuner_callback = cfg->tuner_callback; + } if (tda8290_probe(&priv->i2c_props) == 0) { priv->ver = TDA8290; diff --git a/trunk/drivers/media/common/tuners/tda8290.h b/trunk/drivers/media/common/tuners/tda8290.h index 7e288b26fcc3..aa074f3f0c07 100644 --- a/trunk/drivers/media/common/tuners/tda8290.h +++ b/trunk/drivers/media/common/tuners/tda8290.h @@ -22,6 +22,7 @@ struct tda829x_config { unsigned int lna_cfg; + int (*tuner_callback) (void *dev, int command, int arg); unsigned int probe_tuner:1; #define TDA829X_PROBE_TUNER 0 diff --git a/trunk/drivers/media/common/tuners/tda9887.c b/trunk/drivers/media/common/tuners/tda9887.c index ff1788cc5d48..72abf0b73486 100644 --- a/trunk/drivers/media/common/tuners/tda9887.c +++ b/trunk/drivers/media/common/tuners/tda9887.c @@ -686,6 +686,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, case 0: mutex_unlock(&tda9887_list_mutex); return NULL; + break; case 1: fe->analog_demod_priv = priv; priv->mode = T_STANDBY; diff --git a/trunk/drivers/media/common/tuners/tuner-simple.c b/trunk/drivers/media/common/tuners/tuner-simple.c index 2a1aac1cc755..aa773a658a2a 100644 --- a/trunk/drivers/media/common/tuners/tuner-simple.c +++ b/trunk/drivers/media/common/tuners/tuner-simple.c @@ -142,7 +142,6 @@ static inline int tuner_stereo(const int type, const int status) case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1256_IH3: case TUNER_LG_NTSC_TAPE: - case TUNER_TCL_MF02GIP_5N: return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); default: return status & TUNER_STEREO; @@ -495,7 +494,6 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) case TUNER_PHILIPS_FMD1216ME_MK3: case TUNER_LG_NTSC_TAPE: case TUNER_PHILIPS_FM1256_IH3: - case TUNER_TCL_MF02GIP_5N: buffer[3] = 0x19; break; case TUNER_TNF_5335MF: @@ -1040,6 +1038,7 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, case 0: mutex_unlock(&tuner_simple_list_mutex); return NULL; + break; case 1: fe->tuner_priv = priv; diff --git a/trunk/drivers/media/common/tuners/tuner-types.c b/trunk/drivers/media/common/tuners/tuner-types.c index 04961a1f44be..10dddca8b5d1 100644 --- a/trunk/drivers/media/common/tuners/tuner-types.c +++ b/trunk/drivers/media/common/tuners/tuner-types.c @@ -1216,23 +1216,6 @@ static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = { }, }; -/* ------------ TUNER_TCL_MF02GIP-5N-E - TCL MF02GIP-5N ------------ */ - -static struct tuner_range tuner_tcl_mf02gip_5n_ntsc_ranges[] = { - { 16 * 172.00 /*MHz*/, 0x8e, 0x01, }, - { 16 * 448.00 /*MHz*/, 0x8e, 0x02, }, - { 16 * 999.99 , 0x8e, 0x04, }, -}; - -static struct tuner_params tuner_tcl_mf02gip_5n_params[] = { - { - .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_tcl_mf02gip_5n_ntsc_ranges, - .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_ntsc_ranges), - .cb_first_if_lower_freq = 1, - }, -}; - /* --------------------------------------------------------------------- */ struct tunertype tuners[] = { @@ -1658,11 +1641,6 @@ struct tunertype tuners[] = { .name = "Xceive 5000 tuner", /* see xc5000.c for details */ }, - [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */ - .name = "TCL tuner MF02GIP-5N-E", - .params = tuner_tcl_mf02gip_5n_params, - .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params), - }, }; EXPORT_SYMBOL(tuners); diff --git a/trunk/drivers/media/common/tuners/tuner-xc2028.c b/trunk/drivers/media/common/tuners/tuner-xc2028.c index b65e6803e6c6..4dd1d2421cc5 100644 --- a/trunk/drivers/media/common/tuners/tuner-xc2028.c +++ b/trunk/drivers/media/common/tuners/tuner-xc2028.c @@ -71,6 +71,9 @@ struct firmware_properties { struct xc2028_data { struct list_head hybrid_tuner_instance_list; struct tuner_i2c_props i2c_props; + int (*tuner_callback) (void *dev, + int command, int arg); + void *video_dev; __u32 frequency; struct firmware_description *firm; @@ -489,23 +492,6 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, return i; } -static inline int do_tuner_callback(struct dvb_frontend *fe, int cmd, int arg) -{ - struct xc2028_data *priv = fe->tuner_priv; - - /* analog side (tuner-core) uses i2c_adap->algo_data. - * digital side is not guaranteed to have algo_data defined. - * - * digital side will always have fe->dvb defined. - * analog side (tuner-core) doesn't (yet) define fe->dvb. - */ - - return (!fe->callback) ? -EINVAL : - fe->callback(((fe->dvb) && (fe->dvb->priv)) ? - fe->dvb->priv : priv->i2c_props.adap->algo_data, - DVB_FRONTEND_COMPONENT_TUNER, cmd, arg); -} - static int load_firmware(struct dvb_frontend *fe, unsigned int type, v4l2_std_id *id) { @@ -544,7 +530,8 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, if (!size) { /* Special callback command received */ - rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0); + rc = priv->tuner_callback(priv->video_dev, + XC2028_TUNER_RESET, 0); if (rc < 0) { tuner_err("Error at RESET code %d\n", (*p) & 0x7f); @@ -555,7 +542,8 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, if (size >= 0xff00) { switch (size) { case 0xff00: - rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0); + rc = priv->tuner_callback(priv->video_dev, + XC2028_RESET_CLK, 0); if (rc < 0) { tuner_err("Error at RESET code %d\n", (*p) & 0x7f); @@ -727,7 +715,8 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); /* Reset is needed before loading firmware */ - rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0); + rc = priv->tuner_callback(priv->video_dev, + XC2028_TUNER_RESET, 0); if (rc < 0) goto fail; @@ -944,7 +933,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, The reset CLK is needed only with tm6000. Driver should work fine even if this fails. */ - do_tuner_callback(fe, XC2028_RESET_CLK, 1); + priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); msleep(10); @@ -1013,6 +1002,11 @@ static int xc2028_set_params(struct dvb_frontend *fe, tuner_dbg("%s called\n", __func__); + if (priv->ctrl.d2633) + type |= D2633; + else + type |= D2620; + switch(fe->ops.info.type) { case FE_OFDM: bw = p->u.ofdm.bandwidth; @@ -1027,8 +1021,10 @@ static int xc2028_set_params(struct dvb_frontend *fe, break; case FE_ATSC: bw = BANDWIDTH_6_MHZ; - /* The only ATSC firmware (at least on v2.7) is D2633 */ - type |= ATSC | D2633; + /* The only ATSC firmware (at least on v2.7) is D2633, + so overrides ctrl->d2633 */ + type |= ATSC| D2633; + type &= ~D2620; break; /* DVB-S is not supported */ default: @@ -1061,28 +1057,6 @@ static int xc2028_set_params(struct dvb_frontend *fe, tuner_err("error: bandwidth not supported.\n"); }; - /* - Selects between D2633 or D2620 firmware. - It doesn't make sense for ATSC, since it should be D2633 on all cases - */ - if (fe->ops.info.type != FE_ATSC) { - switch (priv->ctrl.type) { - case XC2028_D2633: - type |= D2633; - break; - case XC2028_D2620: - type |= D2620; - break; - case XC2028_AUTO: - default: - /* Zarlink seems to need D2633 */ - if (priv->ctrl.demod == XC3028_FE_ZARLINK456) - type |= D2633; - else - type |= D2620; - } - } - /* All S-code tables need a 200kHz shift */ if (priv->ctrl.demod) demod = priv->ctrl.demod + 200; @@ -1203,10 +1177,20 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, break; case 1: /* new tuner instance */ + priv->tuner_callback = cfg->callback; priv->ctrl.max_len = 13; mutex_init(&priv->lock); + /* analog side (tuner-core) uses i2c_adap->algo_data. + * digital side is not guaranteed to have algo_data defined. + * + * digital side will always have fe->dvb defined. + * analog side (tuner-core) doesn't (yet) define fe->dvb. + */ + priv->video_dev = ((fe->dvb) && (fe->dvb->priv)) ? + fe->dvb->priv : cfg->i2c_adap->algo_data; + fe->tuner_priv = priv; break; case 2: diff --git a/trunk/drivers/media/common/tuners/tuner-xc2028.h b/trunk/drivers/media/common/tuners/tuner-xc2028.h index 19de7928a74e..2c5b6282b569 100644 --- a/trunk/drivers/media/common/tuners/tuner-xc2028.h +++ b/trunk/drivers/media/common/tuners/tuner-xc2028.h @@ -24,28 +24,24 @@ #define XC3028_FE_ZARLINK456 4560 #define XC3028_FE_CHINA 5200 -enum firmware_type { - XC2028_AUTO = 0, /* By default, auto-detects */ - XC2028_D2633, - XC2028_D2620, -}; - struct xc2028_ctrl { char *fname; int max_len; unsigned int scode_table; unsigned int mts :1; + unsigned int d2633 :1; unsigned int input1:1; unsigned int vhfbw7:1; unsigned int uhfbw8:1; unsigned int demod; - enum firmware_type type:2; }; struct xc2028_config { struct i2c_adapter *i2c_adap; u8 i2c_addr; + void *video_dev; struct xc2028_ctrl *ctrl; + int (*callback) (void *dev, int command, int arg); }; /* xc2028 commands for callback */ diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index f9c2bb917f54..dcddfa803a75 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -30,7 +30,7 @@ #include "dvb_frontend.h" #include "xc5000.h" -#include "tuner-i2c.h" +#include "xc5000_priv.h" static int debug; module_param(debug, int, 0644); @@ -40,26 +40,12 @@ static int xc5000_load_fw_on_attach; module_param_named(init_fw, xc5000_load_fw_on_attach, int, 0644); MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization."); -static DEFINE_MUTEX(xc5000_list_mutex); -static LIST_HEAD(hybrid_tuner_instance_list); - #define dprintk(level,fmt, arg...) if (debug >= level) \ printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" #define XC5000_DEFAULT_FIRMWARE_SIZE 12332 -struct xc5000_priv { - struct tuner_i2c_props i2c_props; - struct list_head hybrid_tuner_instance_list; - - u32 if_khz; - u32 freq_hz; - u32 bandwidth; - u8 video_standard; - u8 rf_mode; -}; - /* Misc Defines */ #define MAX_TV_STANDARD 23 #define XC_MAX_I2C_WRITE_LENGTH 64 @@ -230,12 +216,9 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) dprintk(1, "%s()\n", __func__); - if (fe->callback) { - ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ? - fe->dvb->priv : - priv->i2c_props.adap->algo_data, - DVB_FRONTEND_COMPONENT_TUNER, - XC5000_TUNER_RESET, 0); + if (priv->cfg->tuner_callback) { + ret = priv->cfg->tuner_callback(priv->devptr, + XC5000_TUNER_RESET, 0); if (ret) printk(KERN_ERR "xc5000: reset failed\n"); } else @@ -526,13 +509,13 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) u8 buf[2] = { reg >> 8, reg & 0xff }; u8 bval[2] = { 0, 0 }; struct i2c_msg msg[2] = { - { .addr = priv->i2c_props.addr, + { .addr = priv->cfg->i2c_address, .flags = 0, .buf = &buf[0], .len = 2 }, - { .addr = priv->i2c_props.addr, + { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = &bval[0], .len = 2 }, }; - if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) { + if (i2c_transfer(priv->i2c, msg, 2) != 2) { printk(KERN_WARNING "xc5000: I2C read failed\n"); return -EREMOTEIO; } @@ -543,10 +526,10 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) { - struct i2c_msg msg = { .addr = priv->i2c_props.addr, + struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len }; - if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", (int)len); return -EREMOTEIO; @@ -556,10 +539,10 @@ static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) { - struct i2c_msg msg = { .addr = priv->i2c_props.addr, + struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = buf, .len = len }; - if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len); return -EREMOTEIO; } @@ -576,7 +559,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe) printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", XC5000_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c_props.adap->dev); + ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c->dev); if (ret) { printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); ret = XC_RESULT_RESET_FAILURE; @@ -692,10 +675,10 @@ static int xc5000_set_params(struct dvb_frontend *fe, return -EREMOTEIO; } - ret = xc_set_IF_frequency(priv, priv->if_khz); + ret = xc_set_IF_frequency(priv, priv->cfg->if_khz); if (ret != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n", - priv->if_khz); + priv->cfg->if_khz); return -EIO; } @@ -914,19 +897,9 @@ static int xc5000_init(struct dvb_frontend *fe) static int xc5000_release(struct dvb_frontend *fe) { - struct xc5000_priv *priv = fe->tuner_priv; - dprintk(1, "%s()\n", __func__); - - mutex_lock(&xc5000_list_mutex); - - if (priv) - hybrid_tuner_release_state(priv); - - mutex_unlock(&xc5000_list_mutex); - + kfree(fe->tuner_priv); fe->tuner_priv = NULL; - return 0; } @@ -951,43 +924,29 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - struct xc5000_config *cfg) + struct xc5000_config *cfg, void *devptr) { struct xc5000_priv *priv = NULL; - int instance; u16 id = 0; - dprintk(1, "%s(%d-%04x)\n", __func__, - i2c ? i2c_adapter_id(i2c) : -1, - cfg ? cfg->i2c_address : -1); - - mutex_lock(&xc5000_list_mutex); + dprintk(1, "%s()\n", __func__); - instance = hybrid_tuner_request_state(struct xc5000_priv, priv, - hybrid_tuner_instance_list, - i2c, cfg->i2c_address, "xc5000"); - switch (instance) { - case 0: - goto fail; - break; - case 1: - /* new tuner instance */ - priv->bandwidth = BANDWIDTH_6_MHZ; - priv->if_khz = cfg->if_khz; + priv = kzalloc(sizeof(struct xc5000_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; - fe->tuner_priv = priv; - break; - default: - /* existing tuner instance */ - fe->tuner_priv = priv; - break; - } + priv->cfg = cfg; + priv->bandwidth = BANDWIDTH_6_MHZ; + priv->i2c = i2c; + priv->devptr = devptr; /* Check if firmware has been loaded. It is possible that another instance of the driver has loaded the firmware. */ - if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) - goto fail; + if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) { + kfree(priv); + return NULL; + } switch(id) { case XC_PRODUCT_ID_FW_LOADED: @@ -1008,23 +967,19 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, printk(KERN_ERR "xc5000: Device not found at addr 0x%02x (0x%x)\n", cfg->i2c_address, id); - goto fail; + kfree(priv); + return NULL; } - mutex_unlock(&xc5000_list_mutex); - memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops, sizeof(struct dvb_tuner_ops)); + fe->tuner_priv = priv; + if (xc5000_load_fw_on_attach) xc5000_init(fe); return fe; -fail: - mutex_unlock(&xc5000_list_mutex); - - xc5000_release(fe); - return NULL; } EXPORT_SYMBOL(xc5000_attach); diff --git a/trunk/drivers/media/common/tuners/xc5000.h b/trunk/drivers/media/common/tuners/xc5000.h index cf1a558e0e7f..5389f740945a 100644 --- a/trunk/drivers/media/common/tuners/xc5000.h +++ b/trunk/drivers/media/common/tuners/xc5000.h @@ -30,6 +30,8 @@ struct i2c_adapter; struct xc5000_config { u8 i2c_address; u32 if_khz; + + int (*tuner_callback) (void *priv, int command, int arg); }; /* xc5000 callback command */ @@ -47,11 +49,13 @@ struct xc5000_config { (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - struct xc5000_config *cfg); + struct xc5000_config *cfg, + void *devptr); #else static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - struct xc5000_config *cfg) + struct xc5000_config *cfg, + void *devptr) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; diff --git a/trunk/drivers/media/common/tuners/xc5000_priv.h b/trunk/drivers/media/common/tuners/xc5000_priv.h new file mode 100644 index 000000000000..b2a0074c99c9 --- /dev/null +++ b/trunk/drivers/media/common/tuners/xc5000_priv.h @@ -0,0 +1,37 @@ +/* + * Driver for Xceive XC5000 "QAM/8VSB single chip tuner" + * + * Copyright (c) 2007 Steven Toth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef XC5000_PRIV_H +#define XC5000_PRIV_H + +struct xc5000_priv { + struct xc5000_config *cfg; + struct i2c_adapter *i2c; + + u32 freq_hz; + u32 bandwidth; + u8 video_standard; + u8 rf_mode; + + void *devptr; +}; + +#endif diff --git a/trunk/drivers/media/dvb/Kconfig b/trunk/drivers/media/dvb/Kconfig index 0bcd852576d6..8bc1445bd33b 100644 --- a/trunk/drivers/media/dvb/Kconfig +++ b/trunk/drivers/media/dvb/Kconfig @@ -20,6 +20,7 @@ comment "Supported USB Adapters" source "drivers/media/dvb/dvb-usb/Kconfig" source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" +source "drivers/media/dvb/cinergyT2/Kconfig" source "drivers/media/dvb/siano/Kconfig" comment "Supported FlexCopII (B2C2) Adapters" @@ -34,10 +35,6 @@ comment "Supported Pluto2 Adapters" depends on DVB_CORE && PCI && I2C source "drivers/media/dvb/pluto2/Kconfig" -comment "Supported SDMC DM1105 Adapters" - depends on DVB_CORE && PCI && I2C -source "drivers/media/dvb/dm1105/Kconfig" - comment "Supported DVB Frontends" depends on DVB_CORE source "drivers/media/dvb/frontends/Kconfig" diff --git a/trunk/drivers/media/dvb/Makefile b/trunk/drivers/media/dvb/Makefile index f91e9eb15e52..d6ba4d195201 100644 --- a/trunk/drivers/media/dvb/Makefile +++ b/trunk/drivers/media/dvb/Makefile @@ -2,4 +2,4 @@ # Makefile for the kernel multimedia device drivers. # -obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ +obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/ diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-dma.c b/trunk/drivers/media/dvb/b2c2/flexcop-dma.c index 26f0011a5078..a91ed28f03a4 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-dma.c @@ -10,7 +10,7 @@ int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) { u8 *tcpu; - dma_addr_t tdma = 0; + dma_addr_t tdma; if (size % 2) { err("dma buffersize has to be even."); diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 48762a2b9e42..6afbfbbef0ce 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -702,7 +702,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) } if (card->fe == NULL) - printk("dvb-bt8xx: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", card->bt->dev->vendor, card->bt->dev->device, card->bt->dev->subsystem_vendor, diff --git a/trunk/drivers/media/dvb/cinergyT2/Kconfig b/trunk/drivers/media/dvb/cinergyT2/Kconfig new file mode 100644 index 000000000000..c03513b2ccae --- /dev/null +++ b/trunk/drivers/media/dvb/cinergyT2/Kconfig @@ -0,0 +1,85 @@ +config DVB_CINERGYT2 + tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver" + depends on DVB_CORE && USB && INPUT + help + Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers + + Say Y if you own such a device and want to use it. + + +config DVB_CINERGYT2_TUNING + bool "sophisticated fine-tuning for CinergyT2 cards" + depends on DVB_CINERGYT2 + help + Here you can fine-tune some parameters of the CinergyT2 driver. + + Normally you don't need to touch this, but in exotic setups you + may fine-tune your setup and adjust e.g. DMA buffer sizes for + a particular application. + + +config DVB_CINERGYT2_STREAM_URB_COUNT + int "Number of queued USB Request Blocks for Highspeed Stream Transfers" + depends on DVB_CINERGYT2_TUNING + default "32" + help + USB Request Blocks for Highspeed Stream transfers are scheduled in + a queue for the Host Controller. + + Usually the default value is a safe choice. + + You may increase this number if you are using this device in a + Server Environment with many high-traffic USB Highspeed devices + sharing the same USB bus. + + +config DVB_CINERGYT2_STREAM_BUF_SIZE + int "Size of URB Stream Buffers for Highspeed Transfers" + depends on DVB_CINERGYT2_TUNING + default "512" + help + Should be a multiple of native buffer size of 512 bytes. + Default value is a safe choice. + + You may increase this number if you are using this device in a + Server Environment with many high-traffic USB Highspeed devices + sharing the same USB bus. + + +config DVB_CINERGYT2_QUERY_INTERVAL + int "Status update interval [milliseconds]" + depends on DVB_CINERGYT2_TUNING + default "250" + help + This is the interval for status readouts from the demodulator. + You may try lower values if you need more responsive signal quality + measurements. + + Please keep in mind that these updates cause traffic on the tuner + control bus and thus may or may not affect reception sensitivity. + + The default value should be a safe choice for common applications. + + +config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE + bool "Register the onboard IR Remote Control Receiver as Input Device" + depends on DVB_CINERGYT2_TUNING + default y + help + Enable this option if you want to use the onboard Infrared Remote + Control Receiver as Linux-Input device. + + Right now only the keycode table for the default Remote Control + delivered with the device is supported, please see the driver + source code to find out how to add support for other controls. + + +config DVB_CINERGYT2_RC_QUERY_INTERVAL + int "Infrared Remote Controller update interval [milliseconds]" + depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE + default "50" + help + If you have a very fast-repeating remote control you can try lower + values, for normal consumer receivers the default value should be + a safe choice. + diff --git a/trunk/drivers/media/dvb/cinergyT2/Makefile b/trunk/drivers/media/dvb/cinergyT2/Makefile new file mode 100644 index 000000000000..d762d8cb0cf1 --- /dev/null +++ b/trunk/drivers/media/dvb/cinergyT2/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o + +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c new file mode 100644 index 000000000000..a824f3719f81 --- /dev/null +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -0,0 +1,1105 @@ +/* + * TerraTec Cinergy T²/qanu USB2 DVB-T adapter. + * + * Copyright (C) 2004 Daniel Mack and + * Holger Waechtler + * + * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dmxdev.h" +#include "dvb_demux.h" +#include "dvb_net.h" + +#ifdef CONFIG_DVB_CINERGYT2_TUNING + #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT) + #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE) + #define QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_QUERY_INTERVAL) + #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE + #define RC_QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL) + #define ENABLE_RC (1) + #endif +#else + #define STREAM_URB_COUNT (32) + #define STREAM_BUF_SIZE (512) /* bytes */ + #define ENABLE_RC (1) + #define RC_QUERY_INTERVAL (50) /* milliseconds */ + #define QUERY_INTERVAL (333) /* milliseconds */ +#endif + +#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver" + +static int debug; +module_param_named(debug, debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +#define dprintk(level, args...) \ +do { \ + if ((debug & level)) { \ + printk("%s: %s(): ", KBUILD_MODNAME, \ + __func__); \ + printk(args); } \ +} while (0) + +enum cinergyt2_ep1_cmd { + CINERGYT2_EP1_PID_TABLE_RESET = 0x01, + CINERGYT2_EP1_PID_SETUP = 0x02, + CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03, + CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04, + CINERGYT2_EP1_GET_TUNER_STATUS = 0x05, + CINERGYT2_EP1_START_SCAN = 0x06, + CINERGYT2_EP1_CONTINUE_SCAN = 0x07, + CINERGYT2_EP1_GET_RC_EVENTS = 0x08, + CINERGYT2_EP1_SLEEP_MODE = 0x09 +}; + +struct dvbt_set_parameters_msg { + uint8_t cmd; + __le32 freq; + uint8_t bandwidth; + __le16 tps; + uint8_t flags; +} __attribute__((packed)); + +struct dvbt_get_status_msg { + __le32 freq; + uint8_t bandwidth; + __le16 tps; + uint8_t flags; + __le16 gain; + uint8_t snr; + __le32 viterbi_error_rate; + __le32 rs_error_rate; + __le32 uncorrected_block_count; + uint8_t lock_bits; + uint8_t prev_lock_bits; +} __attribute__((packed)); + +static struct dvb_frontend_info cinergyt2_fe_info = { + .name = DRIVER_NAME, + .type = FE_OFDM, + .frequency_min = 174000000, + .frequency_max = 862000000, + .frequency_stepsize = 166667, + .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS +}; + +struct cinergyt2 { + struct dvb_demux demux; + struct usb_device *udev; + struct mutex sem; + struct mutex wq_sem; + struct dvb_adapter adapter; + struct dvb_device *fedev; + struct dmxdev dmxdev; + struct dvb_net dvbnet; + + int streaming; + int sleeping; + + struct dvbt_set_parameters_msg param; + struct dvbt_get_status_msg status; + struct delayed_work query_work; + + wait_queue_head_t poll_wq; + int pending_fe_events; + int disconnect_pending; + unsigned int uncorrected_block_count; + atomic_t inuse; + + void *streambuf; + dma_addr_t streambuf_dmahandle; + struct urb *stream_urb [STREAM_URB_COUNT]; + +#ifdef ENABLE_RC + struct input_dev *rc_input_dev; + char phys[64]; + struct delayed_work rc_query_work; + int rc_input_event; + __le32 rc_last_code; + unsigned long last_event_jiffies; +#endif +}; + +enum { + CINERGYT2_RC_EVENT_TYPE_NONE = 0x00, + CINERGYT2_RC_EVENT_TYPE_NEC = 0x01, + CINERGYT2_RC_EVENT_TYPE_RC5 = 0x02 +}; + +struct cinergyt2_rc_event { + char type; + __le32 value; +} __attribute__((packed)); + +static const uint32_t rc_keys[] = { + CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xfb04eb04, KEY_3, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xfa05eb04, KEY_4, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf906eb04, KEY_5, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf807eb04, KEY_6, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf708eb04, KEY_7, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf609eb04, KEY_8, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf50aeb04, KEY_9, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf30ceb04, KEY_0, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf40beb04, KEY_VIDEO, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf20deb04, KEY_REFRESH, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf10eeb04, KEY_SELECT, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xf00feb04, KEY_EPG, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xef10eb04, KEY_UP, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xeb14eb04, KEY_DOWN, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xee11eb04, KEY_LEFT, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xec13eb04, KEY_RIGHT, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xed12eb04, KEY_OK, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xea15eb04, KEY_TEXT, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe916eb04, KEY_INFO, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe817eb04, KEY_RED, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe718eb04, KEY_GREEN, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe619eb04, KEY_YELLOW, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe51aeb04, KEY_BLUE, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe31ceb04, KEY_VOLUMEUP, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe11eeb04, KEY_VOLUMEDOWN, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe21deb04, KEY_MUTE, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe41beb04, KEY_CHANNELUP, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xe01feb04, KEY_CHANNELDOWN, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xbf40eb04, KEY_PAUSE, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xb34ceb04, KEY_PLAY, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xa758eb04, KEY_RECORD, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xab54eb04, KEY_PREVIOUS, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xb748eb04, KEY_STOP, + CINERGYT2_RC_EVENT_TYPE_NEC, 0xa35ceb04, KEY_NEXT +}; + +static int cinergyt2_command (struct cinergyt2 *cinergyt2, + char *send_buf, int send_buf_len, + char *recv_buf, int recv_buf_len) +{ + int actual_len; + char dummy; + int ret; + + ret = usb_bulk_msg(cinergyt2->udev, usb_sndbulkpipe(cinergyt2->udev, 1), + send_buf, send_buf_len, &actual_len, 1000); + + if (ret) + dprintk(1, "usb_bulk_msg (send) failed, err %i\n", ret); + + if (!recv_buf) + recv_buf = &dummy; + + ret = usb_bulk_msg(cinergyt2->udev, usb_rcvbulkpipe(cinergyt2->udev, 1), + recv_buf, recv_buf_len, &actual_len, 1000); + + if (ret) + dprintk(1, "usb_bulk_msg (read) failed, err %i\n", ret); + + return ret ? ret : actual_len; +} + +static void cinergyt2_control_stream_transfer (struct cinergyt2 *cinergyt2, int enable) +{ + char buf [] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 }; + cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0); +} + +static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep) +{ + char buf [] = { CINERGYT2_EP1_SLEEP_MODE, sleep ? 1 : 0 }; + cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0); + cinergyt2->sleeping = sleep; +} + +static void cinergyt2_stream_irq (struct urb *urb); + +static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb) +{ + int err; + + usb_fill_bulk_urb(urb, + cinergyt2->udev, + usb_rcvbulkpipe(cinergyt2->udev, 0x2), + urb->transfer_buffer, + STREAM_BUF_SIZE, + cinergyt2_stream_irq, + cinergyt2); + + if ((err = usb_submit_urb(urb, GFP_ATOMIC))) + dprintk(1, "urb submission failed (err = %i)!\n", err); + + return err; +} + +static void cinergyt2_stream_irq (struct urb *urb) +{ + struct cinergyt2 *cinergyt2 = urb->context; + + if (urb->actual_length > 0) + dvb_dmx_swfilter(&cinergyt2->demux, + urb->transfer_buffer, urb->actual_length); + + if (cinergyt2->streaming) + cinergyt2_submit_stream_urb(cinergyt2, urb); +} + +static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2) +{ + int i; + + for (i=0; istream_urb[i]); + + usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, + cinergyt2->streambuf, cinergyt2->streambuf_dmahandle); +} + +static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2) +{ + int i; + + cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, + GFP_KERNEL, &cinergyt2->streambuf_dmahandle); + if (!cinergyt2->streambuf) { + dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n"); + return -ENOMEM; + } + + memset(cinergyt2->streambuf, 0, STREAM_URB_COUNT*STREAM_BUF_SIZE); + + for (i=0; itransfer_buffer = cinergyt2->streambuf + i * STREAM_BUF_SIZE; + urb->transfer_buffer_length = STREAM_BUF_SIZE; + + cinergyt2->stream_urb[i] = urb; + } + + return 0; +} + +static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2) +{ + int i; + + cinergyt2_control_stream_transfer(cinergyt2, 0); + + for (i=0; istream_urb[i]); +} + +static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2) +{ + int i, err; + + for (i=0; istream_urb[i]))) { + cinergyt2_stop_stream_xfer(cinergyt2); + dprintk(1, "failed urb submission (%i: err = %i)!\n", i, err); + return err; + } + } + + cinergyt2_control_stream_transfer(cinergyt2, 1); + return 0; +} + +static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *demux = dvbdmxfeed->demux; + struct cinergyt2 *cinergyt2 = demux->priv; + + if (cinergyt2->disconnect_pending) + return -EAGAIN; + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + + if (cinergyt2->streaming == 0) + cinergyt2_start_stream_xfer(cinergyt2); + + cinergyt2->streaming++; + mutex_unlock(&cinergyt2->sem); + return 0; +} + +static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *demux = dvbdmxfeed->demux; + struct cinergyt2 *cinergyt2 = demux->priv; + + if (cinergyt2->disconnect_pending) + return -EAGAIN; + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + + if (--cinergyt2->streaming == 0) + cinergyt2_stop_stream_xfer(cinergyt2); + + mutex_unlock(&cinergyt2->sem); + return 0; +} + +/** + * convert linux-dvb frontend parameter set into TPS. + * See ETSI ETS-300744, section 4.6.2, table 9 for details. + * + * This function is probably reusable and may better get placed in a support + * library. + * + * We replace errornous fields by default TPS fields (the ones with value 0). + */ +static uint16_t compute_tps (struct dvb_frontend_parameters *p) +{ + struct dvb_ofdm_parameters *op = &p->u.ofdm; + uint16_t tps = 0; + + switch (op->code_rate_HP) { + case FEC_2_3: + tps |= (1 << 7); + break; + case FEC_3_4: + tps |= (2 << 7); + break; + case FEC_5_6: + tps |= (3 << 7); + break; + case FEC_7_8: + tps |= (4 << 7); + break; + case FEC_1_2: + case FEC_AUTO: + default: + /* tps |= (0 << 7) */; + } + + switch (op->code_rate_LP) { + case FEC_2_3: + tps |= (1 << 4); + break; + case FEC_3_4: + tps |= (2 << 4); + break; + case FEC_5_6: + tps |= (3 << 4); + break; + case FEC_7_8: + tps |= (4 << 4); + break; + case FEC_1_2: + case FEC_AUTO: + default: + /* tps |= (0 << 4) */; + } + + switch (op->constellation) { + case QAM_16: + tps |= (1 << 13); + break; + case QAM_64: + tps |= (2 << 13); + break; + case QPSK: + default: + /* tps |= (0 << 13) */; + } + + switch (op->transmission_mode) { + case TRANSMISSION_MODE_8K: + tps |= (1 << 0); + break; + case TRANSMISSION_MODE_2K: + default: + /* tps |= (0 << 0) */; + } + + switch (op->guard_interval) { + case GUARD_INTERVAL_1_16: + tps |= (1 << 2); + break; + case GUARD_INTERVAL_1_8: + tps |= (2 << 2); + break; + case GUARD_INTERVAL_1_4: + tps |= (3 << 2); + break; + case GUARD_INTERVAL_1_32: + default: + /* tps |= (0 << 2) */; + } + + switch (op->hierarchy_information) { + case HIERARCHY_1: + tps |= (1 << 10); + break; + case HIERARCHY_2: + tps |= (2 << 10); + break; + case HIERARCHY_4: + tps |= (3 << 10); + break; + case HIERARCHY_NONE: + default: + /* tps |= (0 << 10) */; + } + + return tps; +} + +static int cinergyt2_open (struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev = file->private_data; + struct cinergyt2 *cinergyt2 = dvbdev->priv; + int err = -EAGAIN; + + if (cinergyt2->disconnect_pending) + goto out; + err = mutex_lock_interruptible(&cinergyt2->wq_sem); + if (err) + goto out; + + err = mutex_lock_interruptible(&cinergyt2->sem); + if (err) + goto out_unlock1; + + if ((err = dvb_generic_open(inode, file))) + goto out_unlock2; + + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + cinergyt2_sleep(cinergyt2, 0); + schedule_delayed_work(&cinergyt2->query_work, HZ/2); + } + + atomic_inc(&cinergyt2->inuse); + +out_unlock2: + mutex_unlock(&cinergyt2->sem); +out_unlock1: + mutex_unlock(&cinergyt2->wq_sem); +out: + return err; +} + +static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) +{ + dvb_net_release(&cinergyt2->dvbnet); + dvb_dmxdev_release(&cinergyt2->dmxdev); + dvb_dmx_release(&cinergyt2->demux); + dvb_unregister_device(cinergyt2->fedev); + dvb_unregister_adapter(&cinergyt2->adapter); + + cinergyt2_free_stream_urbs(cinergyt2); + kfree(cinergyt2); +} + +static int cinergyt2_release (struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev = file->private_data; + struct cinergyt2 *cinergyt2 = dvbdev->priv; + + mutex_lock(&cinergyt2->wq_sem); + + if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { + cancel_rearming_delayed_work(&cinergyt2->query_work); + + mutex_lock(&cinergyt2->sem); + cinergyt2_sleep(cinergyt2, 1); + mutex_unlock(&cinergyt2->sem); + } + + mutex_unlock(&cinergyt2->wq_sem); + + if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { + warn("delayed unregister in release"); + cinergyt2_unregister(cinergyt2); + } + + return dvb_generic_release(inode, file); +} + +static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct *wait) +{ + struct dvb_device *dvbdev = file->private_data; + struct cinergyt2 *cinergyt2 = dvbdev->priv; + unsigned int mask = 0; + + if (cinergyt2->disconnect_pending) + return -EAGAIN; + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + + poll_wait(file, &cinergyt2->poll_wq, wait); + + if (cinergyt2->pending_fe_events != 0) + mask |= (POLLIN | POLLRDNORM | POLLPRI); + + mutex_unlock(&cinergyt2->sem); + + return mask; +} + + +static int cinergyt2_ioctl (struct inode *inode, struct file *file, + unsigned cmd, unsigned long arg) +{ + struct dvb_device *dvbdev = file->private_data; + struct cinergyt2 *cinergyt2 = dvbdev->priv; + struct dvbt_get_status_msg *stat = &cinergyt2->status; + fe_status_t status = 0; + + switch (cmd) { + case FE_GET_INFO: + return copy_to_user((void __user*) arg, &cinergyt2_fe_info, + sizeof(struct dvb_frontend_info)); + + case FE_READ_STATUS: + if (0xffff - le16_to_cpu(stat->gain) > 30) + status |= FE_HAS_SIGNAL; + if (stat->lock_bits & (1 << 6)) + status |= FE_HAS_LOCK; + if (stat->lock_bits & (1 << 5)) + status |= FE_HAS_SYNC; + if (stat->lock_bits & (1 << 4)) + status |= FE_HAS_CARRIER; + if (stat->lock_bits & (1 << 1)) + status |= FE_HAS_VITERBI; + + return copy_to_user((void __user*) arg, &status, sizeof(status)); + + case FE_READ_BER: + return put_user(le32_to_cpu(stat->viterbi_error_rate), + (__u32 __user *) arg); + + case FE_READ_SIGNAL_STRENGTH: + return put_user(0xffff - le16_to_cpu(stat->gain), + (__u16 __user *) arg); + + case FE_READ_SNR: + return put_user((stat->snr << 8) | stat->snr, + (__u16 __user *) arg); + + case FE_READ_UNCORRECTED_BLOCKS: + { + uint32_t unc_count; + + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + unc_count = cinergyt2->uncorrected_block_count; + cinergyt2->uncorrected_block_count = 0; + mutex_unlock(&cinergyt2->sem); + + /* UNC are already converted to host byte order... */ + return put_user(unc_count,(__u32 __user *) arg); + } + case FE_SET_FRONTEND: + { + struct dvbt_set_parameters_msg *param = &cinergyt2->param; + struct dvb_frontend_parameters p; + int err; + + if ((file->f_flags & O_ACCMODE) == O_RDONLY) + return -EPERM; + + if (copy_from_user(&p, (void __user*) arg, sizeof(p))) + return -EFAULT; + + if (cinergyt2->disconnect_pending) + return -EAGAIN; + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + + param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; + param->tps = cpu_to_le16(compute_tps(&p)); + param->freq = cpu_to_le32(p.frequency / 1000); + param->bandwidth = 8 - p.u.ofdm.bandwidth - BANDWIDTH_8_MHZ; + + stat->lock_bits = 0; + cinergyt2->pending_fe_events++; + wake_up_interruptible(&cinergyt2->poll_wq); + + err = cinergyt2_command(cinergyt2, + (char *) param, sizeof(*param), + NULL, 0); + + mutex_unlock(&cinergyt2->sem); + + return (err < 0) ? err : 0; + } + + case FE_GET_FRONTEND: + /** + * trivial to implement (see struct dvbt_get_status_msg). + * equivalent to FE_READ ioctls, but needs + * TPS -> linux-dvb parameter set conversion. Feel free + * to implement this and send us a patch if you need this + * functionality. + */ + break; + + case FE_GET_EVENT: + { + /** + * for now we only fill the status field. the parameters + * are trivial to fill as soon FE_GET_FRONTEND is done. + */ + struct dvb_frontend_event __user *e = (void __user *) arg; + if (cinergyt2->pending_fe_events == 0) { + if (file->f_flags & O_NONBLOCK) + return -EWOULDBLOCK; + wait_event_interruptible(cinergyt2->poll_wq, + cinergyt2->pending_fe_events > 0); + } + cinergyt2->pending_fe_events = 0; + return cinergyt2_ioctl(inode, file, FE_READ_STATUS, + (unsigned long) &e->status); + } + + default: + ; + } + + return -EINVAL; +} + +static int cinergyt2_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct dvb_device *dvbdev = file->private_data; + struct cinergyt2 *cinergyt2 = dvbdev->priv; + int ret = 0; + + lock_kernel(); + + if (vma->vm_flags & (VM_WRITE | VM_EXEC)) { + ret = -EPERM; + goto bailout; + } + + if (vma->vm_end > vma->vm_start + STREAM_URB_COUNT * STREAM_BUF_SIZE) { + ret = -EINVAL; + goto bailout; + } + + vma->vm_flags |= (VM_IO | VM_DONTCOPY); + vma->vm_file = file; + + ret = remap_pfn_range(vma, vma->vm_start, + virt_to_phys(cinergyt2->streambuf) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot) ? -EAGAIN : 0; +bailout: + unlock_kernel(); + return ret; +} + +static struct file_operations cinergyt2_fops = { + .owner = THIS_MODULE, + .ioctl = cinergyt2_ioctl, + .poll = cinergyt2_poll, + .open = cinergyt2_open, + .release = cinergyt2_release, + .mmap = cinergyt2_mmap +}; + +static struct dvb_device cinergyt2_fe_template = { + .users = ~0, + .writers = 1, + .readers = (~0)-1, + .fops = &cinergyt2_fops +}; + +#ifdef ENABLE_RC + +static void cinergyt2_query_rc (struct work_struct *work) +{ + struct cinergyt2 *cinergyt2 = + container_of(work, struct cinergyt2, rc_query_work.work); + char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS }; + struct cinergyt2_rc_event rc_events[12]; + int n, len, i; + + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + return; + + len = cinergyt2_command(cinergyt2, buf, sizeof(buf), + (char *) rc_events, sizeof(rc_events)); + if (len < 0) + goto out; + if (len == 0) { + if (time_after(jiffies, cinergyt2->last_event_jiffies + + msecs_to_jiffies(150))) { + /* stop key repeat */ + if (cinergyt2->rc_input_event != KEY_MAX) { + dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event); + input_report_key(cinergyt2->rc_input_dev, + cinergyt2->rc_input_event, 0); + input_sync(cinergyt2->rc_input_dev); + cinergyt2->rc_input_event = KEY_MAX; + } + cinergyt2->rc_last_code = cpu_to_le32(~0); + } + goto out; + } + cinergyt2->last_event_jiffies = jiffies; + + for (n = 0; n < (len / sizeof(rc_events[0])); n++) { + dprintk(1, "rc_events[%d].value = %x, type=%x\n", + n, le32_to_cpu(rc_events[n].value), rc_events[n].type); + + if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && + rc_events[n].value == cpu_to_le32(~0)) { + /* keyrepeat bit -> just repeat last rc_input_event */ + } else { + cinergyt2->rc_input_event = KEY_MAX; + for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) { + if (rc_keys[i + 0] == rc_events[n].type && + rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) { + cinergyt2->rc_input_event = rc_keys[i + 2]; + break; + } + } + } + + if (cinergyt2->rc_input_event != KEY_MAX) { + if (rc_events[n].value == cinergyt2->rc_last_code && + cinergyt2->rc_last_code != cpu_to_le32(~0)) { + /* emit a key-up so the double event is recognized */ + dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); + input_report_key(cinergyt2->rc_input_dev, + cinergyt2->rc_input_event, 0); + } + dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event); + input_report_key(cinergyt2->rc_input_dev, + cinergyt2->rc_input_event, 1); + input_sync(cinergyt2->rc_input_dev); + cinergyt2->rc_last_code = rc_events[n].value; + } + } + +out: + schedule_delayed_work(&cinergyt2->rc_query_work, + msecs_to_jiffies(RC_QUERY_INTERVAL)); + + mutex_unlock(&cinergyt2->sem); +} + +static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) +{ + struct input_dev *input_dev; + int i; + int err; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); + strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); + cinergyt2->rc_input_event = KEY_MAX; + cinergyt2->rc_last_code = cpu_to_le32(~0); + INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); + + input_dev->name = DRIVER_NAME " remote control"; + input_dev->phys = cinergyt2->phys; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) + set_bit(rc_keys[i + 2], input_dev->keybit); + input_dev->keycodesize = 0; + input_dev->keycodemax = 0; + input_dev->id.bustype = BUS_USB; + input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct); + input_dev->id.version = 1; + input_dev->dev.parent = &cinergyt2->udev->dev; + + err = input_register_device(input_dev); + if (err) { + input_free_device(input_dev); + return err; + } + + cinergyt2->rc_input_dev = input_dev; + schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); + + return 0; +} + +static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) +{ + cancel_rearming_delayed_work(&cinergyt2->rc_query_work); + input_unregister_device(cinergyt2->rc_input_dev); +} + +static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) +{ + cancel_rearming_delayed_work(&cinergyt2->rc_query_work); +} + +static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) +{ + schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); +} + +#else + +static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; } +static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { } +static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { } +static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { } + +#endif /* ENABLE_RC */ + +static void cinergyt2_query (struct work_struct *work) +{ + struct cinergyt2 *cinergyt2 = + container_of(work, struct cinergyt2, query_work.work); + char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; + struct dvbt_get_status_msg *s = &cinergyt2->status; + uint8_t lock_bits; + + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + return; + + lock_bits = s->lock_bits; + + cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); + + cinergyt2->uncorrected_block_count += + le32_to_cpu(s->uncorrected_block_count); + + if (lock_bits != s->lock_bits) { + wake_up_interruptible(&cinergyt2->poll_wq); + cinergyt2->pending_fe_events++; + } + + schedule_delayed_work(&cinergyt2->query_work, + msecs_to_jiffies(QUERY_INTERVAL)); + + mutex_unlock(&cinergyt2->sem); +} + +static int cinergyt2_probe (struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct cinergyt2 *cinergyt2; + int err; + + if (!(cinergyt2 = kzalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { + dprintk(1, "out of memory?!?\n"); + return -ENOMEM; + } + + usb_set_intfdata (intf, (void *) cinergyt2); + + mutex_init(&cinergyt2->sem); + mutex_init(&cinergyt2->wq_sem); + init_waitqueue_head (&cinergyt2->poll_wq); + INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query); + + cinergyt2->udev = interface_to_usbdev(intf); + cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; + + if (cinergyt2_alloc_stream_urbs (cinergyt2) < 0) { + dprintk(1, "unable to allocate stream urbs\n"); + kfree(cinergyt2); + return -ENOMEM; + } + + err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, + THIS_MODULE, &cinergyt2->udev->dev, + adapter_nr); + if (err < 0) { + kfree(cinergyt2); + return err; + } + + cinergyt2->demux.priv = cinergyt2; + cinergyt2->demux.filternum = 256; + cinergyt2->demux.feednum = 256; + cinergyt2->demux.start_feed = cinergyt2_start_feed; + cinergyt2->demux.stop_feed = cinergyt2_stop_feed; + cinergyt2->demux.dmx.capabilities = DMX_TS_FILTERING | + DMX_SECTION_FILTERING | + DMX_MEMORY_BASED_FILTERING; + + if ((err = dvb_dmx_init(&cinergyt2->demux)) < 0) { + dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err); + goto bailout; + } + + cinergyt2->dmxdev.filternum = cinergyt2->demux.filternum; + cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx; + cinergyt2->dmxdev.capabilities = 0; + + if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, &cinergyt2->adapter)) < 0) { + dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err); + goto bailout; + } + + if (dvb_net_init(&cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx)) + dprintk(1, "dvb_net_init() failed!\n"); + + dvb_register_device(&cinergyt2->adapter, &cinergyt2->fedev, + &cinergyt2_fe_template, cinergyt2, + DVB_DEVICE_FRONTEND); + + err = cinergyt2_register_rc(cinergyt2); + if (err) + goto bailout; + + return 0; + +bailout: + dvb_net_release(&cinergyt2->dvbnet); + dvb_dmxdev_release(&cinergyt2->dmxdev); + dvb_dmx_release(&cinergyt2->demux); + dvb_unregister_adapter(&cinergyt2->adapter); + cinergyt2_free_stream_urbs(cinergyt2); + kfree(cinergyt2); + return -ENOMEM; +} + +static void cinergyt2_disconnect (struct usb_interface *intf) +{ + struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); + + cinergyt2_unregister_rc(cinergyt2); + cancel_rearming_delayed_work(&cinergyt2->query_work); + wake_up_interruptible(&cinergyt2->poll_wq); + + cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); + cinergyt2->disconnect_pending = 1; + + if (!atomic_read(&cinergyt2->inuse)) + cinergyt2_unregister(cinergyt2); +} + +static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) +{ + struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); + + if (cinergyt2->disconnect_pending) + return -EAGAIN; + if (mutex_lock_interruptible(&cinergyt2->wq_sem)) + return -ERESTARTSYS; + + cinergyt2_suspend_rc(cinergyt2); + cancel_rearming_delayed_work(&cinergyt2->query_work); + + mutex_lock(&cinergyt2->sem); + if (cinergyt2->streaming) + cinergyt2_stop_stream_xfer(cinergyt2); + cinergyt2_sleep(cinergyt2, 1); + mutex_unlock(&cinergyt2->sem); + + mutex_unlock(&cinergyt2->wq_sem); + + return 0; +} + +static int cinergyt2_resume (struct usb_interface *intf) +{ + struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); + struct dvbt_set_parameters_msg *param = &cinergyt2->param; + int err = -EAGAIN; + + if (cinergyt2->disconnect_pending) + goto out; + err = mutex_lock_interruptible(&cinergyt2->wq_sem); + if (err) + goto out; + + err = mutex_lock_interruptible(&cinergyt2->sem); + if (err) + goto out_unlock1; + + if (!cinergyt2->sleeping) { + cinergyt2_sleep(cinergyt2, 0); + cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0); + if (cinergyt2->streaming) + cinergyt2_start_stream_xfer(cinergyt2); + schedule_delayed_work(&cinergyt2->query_work, HZ/2); + } + + cinergyt2_resume_rc(cinergyt2); + + mutex_unlock(&cinergyt2->sem); +out_unlock1: + mutex_unlock(&cinergyt2->wq_sem); +out: + return err; +} + +static const struct usb_device_id cinergyt2_table [] __devinitdata = { + { USB_DEVICE(0x0ccd, 0x0038) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(usb, cinergyt2_table); + +static struct usb_driver cinergyt2_driver = { + .name = "cinergyT2", + .probe = cinergyt2_probe, + .disconnect = cinergyt2_disconnect, + .suspend = cinergyt2_suspend, + .resume = cinergyt2_resume, + .id_table = cinergyt2_table +}; + +static int __init cinergyt2_init (void) +{ + int err; + + if ((err = usb_register(&cinergyt2_driver)) < 0) + dprintk(1, "usb_register() failed! (err %i)\n", err); + + return err; +} + +static void __exit cinergyt2_exit (void) +{ + usb_deregister(&cinergyt2_driver); +} + +module_init (cinergyt2_init); +module_exit (cinergyt2_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); diff --git a/trunk/drivers/media/dvb/dm1105/Kconfig b/trunk/drivers/media/dvb/dm1105/Kconfig deleted file mode 100644 index 1332301ef3ae..000000000000 --- a/trunk/drivers/media/dvb/dm1105/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -config DVB_DM1105 - tristate "SDMC DM1105 based PCI cards" - depends on DVB_CORE && PCI && I2C - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_STV0288 if !DVB_FE_CUSTOMISE - select DVB_STB6000 if !DVB_FE_CUSTOMISE - select DVB_CX24116 if !DVB_FE_CUSTOMISE - select DVB_SI21XX if !DVB_FE_CUSTOMISE - help - Support for cards based on the SDMC DM1105 PCI chip like - DvbWorld 2002 - - Since these cards have no MPEG decoder onboard, they transmit - only compressed MPEG data over the PCI bus, so you need - an external software decoder to watch TV on your computer. - - Say Y or M if you own such a device and want to use it. diff --git a/trunk/drivers/media/dvb/dm1105/Makefile b/trunk/drivers/media/dvb/dm1105/Makefile deleted file mode 100644 index 8ac28b0546af..000000000000 --- a/trunk/drivers/media/dvb/dm1105/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_DVB_DM1105) += dm1105.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends diff --git a/trunk/drivers/media/dvb/dm1105/dm1105.c b/trunk/drivers/media/dvb/dm1105/dm1105.c deleted file mode 100644 index f7321448b4b1..000000000000 --- a/trunk/drivers/media/dvb/dm1105/dm1105.c +++ /dev/null @@ -1,911 +0,0 @@ -/* - * dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip - * - * Copyright (C) 2008 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "demux.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dvb_net.h" -#include "dvbdev.h" -#include "dvb-pll.h" - -#include "stv0299.h" -#include "stv0288.h" -#include "stb6000.h" -#include "si21xx.h" -#include "cx24116.h" -#include "z0194a.h" - -/* ----------------------------------------------- */ -/* - * PCI ID's - */ -#ifndef PCI_VENDOR_ID_TRIGEM -#define PCI_VENDOR_ID_TRIGEM 0x109f -#endif -#ifndef PCI_DEVICE_ID_DM1105 -#define PCI_DEVICE_ID_DM1105 0x036f -#endif -#ifndef PCI_DEVICE_ID_DW2002 -#define PCI_DEVICE_ID_DW2002 0x2002 -#endif -#ifndef PCI_DEVICE_ID_DW2004 -#define PCI_DEVICE_ID_DW2004 0x2004 -#endif -/* ----------------------------------------------- */ -/* sdmc dm1105 registers */ - -/* TS Control */ -#define DM1105_TSCTR 0x00 -#define DM1105_DTALENTH 0x04 - -/* GPIO Interface */ -#define DM1105_GPIOVAL 0x08 -#define DM1105_GPIOCTR 0x0c - -/* PID serial number */ -#define DM1105_PIDN 0x10 - -/* Odd-even secret key select */ -#define DM1105_CWSEL 0x14 - -/* Host Command Interface */ -#define DM1105_HOST_CTR 0x18 -#define DM1105_HOST_AD 0x1c - -/* PCI Interface */ -#define DM1105_CR 0x30 -#define DM1105_RST 0x34 -#define DM1105_STADR 0x38 -#define DM1105_RLEN 0x3c -#define DM1105_WRP 0x40 -#define DM1105_INTCNT 0x44 -#define DM1105_INTMAK 0x48 -#define DM1105_INTSTS 0x4c - -/* CW Value */ -#define DM1105_ODD 0x50 -#define DM1105_EVEN 0x58 - -/* PID Value */ -#define DM1105_PID 0x60 - -/* IR Control */ -#define DM1105_IRCTR 0x64 -#define DM1105_IRMODE 0x68 -#define DM1105_SYSTEMCODE 0x6c -#define DM1105_IRCODE 0x70 - -/* Unknown Values */ -#define DM1105_ENCRYPT 0x74 -#define DM1105_VER 0x7c - -/* I2C Interface */ -#define DM1105_I2CCTR 0x80 -#define DM1105_I2CSTS 0x81 -#define DM1105_I2CDAT 0x82 -#define DM1105_I2C_RA 0x83 -/* ----------------------------------------------- */ -/* Interrupt Mask Bits */ - -#define INTMAK_TSIRQM 0x01 -#define INTMAK_HIRQM 0x04 -#define INTMAK_IRM 0x08 -#define INTMAK_ALLMASK (INTMAK_TSIRQM | \ - INTMAK_HIRQM | \ - INTMAK_IRM) -#define INTMAK_NONEMASK 0x00 - -/* Interrupt Status Bits */ -#define INTSTS_TSIRQ 0x01 -#define INTSTS_HIRQ 0x04 -#define INTSTS_IR 0x08 - -/* IR Control Bits */ -#define DM1105_IR_EN 0x01 -#define DM1105_SYS_CHK 0x02 -#define DM1105_REP_FLG 0x08 - -/* EEPROM addr */ -#define IIC_24C01_addr 0xa0 -/* Max board count */ -#define DM1105_MAX 0x04 - -#define DRIVER_NAME "dm1105" - -#define DM1105_DMA_PACKETS 47 -#define DM1105_DMA_PACKET_LENGTH (128*4) -#define DM1105_DMA_BYTES (128 * 4 * DM1105_DMA_PACKETS) - -/* GPIO's for LNB power control */ -#define DM1105_LNB_MASK 0x00000000 -#define DM1105_LNB_13V 0x00010100 -#define DM1105_LNB_18V 0x00000100 - -static int ir_debug; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static u16 ir_codes_dm1105_nec[128] = { - [0x0a] = KEY_Q, /*power*/ - [0x0c] = KEY_M, /*mute*/ - [0x11] = KEY_1, - [0x12] = KEY_2, - [0x13] = KEY_3, - [0x14] = KEY_4, - [0x15] = KEY_5, - [0x16] = KEY_6, - [0x17] = KEY_7, - [0x18] = KEY_8, - [0x19] = KEY_9, - [0x10] = KEY_0, - [0x1c] = KEY_PAGEUP, /*ch+*/ - [0x0f] = KEY_PAGEDOWN, /*ch-*/ - [0x1a] = KEY_O, /*vol+*/ - [0x0e] = KEY_Z, /*vol-*/ - [0x04] = KEY_R, /*rec*/ - [0x09] = KEY_D, /*fav*/ - [0x08] = KEY_BACKSPACE, /*rewind*/ - [0x07] = KEY_A, /*fast*/ - [0x0b] = KEY_P, /*pause*/ - [0x02] = KEY_ESC, /*cancel*/ - [0x03] = KEY_G, /*tab*/ - [0x00] = KEY_UP, /*up*/ - [0x1f] = KEY_ENTER, /*ok*/ - [0x01] = KEY_DOWN, /*down*/ - [0x05] = KEY_C, /*cap*/ - [0x06] = KEY_S, /*stop*/ - [0x40] = KEY_F, /*full*/ - [0x1e] = KEY_W, /*tvmode*/ - [0x1b] = KEY_B, /*recall*/ -}; - -/* infrared remote control */ -struct infrared { - u16 key_map[128]; - struct input_dev *input_dev; - char input_phys[32]; - struct tasklet_struct ir_tasklet; - u32 ir_command; -}; - -struct dm1105dvb { - /* pci */ - struct pci_dev *pdev; - u8 __iomem *io_mem; - - /* ir */ - struct infrared ir; - - /* dvb */ - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - struct dmxdev dmxdev; - struct dvb_adapter dvb_adapter; - struct dvb_demux demux; - struct dvb_frontend *fe; - struct dvb_net dvbnet; - unsigned int full_ts_users; - - /* i2c */ - struct i2c_adapter i2c_adap; - - /* dma */ - dma_addr_t dma_addr; - unsigned char *ts_buf; - u32 wrp; - u32 buffer_size; - unsigned int PacketErrorCount; - unsigned int dmarst; - spinlock_t lock; - -}; - -#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) - -static struct dm1105dvb *dm1105dvb_local; - -static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct dm1105dvb *dm1105dvb ; - - int addr, rc, i, j, k, len, byte, data; - u8 status; - - dm1105dvb = i2c_adap->algo_data; - for (i = 0; i < num; i++) { - outb(0x00, dm_io_mem(DM1105_I2CCTR)); - if (msgs[i].flags & I2C_M_RD) { - /* read bytes */ - addr = msgs[i].addr << 1; - addr |= 1; - outb(addr, dm_io_mem(DM1105_I2CDAT)); - for (byte = 0; byte < msgs[i].len; byte++) - outb(0, dm_io_mem(DM1105_I2CDAT + byte + 1)); - - outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); - for (j = 0; j < 55; j++) { - mdelay(10); - status = inb(dm_io_mem(DM1105_I2CSTS)); - if ((status & 0xc0) == 0x40) - break; - } - if (j >= 55) - return -1; - - for (byte = 0; byte < msgs[i].len; byte++) { - rc = inb(dm_io_mem(DM1105_I2CDAT + byte + 1)); - if (rc < 0) - goto err; - msgs[i].buf[byte] = rc; - } - } else { - if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) { - /* prepaired for cx24116 firmware */ - /* Write in small blocks */ - len = msgs[i].len - 1; - k = 1; - do { - outb(msgs[i].addr << 1, dm_io_mem(DM1105_I2CDAT)); - outb(0xf7, dm_io_mem(DM1105_I2CDAT + 1)); - for (byte = 0; byte < (len > 48 ? 48 : len); byte++) { - data = msgs[i].buf[k+byte]; - outb(data, dm_io_mem(DM1105_I2CDAT + byte + 2)); - } - outb(0x82 + (len > 48 ? 48 : len), dm_io_mem(DM1105_I2CCTR)); - for (j = 0; j < 25; j++) { - mdelay(10); - status = inb(dm_io_mem(DM1105_I2CSTS)); - if ((status & 0xc0) == 0x40) - break; - } - - if (j >= 25) - return -1; - - k += 48; - len -= 48; - } while (len > 0); - } else { - /* write bytes */ - outb(msgs[i].addr<<1, dm_io_mem(DM1105_I2CDAT)); - for (byte = 0; byte < msgs[i].len; byte++) { - data = msgs[i].buf[byte]; - outb(data, dm_io_mem(DM1105_I2CDAT + byte + 1)); - } - outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); - for (j = 0; j < 25; j++) { - mdelay(10); - status = inb(dm_io_mem(DM1105_I2CSTS)); - if ((status & 0xc0) == 0x40) - break; - } - - if (j >= 25) - return -1; - } - } - } - return num; - err: - return rc; -} - -static u32 functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm dm1105_algo = { - .master_xfer = dm1105_i2c_xfer, - .functionality = functionality, -}; - -static inline struct dm1105dvb *feed_to_dm1105dvb(struct dvb_demux_feed *feed) -{ - return container_of(feed->demux, struct dm1105dvb, demux); -} - -static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) -{ - return container_of(fe->dvb, struct dm1105dvb, dvb_adapter); -} - -static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); - - if (voltage == SEC_VOLTAGE_18) { - outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); - outl(DM1105_LNB_18V, dm_io_mem(DM1105_GPIOVAL)); - } else { - /*LNB ON-13V by default!*/ - outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); - outl(DM1105_LNB_13V, dm_io_mem(DM1105_GPIOVAL)); - } - - return 0; -} - -static void dm1105dvb_set_dma_addr(struct dm1105dvb *dm1105dvb) -{ - outl(cpu_to_le32(dm1105dvb->dma_addr), dm_io_mem(DM1105_STADR)); -} - -static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb) -{ - dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr); - - return pci_dma_mapping_error(dm1105dvb->pdev, dm1105dvb->dma_addr); -} - -static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb) -{ - pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr); -} - -static void __devinit dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb) -{ - outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK)); - outb(1, dm_io_mem(DM1105_CR)); -} - -static void dm1105dvb_disable_irqs(struct dm1105dvb *dm1105dvb) -{ - outb(INTMAK_IRM, dm_io_mem(DM1105_INTMAK)); - outb(0, dm_io_mem(DM1105_CR)); -} - -static int dm1105dvb_start_feed(struct dvb_demux_feed *f) -{ - struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); - - if (dm1105dvb->full_ts_users++ == 0) - dm1105dvb_enable_irqs(dm1105dvb); - - return 0; -} - -static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) -{ - struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); - - if (--dm1105dvb->full_ts_users == 0) - dm1105dvb_disable_irqs(dm1105dvb); - - return 0; -} - -/* ir tasklet */ -static void dm1105_emit_key(unsigned long parm) -{ - struct infrared *ir = (struct infrared *) parm; - u32 ircom = ir->ir_command; - u8 data; - u16 keycode; - - data = (ircom >> 8) & 0x7f; - - input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data); - input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); - keycode = ir->key_map[data]; - - if (!keycode) - return; - - input_event(ir->input_dev, EV_KEY, keycode, 1); - input_sync(ir->input_dev); - input_event(ir->input_dev, EV_KEY, keycode, 0); - input_sync(ir->input_dev); - -} - -static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) -{ - struct dm1105dvb *dm1105dvb = dev_id; - unsigned int piece; - unsigned int nbpackets; - u32 command; - u32 nextwrp; - u32 oldwrp; - - /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ - unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS)); - outb(intsts, dm_io_mem(DM1105_INTSTS)); - - switch (intsts) { - case INTSTS_TSIRQ: - case (INTSTS_TSIRQ | INTSTS_IR): - nextwrp = inl(dm_io_mem(DM1105_WRP)) - - inl(dm_io_mem(DM1105_STADR)) ; - oldwrp = dm1105dvb->wrp; - spin_lock(&dm1105dvb->lock); - if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { - dm1105dvb->PacketErrorCount++; - /* bad packet found */ - if ((dm1105dvb->PacketErrorCount >= 2) && - (dm1105dvb->dmarst == 0)) { - outb(1, dm_io_mem(DM1105_RST)); - dm1105dvb->wrp = 0; - dm1105dvb->PacketErrorCount = 0; - dm1105dvb->dmarst = 0; - spin_unlock(&dm1105dvb->lock); - return IRQ_HANDLED; - } - } - if (nextwrp < oldwrp) { - piece = dm1105dvb->buffer_size - oldwrp; - memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp); - nbpackets = (piece + nextwrp)/188; - } else { - nbpackets = (nextwrp - oldwrp)/188; - } - dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets); - dm1105dvb->wrp = nextwrp; - spin_unlock(&dm1105dvb->lock); - break; - case INTSTS_IR: - command = inl(dm_io_mem(DM1105_IRCODE)); - if (ir_debug) - printk("dm1105: received byte 0x%04x\n", command); - - dm1105dvb->ir.ir_command = command; - tasklet_schedule(&dm1105dvb->ir.ir_tasklet); - break; - } - return IRQ_HANDLED; - - -} - -/* register with input layer */ -static void input_register_keys(struct infrared *ir) -{ - int i; - - memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); - - for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) - set_bit(ir->key_map[i], ir->input_dev->keybit); - - ir->input_dev->keycode = ir->key_map; - ir->input_dev->keycodesize = sizeof(ir->key_map[0]); - ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); -} - -int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) -{ - struct input_dev *input_dev; - int err; - - dm1105dvb_local = dm1105; - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - dm1105->ir.input_dev = input_dev; - snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), - "pci-%s/ir0", pci_name(dm1105->pdev)); - - input_dev->evbit[0] = BIT(EV_KEY); - input_dev->name = "DVB on-card IR receiver"; - - input_dev->phys = dm1105->ir.input_phys; - input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 2; - if (dm1105->pdev->subsystem_vendor) { - input_dev->id.vendor = dm1105->pdev->subsystem_vendor; - input_dev->id.product = dm1105->pdev->subsystem_device; - } else { - input_dev->id.vendor = dm1105->pdev->vendor; - input_dev->id.product = dm1105->pdev->device; - } - input_dev->dev.parent = &dm1105->pdev->dev; - /* initial keymap */ - memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map); - input_register_keys(&dm1105->ir); - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; - } - - tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir); - - return 0; -} - - -void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) -{ - tasklet_kill(&dm1105->ir.ir_tasklet); - input_unregister_device(dm1105->ir.input_dev); - -} - -static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) -{ - dm1105dvb_disable_irqs(dm1105dvb); - - outb(0, dm_io_mem(DM1105_HOST_CTR)); - - /*DATALEN 188,*/ - outb(188, dm_io_mem(DM1105_DTALENTH)); - /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/ - outw(0xc10a, dm_io_mem(DM1105_TSCTR)); - - /* map DMA and set address */ - dm1105dvb_dma_map(dm1105dvb); - dm1105dvb_set_dma_addr(dm1105dvb); - /* big buffer */ - outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN)); - outb(47, dm_io_mem(DM1105_INTCNT)); - - /* IR NEC mode enable */ - outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR)); - outb(0, dm_io_mem(DM1105_IRMODE)); - outw(0, dm_io_mem(DM1105_SYSTEMCODE)); - - return 0; -} - -static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) -{ - dm1105dvb_disable_irqs(dm1105dvb); - - /* IR disable */ - outb(0, dm_io_mem(DM1105_IRCTR)); - outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK)); - - dm1105dvb_dma_unmap(dm1105dvb); -} - -static struct stv0288_config earda_config = { - .demod_address = 0x68, - .min_delay_ms = 100, -}; - -static struct si21xx_config serit_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - -}; - -static struct cx24116_config serit_sp2633_config = { - .demod_address = 0x55, -}; - -static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) -{ - int ret; - - switch (dm1105dvb->pdev->subsystem_device) { - case PCI_DEVICE_ID_DW2002: - dm1105dvb->fe = dvb_attach( - stv0299_attach, &sharp_z0194a_config, - &dm1105dvb->i2c_adap); - - if (dm1105dvb->fe) { - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, - &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); - } - - if (!dm1105dvb->fe) { - dm1105dvb->fe = dvb_attach( - stv0288_attach, &earda_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) { - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, - &dm1105dvb->i2c_adap); - } - } - - if (!dm1105dvb->fe) { - dm1105dvb->fe = dvb_attach( - si21xx_attach, &serit_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - } - break; - case PCI_DEVICE_ID_DW2004: - dm1105dvb->fe = dvb_attach( - cx24116_attach, &serit_sp2633_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) - dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; - break; - } - - if (!dm1105dvb->fe) { - dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n"); - return -ENODEV; - } - - ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe); - if (ret < 0) { - if (dm1105dvb->fe->ops.release) - dm1105dvb->fe->ops.release(dm1105dvb->fe); - dm1105dvb->fe = NULL; - return ret; - } - - return 0; -} - -static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) -{ - static u8 command[1] = { 0x28 }; - - struct i2c_msg msg[] = { - { .addr = IIC_24C01_addr >> 1, .flags = 0, - .buf = command, .len = 1 }, - { .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD, - .buf = mac, .len = 6 }, - }; - - dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); - dev_info(&dm1105dvb->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -} - -static int __devinit dm1105_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct dm1105dvb *dm1105dvb; - struct dvb_adapter *dvb_adapter; - struct dvb_demux *dvbdemux; - struct dmx_demux *dmx; - int ret = -ENOMEM; - - dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); - if (!dm1105dvb) - goto out; - - dm1105dvb->pdev = pdev; - dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; - dm1105dvb->PacketErrorCount = 0; - dm1105dvb->dmarst = 0; - - ret = pci_enable_device(pdev); - if (ret < 0) - goto err_kfree; - - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (ret < 0) - goto err_pci_disable_device; - - pci_set_master(pdev); - - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret < 0) - goto err_pci_disable_device; - - dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); - if (!dm1105dvb->io_mem) { - ret = -EIO; - goto err_pci_release_regions; - } - - spin_lock_init(&dm1105dvb->lock); - pci_set_drvdata(pdev, dm1105dvb); - - ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb); - if (ret < 0) - goto err_pci_iounmap; - - ret = dm1105dvb_hw_init(dm1105dvb); - if (ret < 0) - goto err_free_irq; - - /* i2c */ - i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); - strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME); - dm1105dvb->i2c_adap.owner = THIS_MODULE; - dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - dm1105dvb->i2c_adap.dev.parent = &pdev->dev; - dm1105dvb->i2c_adap.algo = &dm1105_algo; - dm1105dvb->i2c_adap.algo_data = dm1105dvb; - ret = i2c_add_adapter(&dm1105dvb->i2c_adap); - - if (ret < 0) - goto err_dm1105dvb_hw_exit; - - /* dvb */ - ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME, - THIS_MODULE, &pdev->dev, adapter_nr); - if (ret < 0) - goto err_i2c_del_adapter; - - dvb_adapter = &dm1105dvb->dvb_adapter; - - dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac); - - dvbdemux = &dm1105dvb->demux; - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = dm1105dvb_start_feed; - dvbdemux->stop_feed = dm1105dvb_stop_feed; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); - ret = dvb_dmx_init(dvbdemux); - if (ret < 0) - goto err_dvb_unregister_adapter; - - dmx = &dvbdemux->dmx; - dm1105dvb->dmxdev.filternum = 256; - dm1105dvb->dmxdev.demux = dmx; - dm1105dvb->dmxdev.capabilities = 0; - - ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter); - if (ret < 0) - goto err_dvb_dmx_release; - - dm1105dvb->hw_frontend.source = DMX_FRONTEND_0; - - ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend); - if (ret < 0) - goto err_dvb_dmxdev_release; - - dm1105dvb->mem_frontend.source = DMX_MEMORY_FE; - - ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend); - if (ret < 0) - goto err_remove_hw_frontend; - - ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend); - if (ret < 0) - goto err_remove_mem_frontend; - - ret = frontend_init(dm1105dvb); - if (ret < 0) - goto err_disconnect_frontend; - - dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); - dm1105_ir_init(dm1105dvb); -out: - return ret; - -err_disconnect_frontend: - dmx->disconnect_frontend(dmx); -err_remove_mem_frontend: - dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); -err_remove_hw_frontend: - dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); -err_dvb_dmxdev_release: - dvb_dmxdev_release(&dm1105dvb->dmxdev); -err_dvb_dmx_release: - dvb_dmx_release(dvbdemux); -err_dvb_unregister_adapter: - dvb_unregister_adapter(dvb_adapter); -err_i2c_del_adapter: - i2c_del_adapter(&dm1105dvb->i2c_adap); -err_dm1105dvb_hw_exit: - dm1105dvb_hw_exit(dm1105dvb); -err_free_irq: - free_irq(pdev->irq, dm1105dvb); -err_pci_iounmap: - pci_iounmap(pdev, dm1105dvb->io_mem); -err_pci_release_regions: - pci_release_regions(pdev); -err_pci_disable_device: - pci_disable_device(pdev); -err_kfree: - pci_set_drvdata(pdev, NULL); - kfree(dm1105dvb); - goto out; -} - -static void __devexit dm1105_remove(struct pci_dev *pdev) -{ - struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev); - struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter; - struct dvb_demux *dvbdemux = &dm1105dvb->demux; - struct dmx_demux *dmx = &dvbdemux->dmx; - - dm1105_ir_exit(dm1105dvb); - dmx->close(dmx); - dvb_net_release(&dm1105dvb->dvbnet); - if (dm1105dvb->fe) - dvb_unregister_frontend(dm1105dvb->fe); - - dmx->disconnect_frontend(dmx); - dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); - dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); - dvb_dmxdev_release(&dm1105dvb->dmxdev); - dvb_dmx_release(dvbdemux); - dvb_unregister_adapter(dvb_adapter); - if (&dm1105dvb->i2c_adap) - i2c_del_adapter(&dm1105dvb->i2c_adap); - - dm1105dvb_hw_exit(dm1105dvb); - synchronize_irq(pdev->irq); - free_irq(pdev->irq, dm1105dvb); - pci_iounmap(pdev, dm1105dvb->io_mem); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - kfree(dm1105dvb); -} - -static struct pci_device_id dm1105_id_table[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_TRIGEM, - .device = PCI_DEVICE_ID_DM1105, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_DEVICE_ID_DW2002, - }, { - .vendor = PCI_VENDOR_ID_TRIGEM, - .device = PCI_DEVICE_ID_DM1105, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_DEVICE_ID_DW2004, - }, { - /* empty */ - }, -}; - -MODULE_DEVICE_TABLE(pci, dm1105_id_table); - -static struct pci_driver dm1105_driver = { - .name = DRIVER_NAME, - .id_table = dm1105_id_table, - .probe = dm1105_probe, - .remove = __devexit_p(dm1105_remove), -}; - -static int __init dm1105_init(void) -{ - return pci_register_driver(&dm1105_driver); -} - -static void __exit dm1105_exit(void) -{ - pci_unregister_driver(&dm1105_driver); -} - -module_init(dm1105_init); -module_exit(dm1105_exit); - -MODULE_AUTHOR("Igor M. Liplianin "); -MODULE_DESCRIPTION("SDMC DM1105 DVB driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index f170e822fadc..3526e3ee9487 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -40,7 +40,6 @@ #include "dvb_frontend.h" #include "dvbdev.h" -#include static int dvb_frontend_debug; static int dvb_shutdown_timeout; @@ -756,539 +755,6 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, return 0; } -struct dtv_cmds_h dtv_cmds[] = { - [DTV_TUNE] = { - .name = "DTV_TUNE", - .cmd = DTV_TUNE, - .set = 1, - }, - [DTV_CLEAR] = { - .name = "DTV_CLEAR", - .cmd = DTV_CLEAR, - .set = 1, - }, - - /* Set */ - [DTV_FREQUENCY] = { - .name = "DTV_FREQUENCY", - .cmd = DTV_FREQUENCY, - .set = 1, - }, - [DTV_BANDWIDTH_HZ] = { - .name = "DTV_BANDWIDTH_HZ", - .cmd = DTV_BANDWIDTH_HZ, - .set = 1, - }, - [DTV_MODULATION] = { - .name = "DTV_MODULATION", - .cmd = DTV_MODULATION, - .set = 1, - }, - [DTV_INVERSION] = { - .name = "DTV_INVERSION", - .cmd = DTV_INVERSION, - .set = 1, - }, - [DTV_DISEQC_MASTER] = { - .name = "DTV_DISEQC_MASTER", - .cmd = DTV_DISEQC_MASTER, - .set = 1, - .buffer = 1, - }, - [DTV_SYMBOL_RATE] = { - .name = "DTV_SYMBOL_RATE", - .cmd = DTV_SYMBOL_RATE, - .set = 1, - }, - [DTV_INNER_FEC] = { - .name = "DTV_INNER_FEC", - .cmd = DTV_INNER_FEC, - .set = 1, - }, - [DTV_VOLTAGE] = { - .name = "DTV_VOLTAGE", - .cmd = DTV_VOLTAGE, - .set = 1, - }, - [DTV_TONE] = { - .name = "DTV_TONE", - .cmd = DTV_TONE, - .set = 1, - }, - [DTV_PILOT] = { - .name = "DTV_PILOT", - .cmd = DTV_PILOT, - .set = 1, - }, - [DTV_ROLLOFF] = { - .name = "DTV_ROLLOFF", - .cmd = DTV_ROLLOFF, - .set = 1, - }, - [DTV_DELIVERY_SYSTEM] = { - .name = "DTV_DELIVERY_SYSTEM", - .cmd = DTV_DELIVERY_SYSTEM, - .set = 1, - }, - [DTV_HIERARCHY] = { - .name = "DTV_HIERARCHY", - .cmd = DTV_HIERARCHY, - .set = 1, - }, - [DTV_CODE_RATE_HP] = { - .name = "DTV_CODE_RATE_HP", - .cmd = DTV_CODE_RATE_HP, - .set = 1, - }, - [DTV_CODE_RATE_LP] = { - .name = "DTV_CODE_RATE_LP", - .cmd = DTV_CODE_RATE_LP, - .set = 1, - }, - [DTV_GUARD_INTERVAL] = { - .name = "DTV_GUARD_INTERVAL", - .cmd = DTV_GUARD_INTERVAL, - .set = 1, - }, - [DTV_TRANSMISSION_MODE] = { - .name = "DTV_TRANSMISSION_MODE", - .cmd = DTV_TRANSMISSION_MODE, - .set = 1, - }, - /* Get */ - [DTV_DISEQC_SLAVE_REPLY] = { - .name = "DTV_DISEQC_SLAVE_REPLY", - .cmd = DTV_DISEQC_SLAVE_REPLY, - .set = 0, - .buffer = 1, - }, - [DTV_API_VERSION] = { - .name = "DTV_API_VERSION", - .cmd = DTV_API_VERSION, - .set = 0, - }, - [DTV_CODE_RATE_HP] = { - .name = "DTV_CODE_RATE_HP", - .cmd = DTV_CODE_RATE_HP, - .set = 0, - }, - [DTV_CODE_RATE_LP] = { - .name = "DTV_CODE_RATE_LP", - .cmd = DTV_CODE_RATE_LP, - .set = 0, - }, - [DTV_GUARD_INTERVAL] = { - .name = "DTV_GUARD_INTERVAL", - .cmd = DTV_GUARD_INTERVAL, - .set = 0, - }, - [DTV_TRANSMISSION_MODE] = { - .name = "DTV_TRANSMISSION_MODE", - .cmd = DTV_TRANSMISSION_MODE, - .set = 0, - }, - [DTV_HIERARCHY] = { - .name = "DTV_HIERARCHY", - .cmd = DTV_HIERARCHY, - .set = 0, - }, -}; - -void dtv_property_dump(struct dtv_property *tvp) -{ - int i; - - if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { - printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n", - __func__, tvp->cmd); - return; - } - - printk("%s() tvp.cmd = 0x%08x (%s)\n" - ,__FUNCTION__ - ,tvp->cmd - ,dtv_cmds[ tvp->cmd ].name); - - if(dtv_cmds[ tvp->cmd ].buffer) { - - printk("%s() tvp.u.buffer.len = 0x%02x\n" - ,__FUNCTION__ - ,tvp->u.buffer.len); - - for(i = 0; i < tvp->u.buffer.len; i++) - printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" - ,__FUNCTION__ - ,i - ,tvp->u.buffer.data[i]); - - } else - printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data); -} - -int is_legacy_delivery_system(fe_delivery_system_t s) -{ - if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || - (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS)) - return 1; - - return 0; -} - -/* Synchronise the legacy tuning parameters into the cache, so that demodulator - * drivers can use a single set_frontend tuning function, regardless of whether - * it's being used for the legacy or new API, reducing code and complexity. - */ -void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - printk("%s()\n", __FUNCTION__); - - c->frequency = p->frequency; - c->inversion = p->inversion; - - switch (fe->ops.info.type) { - case FE_QPSK: - c->modulation = QPSK; /* implied for DVB-S in legacy API */ - c->rolloff = ROLLOFF_35;/* implied for DVB-S */ - c->symbol_rate = p->u.qpsk.symbol_rate; - c->fec_inner = p->u.qpsk.fec_inner; - c->delivery_system = SYS_DVBS; - break; - case FE_QAM: - c->symbol_rate = p->u.qam.symbol_rate; - c->fec_inner = p->u.qam.fec_inner; - c->modulation = p->u.qam.modulation; - c->delivery_system = SYS_DVBC_ANNEX_AC; - break; - case FE_OFDM: - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - c->bandwidth_hz = 6000000; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - c->bandwidth_hz = 7000000; - else if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - c->bandwidth_hz = 8000000; - else - /* Including BANDWIDTH_AUTO */ - c->bandwidth_hz = 0; - c->code_rate_HP = p->u.ofdm.code_rate_HP; - c->code_rate_LP = p->u.ofdm.code_rate_LP; - c->modulation = p->u.ofdm.constellation; - c->transmission_mode = p->u.ofdm.transmission_mode; - c->guard_interval = p->u.ofdm.guard_interval; - c->hierarchy = p->u.ofdm.hierarchy_information; - c->delivery_system = SYS_DVBT; - break; - case FE_ATSC: - c->modulation = p->u.vsb.modulation; - if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) - c->delivery_system = SYS_ATSC; - else - c->delivery_system = SYS_DVBC_ANNEX_B; - break; - } -} - -/* Ensure the cached values are set correctly in the frontend - * legacy tuning structures, for the advanced tuning API. - */ -void dtv_property_legacy_params_sync(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters *p = &fepriv->parameters; - - printk("%s()\n", __FUNCTION__); - - p->frequency = c->frequency; - p->inversion = c->inversion; - - switch (fe->ops.info.type) { - case FE_QPSK: - printk("%s() Preparing QPSK req\n", __FUNCTION__); - p->u.qpsk.symbol_rate = c->symbol_rate; - p->u.qpsk.fec_inner = c->fec_inner; - c->delivery_system = SYS_DVBS; - break; - case FE_QAM: - printk("%s() Preparing QAM req\n", __FUNCTION__); - p->u.qam.symbol_rate = c->symbol_rate; - p->u.qam.fec_inner = c->fec_inner; - p->u.qam.modulation = c->modulation; - c->delivery_system = SYS_DVBC_ANNEX_AC; - break; - case FE_OFDM: - printk("%s() Preparing OFDM req\n", __FUNCTION__); - if (c->bandwidth_hz == 6000000) - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - else if (c->bandwidth_hz == 7000000) - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - else if (c->bandwidth_hz == 8000000) - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - else - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; - p->u.ofdm.code_rate_HP = c->code_rate_HP; - p->u.ofdm.code_rate_LP = c->code_rate_LP; - p->u.ofdm.constellation = c->modulation; - p->u.ofdm.transmission_mode = c->transmission_mode; - p->u.ofdm.guard_interval = c->guard_interval; - p->u.ofdm.hierarchy_information = c->hierarchy; - c->delivery_system = SYS_DVBT; - break; - case FE_ATSC: - printk("%s() Preparing VSB req\n", __FUNCTION__); - p->u.vsb.modulation = c->modulation; - if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) - c->delivery_system = SYS_ATSC; - else - c->delivery_system = SYS_DVBC_ANNEX_B; - break; - } -} - -/* Ensure the cached values are set correctly in the frontend - * legacy tuning structures, for the legacy tuning API. - */ -void dtv_property_adv_params_sync(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters *p = &fepriv->parameters; - - printk("%s()\n", __FUNCTION__); - - p->frequency = c->frequency; - p->inversion = c->inversion; - - switch(c->modulation) { - case PSK_8: - case APSK_16: - case QPSK: - p->u.qpsk.symbol_rate = c->symbol_rate; - p->u.qpsk.fec_inner = c->fec_inner; - break; - default: - break; - } - - if(c->delivery_system == SYS_ISDBT) { - /* Fake out a generic DVB-T request so we pass validation in the ioctl */ - p->frequency = c->frequency; - p->inversion = INVERSION_AUTO; - p->u.ofdm.constellation = QAM_AUTO; - p->u.ofdm.code_rate_HP = FEC_AUTO; - p->u.ofdm.code_rate_LP = FEC_AUTO; - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; - } -} - -void dtv_property_cache_submit(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - printk("%s()\n", __FUNCTION__); - - /* For legacy delivery systems we don't need the delivery_system to - * be specified, but we populate the older structures from the cache - * so we can call set_frontend on older drivers. - */ - if(is_legacy_delivery_system(c->delivery_system)) { - - printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation); - dtv_property_legacy_params_sync(fe); - - } else { - printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation); - - /* For advanced delivery systems / modulation types ... - * we seed the lecacy dvb_frontend_parameters structure - * so that the sanity checking code later in the IOCTL processing - * can validate our basic frequency ranges, symbolrates, modulation - * etc. - */ - dtv_property_adv_params_sync(fe); - } -} - -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, - unsigned int cmd, void *parg); -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, - unsigned int cmd, void *parg); - -int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, - struct inode *inode, struct file *file) -{ - int r = 0; - - printk("%s()\n", __FUNCTION__); - - dtv_property_dump(tvp); - - /* Allow the frontend to validate incoming properties */ - if (fe->ops.get_property) - r = fe->ops.get_property(fe, tvp); - - if (r < 0) - return r; - - switch(tvp->cmd) { - case DTV_FREQUENCY: - tvp->u.data = fe->dtv_property_cache.frequency; - break; - case DTV_MODULATION: - tvp->u.data = fe->dtv_property_cache.modulation; - break; - case DTV_BANDWIDTH_HZ: - tvp->u.data = fe->dtv_property_cache.bandwidth_hz; - break; - case DTV_INVERSION: - tvp->u.data = fe->dtv_property_cache.inversion; - break; - case DTV_SYMBOL_RATE: - tvp->u.data = fe->dtv_property_cache.symbol_rate; - break; - case DTV_INNER_FEC: - tvp->u.data = fe->dtv_property_cache.fec_inner; - break; - case DTV_PILOT: - tvp->u.data = fe->dtv_property_cache.pilot; - break; - case DTV_ROLLOFF: - tvp->u.data = fe->dtv_property_cache.rolloff; - break; - case DTV_DELIVERY_SYSTEM: - tvp->u.data = fe->dtv_property_cache.delivery_system; - break; - case DTV_VOLTAGE: - tvp->u.data = fe->dtv_property_cache.voltage; - break; - case DTV_TONE: - tvp->u.data = fe->dtv_property_cache.sectone; - break; - case DTV_API_VERSION: - tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR; - break; - case DTV_CODE_RATE_HP: - tvp->u.data = fe->dtv_property_cache.code_rate_HP; - break; - case DTV_CODE_RATE_LP: - tvp->u.data = fe->dtv_property_cache.code_rate_LP; - break; - case DTV_GUARD_INTERVAL: - tvp->u.data = fe->dtv_property_cache.guard_interval; - break; - case DTV_TRANSMISSION_MODE: - tvp->u.data = fe->dtv_property_cache.transmission_mode; - break; - case DTV_HIERARCHY: - tvp->u.data = fe->dtv_property_cache.hierarchy; - break; - default: - r = -1; - } - - return r; -} - -int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, - struct inode *inode, struct file *file) -{ - int r = 0; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - printk("%s()\n", __FUNCTION__); - dtv_property_dump(tvp); - - /* Allow the frontend to validate incoming properties */ - if (fe->ops.set_property) - r = fe->ops.set_property(fe, tvp); - - if (r < 0) - return r; - - switch(tvp->cmd) { - case DTV_CLEAR: - /* Reset a cache of data specific to the frontend here. This does - * not effect hardware. - */ - printk("%s() Flushing property cache\n", __FUNCTION__); - memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); - fe->dtv_property_cache.state = tvp->cmd; - fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; - break; - case DTV_TUNE: - /* interpret the cache of data, build either a traditional frontend - * tunerequest so we can pass validation in the FE_SET_FRONTEND - * ioctl. - */ - fe->dtv_property_cache.state = tvp->cmd; - printk("%s() Finalised property cache\n", __FUNCTION__); - dtv_property_cache_submit(fe); - - r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, - &fepriv->parameters); - break; - case DTV_FREQUENCY: - fe->dtv_property_cache.frequency = tvp->u.data; - break; - case DTV_MODULATION: - fe->dtv_property_cache.modulation = tvp->u.data; - break; - case DTV_BANDWIDTH_HZ: - fe->dtv_property_cache.bandwidth_hz = tvp->u.data; - break; - case DTV_INVERSION: - fe->dtv_property_cache.inversion = tvp->u.data; - break; - case DTV_SYMBOL_RATE: - fe->dtv_property_cache.symbol_rate = tvp->u.data; - break; - case DTV_INNER_FEC: - fe->dtv_property_cache.fec_inner = tvp->u.data; - break; - case DTV_PILOT: - fe->dtv_property_cache.pilot = tvp->u.data; - break; - case DTV_ROLLOFF: - fe->dtv_property_cache.rolloff = tvp->u.data; - break; - case DTV_DELIVERY_SYSTEM: - fe->dtv_property_cache.delivery_system = tvp->u.data; - break; - case DTV_VOLTAGE: - fe->dtv_property_cache.voltage = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, - (void *)fe->dtv_property_cache.voltage); - break; - case DTV_TONE: - fe->dtv_property_cache.sectone = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, - (void *)fe->dtv_property_cache.sectone); - break; - case DTV_CODE_RATE_HP: - fe->dtv_property_cache.code_rate_HP = tvp->u.data; - break; - case DTV_CODE_RATE_LP: - fe->dtv_property_cache.code_rate_LP = tvp->u.data; - break; - case DTV_GUARD_INTERVAL: - fe->dtv_property_cache.guard_interval = tvp->u.data; - break; - case DTV_TRANSMISSION_MODE: - fe->dtv_property_cache.transmission_mode = tvp->u.data; - break; - case DTV_HIERARCHY: - fe->dtv_property_cache.hierarchy = tvp->u.data; - break; - default: - r = -1; - } - - return r; -} - static int dvb_frontend_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { @@ -1310,116 +776,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, if (down_interruptible (&fepriv->sem)) return -ERESTARTSYS; - if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) - err = dvb_frontend_ioctl_properties(inode, file, cmd, parg); - else { - fe->dtv_property_cache.state = DTV_UNDEFINED; - err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg); - } - - up(&fepriv->sem); - return err; -} - -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - int err = 0; - - struct dtv_properties *tvps = NULL; - struct dtv_property *tvp = NULL; - int i; - - dprintk("%s\n", __func__); - - if(cmd == FE_SET_PROPERTY) { - printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); - - tvps = (struct dtv_properties __user *)parg; - - printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); - printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); - - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ - if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) - return -EINVAL; - - tvp = (struct dtv_property *) kmalloc(tvps->num * - sizeof(struct dtv_property), GFP_KERNEL); - if (!tvp) { - err = -ENOMEM; - goto out; - } - - if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_set(fe, tvp + i, inode, file); - err |= (tvp + i)->result; - } - - if(fe->dtv_property_cache.state == DTV_TUNE) { - printk("%s() Property cache is full, tuning\n", __FUNCTION__); - } - - } else - if(cmd == FE_GET_PROPERTY) { - printk("%s() FE_GET_PROPERTY\n", __FUNCTION__); - - tvps = (struct dtv_properties __user *)parg; - - printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); - printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); - - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ - if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) - return -EINVAL; - - tvp = (struct dtv_property *) kmalloc(tvps->num * - sizeof(struct dtv_property), GFP_KERNEL); - if (!tvp) { - err = -ENOMEM; - goto out; - } - - if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_get(fe, tvp + i, inode, file); - err |= (tvp + i)->result; - } - - if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - } else - err = -EOPNOTSUPP; - -out: - kfree(tvp); - return err; -} - -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - int err = -EOPNOTSUPP; - switch (cmd) { case FE_GET_INFO: { struct dvb_frontend_info* info = parg; @@ -1586,22 +942,14 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; - if(fe->dtv_property_cache.state == DTV_TUNE) { - if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { - err = -EINVAL; - break; - } - } else { - if (dvb_frontend_check_parameters(fe, parg) < 0) { - err = -EINVAL; - break; - } - - memcpy (&fepriv->parameters, parg, - sizeof (struct dvb_frontend_parameters)); - dtv_property_cache_sync(fe, &fepriv->parameters); + if (dvb_frontend_check_parameters(fe, parg) < 0) { + err = -EINVAL; + break; } + memcpy (&fepriv->parameters, parg, + sizeof (struct dvb_frontend_parameters)); + memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); memcpy(&fetunesettings.parameters, parg, sizeof (struct dvb_frontend_parameters)); @@ -1679,10 +1027,10 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, break; }; + up (&fepriv->sem); return err; } - static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait) { struct dvb_device *dvbdev = file->private_data; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h index 3055301ff3ca..aa4133f0bd19 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -169,9 +169,6 @@ struct dvb_frontend_ops { struct dvb_tuner_ops tuner_ops; struct analog_demod_ops analog_ops; - - int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); - int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); }; #define MAX_EVENT 8 @@ -185,32 +182,6 @@ struct dvb_fe_events { struct mutex mtx; }; -struct dtv_frontend_properties { - - /* Cache State */ - u32 state; - - u32 frequency; - fe_modulation_t modulation; - - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t sectone; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec_inner; - fe_transmit_mode_t transmission_mode; - u32 bandwidth_hz; /* 0 = AUTO */ - fe_guard_interval_t guard_interval; - fe_hierarchy_t hierarchy; - u32 symbol_rate; - fe_code_rate_t code_rate_HP; - fe_code_rate_t code_rate_LP; - - fe_pilot_t pilot; - fe_rolloff_t rolloff; - - fe_delivery_system_t delivery_system; -}; - struct dvb_frontend { struct dvb_frontend_ops ops; struct dvb_adapter *dvb; @@ -219,9 +190,6 @@ struct dvb_frontend { void *frontend_priv; void *sec_priv; void *analog_demod_priv; - struct dtv_frontend_properties dtv_property_cache; -#define DVB_FRONTEND_COMPONENT_TUNER 0 - int (*callback)(void *adapter_priv, int component, int cmd, int arg); }; extern int dvb_register_frontend(struct dvb_adapter *dvb, diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index 665776d72a48..e7132770a3bf 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -233,7 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, mutex_unlock(&dvbdev_register_lock); - clsdev = device_create(dvb_class, adap->device, + clsdev = device_create_drvdata(dvb_class, adap->device, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), NULL, "dvb%d.%s%d", adap->num, dnames[type], id); if (IS_ERR(clsdev)) { diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index 3c13bcfa6385..e84152b7576d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -72,11 +72,9 @@ config DVB_USB_DIB0700 select DVB_DIB7000P select DVB_DIB7000M select DVB_DIB3000MC - select DVB_S5H1411 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE select DVB_TUNER_DIB0070 help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The @@ -110,8 +108,6 @@ config DVB_USB_CXUSB select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE - select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode @@ -249,25 +245,12 @@ config DVB_USB_AF9005_REMOTE Afatech AF9005 based receiver. config DVB_USB_DW2102 - tristate "DvbWorld DVB-S/S2 USB2.0 support" + tristate "DvbWorld 2102 DVB-S USB2.0 receiver" depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_STV0288 if !DVB_FE_CUSTOMISE - select DVB_STB6000 if !DVB_FE_CUSTOMISE - select DVB_CX24116 if !DVB_FE_CUSTOMISE - select DVB_SI21XX if !DVB_FE_CUSTOMISE - help - Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers - and the TeVii S650. - -config DVB_USB_CINERGY_T2 - tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" - depends on DVB_USB + select DVB_PLL if !DVB_FE_CUSTOMISE help - Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers - - Say Y if you own such a device and want to use it. + Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver. config DVB_USB_ANYSEE tristate "Anysee DVB-T/C USB2.0 support" @@ -279,22 +262,3 @@ config DVB_USB_ANYSEE help Say Y here to support the Anysee E30, Anysee E30 Plus or Anysee E30 C Plus DVB USB2.0 receiver. - -config DVB_USB_DTV5100 - tristate "AME DTV-5100 USB2.0 DVB-T support" - depends on DVB_USB - select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE - help - Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. - -config DVB_USB_AF9015 - tristate "Afatech AF9015 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL - select DVB_AF9013 - select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE - help - Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver diff --git a/trunk/drivers/media/dvb/dvb-usb/Makefile b/trunk/drivers/media/dvb/dvb-usb/Makefile index 3122b7cc2c23..e206f1ea0027 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Makefile +++ b/trunk/drivers/media/dvb/dvb-usb/Makefile @@ -67,16 +67,6 @@ obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o dvb-usb-dw2102-objs = dw2102.o obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o -dvb-usb-dtv5100-objs = dtv5100.o -obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o - -dvb-usb-af9015-objs = af9015.o -obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o - -dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o -obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o - - EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/trunk/drivers/media/dvb/dvb-usb/af9005-remote.c b/trunk/drivers/media/dvb/dvb-usb/af9005-remote.c index 7c596f926764..ff00c0e8f4a1 100644 --- a/trunk/drivers/media/dvb/dvb-usb/af9005-remote.c +++ b/trunk/drivers/media/dvb/dvb-usb/af9005-remote.c @@ -25,7 +25,7 @@ */ #include "af9005.h" /* debug */ -static int dvb_usb_af9005_remote_debug; +int dvb_usb_af9005_remote_debug; module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); MODULE_PARM_DESC(debug, "enable (1) or disable (0) debug messages." diff --git a/trunk/drivers/media/dvb/dvb-usb/af9005-script.h b/trunk/drivers/media/dvb/dvb-usb/af9005-script.h index 4d69045426dd..6eeaae51b1ca 100644 --- a/trunk/drivers/media/dvb/dvb-usb/af9005-script.h +++ b/trunk/drivers/media/dvb/dvb-usb/af9005-script.h @@ -14,7 +14,7 @@ typedef struct { u8 val; } RegDesc; -static RegDesc script[] = { +RegDesc script[] = { {0xa180, 0x0, 0x8, 0xa}, {0xa181, 0x0, 0x8, 0xd7}, {0xa182, 0x0, 0x8, 0xa3}, diff --git a/trunk/drivers/media/dvb/dvb-usb/af9005.c b/trunk/drivers/media/dvb/dvb-usb/af9005.c index ca5a0a4d2a47..cfe71feefcad 100644 --- a/trunk/drivers/media/dvb/dvb-usb/af9005.c +++ b/trunk/drivers/media/dvb/dvb-usb/af9005.c @@ -35,17 +35,17 @@ module_param_named(led, dvb_usb_af9005_led, bool, 0644); MODULE_PARM_DESC(led, "enable led (default: 1)."); /* eeprom dump */ -static int dvb_usb_af9005_dump_eeprom; +int dvb_usb_af9005_dump_eeprom = 0; module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* remote control decoder */ -static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len, - u32 *event, int *state); -static void *rc_keys; -static int *rc_keys_size; +int (*rc_decode) (struct dvb_usb_device * d, u8 * data, int len, u32 * event, + int *state); +void *rc_keys; +int *rc_keys_size; u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; @@ -54,8 +54,8 @@ struct af9005_device_state { int led_state; }; -static int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, - u8 *rbuf, u16 rlen, int delay_ms) +int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 * wbuf, u16 wlen, + u8 * rbuf, u16 rlen, int delay_ms) { int actlen, ret = -ENOMEM; @@ -98,7 +98,12 @@ static int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, return ret; } -static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, +int af9005_usb_generic_write(struct dvb_usb_device *d, u8 * buf, u16 len) +{ + return af9005_usb_generic_rw(d, buf, len, NULL, 0, 0); +} + +int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, int readwrite, int type, u8 * values, int len) { struct af9005_device_state *st = d->priv; @@ -760,7 +765,7 @@ static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply) return 0; } -static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) +int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) { int i, packets, ret, act_len; diff --git a/trunk/drivers/media/dvb/dvb-usb/af9015.c b/trunk/drivers/media/dvb/dvb-usb/af9015.c deleted file mode 100644 index cb0829c038ce..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/af9015.c +++ /dev/null @@ -1,1474 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "af9015.h" -#include "af9013.h" -#include "mt2060.h" -#include "qt1010.h" -#include "tda18271.h" -#include "mxl5005s.h" -#if 0 -#include "mc44s80x.h" -#endif - -int dvb_usb_af9015_debug; -module_param_named(debug, dvb_usb_af9015_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -int dvb_usb_af9015_remote; -module_param_named(remote, dvb_usb_af9015_remote, int, 0644); -MODULE_PARM_DESC(remote, "select remote"); -int dvb_usb_af9015_dual_mode; -module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); -MODULE_PARM_DESC(dual_mode, "enable dual mode"); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static DEFINE_MUTEX(af9015_usb_mutex); - -static struct af9015_config af9015_config; -static struct dvb_usb_device_properties af9015_properties[2]; -int af9015_properties_count = ARRAY_SIZE(af9015_properties); - -static struct af9013_config af9015_af9013_config[] = { - { - .demod_address = AF9015_I2C_DEMOD, - .output_mode = AF9013_OUTPUT_MODE_USB, - .api_version = { 0, 1, 9, 0 }, - .gpio[0] = AF9013_GPIO_HI, - .gpio[3] = AF9013_GPIO_TUNER_ON, - - }, { - .output_mode = AF9013_OUTPUT_MODE_SERIAL, - .api_version = { 0, 1, 9, 0 }, - .gpio[0] = AF9013_GPIO_TUNER_ON, - .gpio[1] = AF9013_GPIO_LO, - } -}; - -static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) -{ - int act_len, ret; - u8 buf[64]; - u8 write = 1; - u8 msg_len = 8; - static u8 seq; /* packet sequence number */ - - if (mutex_lock_interruptible(&af9015_usb_mutex) < 0) - return -EAGAIN; - - buf[0] = req->cmd; - buf[1] = seq++; - buf[2] = req->i2c_addr; - buf[3] = req->addr >> 8; - buf[4] = req->addr & 0xff; - buf[5] = req->mbox; - buf[6] = req->addr_len; - buf[7] = req->data_len; - - switch (req->cmd) { - case GET_CONFIG: - case BOOT: - case READ_MEMORY: - case RECONNECT_USB: - case GET_IR_CODE: - write = 0; - break; - case READ_I2C: - write = 0; - buf[2] |= 0x01; /* set I2C direction */ - case WRITE_I2C: - buf[0] = READ_WRITE_I2C; - break; - case WRITE_MEMORY: - if (((req->addr & 0xff00) == 0xff00) || - ((req->addr & 0xae00) == 0xae00)) - buf[0] = WRITE_VIRTUAL_MEMORY; - case WRITE_VIRTUAL_MEMORY: - case COPY_FIRMWARE: - case DOWNLOAD_FIRMWARE: - break; - default: - err("unknown command:%d", req->cmd); - ret = -1; - goto error_unlock; - } - - /* write requested */ - if (write) { - memcpy(&buf[8], req->data, req->data_len); - msg_len += req->data_len; - } - deb_xfer(">>> "); - debug_dump(buf, msg_len, deb_xfer); - - /* send req */ - ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len, - &act_len, AF9015_USB_TIMEOUT); - if (ret) - err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len); - else - if (act_len != msg_len) - ret = -1; /* all data is not send */ - if (ret) - goto error_unlock; - - /* no ack for those packets */ - if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) - goto exit_unlock; - - /* receive ack and data if read req */ - msg_len = 1 + 1 + req->data_len; /* seq + status + data len */ - ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len, - &act_len, AF9015_USB_TIMEOUT); - if (ret) { - err("recv bulk message failed:%d", ret); - ret = -1; - goto error_unlock; - } - - deb_xfer("<<< "); - debug_dump(buf, act_len, deb_xfer); - - /* remote controller query status is 1 if remote code is not received */ - if (req->cmd == GET_IR_CODE && buf[1] == 1) { - buf[1] = 0; /* clear command "error" status */ - memset(&buf[2], 0, req->data_len); - buf[3] = 1; /* no remote code received mark */ - } - - /* check status */ - if (buf[1]) { - err("command failed:%d", buf[1]); - ret = -1; - goto error_unlock; - } - - /* read request, copy returned data to return buf */ - if (!write) - memcpy(req->data, &buf[2], req->data_len); - -error_unlock: -exit_unlock: - mutex_unlock(&af9015_usb_mutex); - - return ret; -} - -static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) -{ - return af9015_rw_udev(d->udev, req); -} - -static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, - u8 len) -{ - struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, - val}; - return af9015_ctrl_msg(d, &req); -} - -static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) -{ - return af9015_write_regs(d, addr, &val, 1); -} - -static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) -{ - struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val}; - return af9015_ctrl_msg(d, &req); -} - -static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 val) -{ - struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; - - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) - req.addr_len = 3; - - return af9015_ctrl_msg(d, &req); -} - -static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 *val) -{ - struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; - - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) - req.addr_len = 3; - - return af9015_ctrl_msg(d, &req); -} - -static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0, i = 0; - u16 addr; - u8 mbox, addr_len; - struct req_t req; - -/* TODO: implement bus lock - -The bus lock is needed because there is two tuners both using same I2C-address. -Due to that the only way to select correct tuner is use demodulator I2C-gate. - -................................................ -. AF9015 includes integrated AF9013 demodulator. -. ____________ ____________ . ____________ -.| uC | | demod | . | tuner | -.|------------| |------------| . |------------| -.| AF9015 | | AF9013/5 | . | MXL5003 | -.| |--+----I2C-------|-----/ -----|-.-----I2C-------| | -.| | | | addr 0x38 | . | addr 0xc6 | -.|____________| | |____________| . |____________| -.................|.............................. - | ____________ ____________ - | | demod | | tuner | - | |------------| |------------| - | | AF9013 | | MXL5003 | - +----I2C-------|-----/ -----|-------I2C-------| | - | addr 0x3a | | addr 0xc6 | - |____________| |____________| -*/ - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - while (i < num) { - if (msg[i].addr == af9015_af9013_config[0].demod_address || - msg[i].addr == af9015_af9013_config[1].demod_address) { - addr = msg[i].buf[0] << 8; - addr += msg[i].buf[1]; - mbox = msg[i].buf[2]; - addr_len = 3; - } else { - addr = msg[i].buf[0]; - addr_len = 1; - mbox = 0; - } - - if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { - if (msg[i].addr == - af9015_af9013_config[0].demod_address) - req.cmd = READ_MEMORY; - else - req.cmd = READ_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i+1].len; - req.data = &msg[i+1].buf[0]; - ret = af9015_ctrl_msg(d, &req); - i += 2; - } else { - if (msg[i].addr == - af9015_af9013_config[0].demod_address) - req.cmd = WRITE_MEMORY; - else - req.cmd = WRITE_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i].len-addr_len; - req.data = &msg[i].buf[addr_len]; - ret = af9015_ctrl_msg(d, &req); - i += 1; - } - if (ret) - goto error; - - } - ret = i; - -error: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -static u32 af9015_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm af9015_i2c_algo = { - .master_xfer = af9015_i2c_xfer, - .functionality = af9015_i2c_func, -}; - -static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op) -{ - int ret; - u8 val, mask = 0x01; - - ret = af9015_read_reg(d, addr, &val); - if (ret) - return ret; - - mask <<= bit; - if (op) { - /* set bit */ - val |= mask; - } else { - /* clear bit */ - mask ^= 0xff; - val &= mask; - } - - return af9015_write_reg(d, addr, val); -} - -static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 1); -} - -static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 0); -} - -static int af9015_init_endpoint(struct dvb_usb_device *d) -{ - int ret; - u16 frame_size; - u8 packet_size; - deb_info("%s: USB speed:%d\n", __func__, d->udev->speed); - -#define TS_PACKET_SIZE 188 - -#define TS_USB20_PACKET_COUNT 348 -#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT) - -#define TS_USB11_PACKET_COUNT 21 -#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT) - -#define TS_USB20_MAX_PACKET_SIZE 512 -#define TS_USB11_MAX_PACKET_SIZE 64 - - if (d->udev->speed == USB_SPEED_FULL) { - frame_size = TS_USB11_FRAME_SIZE/4; - packet_size = TS_USB11_MAX_PACKET_SIZE/4; - } else { - frame_size = TS_USB20_FRAME_SIZE/4; - packet_size = TS_USB20_MAX_PACKET_SIZE/4; - } - - ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */ - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */ - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */ - if (ret) - goto error; - if (af9015_config.dual_mode) { - ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */ - if (ret) - goto error; - } - ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */ - if (ret) - goto error; - if (af9015_config.dual_mode) { - ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */ - if (ret) - goto error; - } - /* EP4 xfer length */ - ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd89, frame_size >> 8); - if (ret) - goto error; - /* EP5 xfer length */ - ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */ - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */ - if (ret) - goto error; - if (af9015_config.dual_mode) { - ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */ - if (ret) - goto error; - } - - /* enable / disable mp2if2 */ - if (af9015_config.dual_mode) - ret = af9015_set_reg_bit(d, 0xd50b, 0); - else - ret = af9015_clear_reg_bit(d, 0xd50b, 0); -error: - if (ret) - err("endpoint init failed:%d", ret); - return ret; -} - -static int af9015_copy_firmware(struct dvb_usb_device *d) -{ - int ret; - u8 fw_params[4]; - u8 val, i; - struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), - fw_params }; - deb_info("%s:\n", __func__); - - fw_params[0] = af9015_config.firmware_size >> 8; - fw_params[1] = af9015_config.firmware_size & 0xff; - fw_params[2] = af9015_config.firmware_checksum >> 8; - fw_params[3] = af9015_config.firmware_checksum & 0xff; - - /* wait 2nd demodulator ready */ - msleep(100); - - ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val); - if (ret) - goto error; - else - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; - - /* set I2C master clock to fast (to speed up firmware copy) */ - ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ - if (ret) - goto error; - - msleep(50); - - /* copy firmware */ - ret = af9015_ctrl_msg(d, &req); - if (ret) - err("firmware copy cmd failed:%d", ret); - deb_info("%s: firmware copy done\n", __func__); - - /* set I2C master clock back to normal */ - ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ - if (ret) - goto error; - - /* request boot firmware */ - ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address, - 0xe205, 1); - deb_info("%s: firmware boot cmd status:%d\n", __func__, ret); - if (ret) - goto error; - - for (i = 0; i < 15; i++) { - msleep(100); - - /* check firmware status */ - ret = af9015_read_reg_i2c(d, - af9015_af9013_config[1].demod_address, 0x98be, &val); - deb_info("%s: firmware status cmd status:%d fw status:%02x\n", - __func__, ret, val); - if (ret) - goto error; - - if (val == 0x0c || val == 0x04) /* success or fail */ - break; - } - - if (val == 0x04) { - err("firmware did not run"); - ret = -1; - } else if (val != 0x0c) { - err("firmware boot timeout"); - ret = -1; - } - -error: -exit: - return ret; -} - -/* dump eeprom */ -static int af9015_eeprom_dump(struct dvb_usb_device *d) -{ - char buf[52], buf2[4]; - u8 reg, val; - - for (reg = 0; ; reg++) { - if (reg % 16 == 0) { - if (reg) - deb_info("%s\n", buf); - sprintf(buf, "%02x: ", reg); - } - if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0) - sprintf(buf2, "%02x ", val); - else - strcpy(buf2, "-- "); - strcat(buf, buf2); - if (reg == 0xff) - break; - } - deb_info("%s\n", buf); - return 0; -} - -int af9015_download_ir_table(struct dvb_usb_device *d) -{ - int i, packets = 0, ret; - u16 addr = 0x9a56; /* ir-table start address */ - struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL}; - u8 *data = NULL; - deb_info("%s:\n", __func__); - - data = af9015_config.ir_table; - packets = af9015_config.ir_table_size; - - /* no remote */ - if (!packets) - goto exit; - - /* load remote ir-table */ - for (i = 0; i < packets; i++) { - req.addr = addr + i; - req.data = &data[i]; - ret = af9015_ctrl_msg(d, &req); - if (ret) { - err("ir-table download failed at packet %d with " \ - "code %d", i, ret); - return ret; - } - } - -exit: - return 0; -} - -static int af9015_init(struct dvb_usb_device *d) -{ - int ret; - deb_info("%s:\n", __func__); - - ret = af9015_init_endpoint(d); - if (ret) - goto error; - - ret = af9015_download_ir_table(d); - if (ret) - goto error; - -error: - return ret; -} - -static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); - - if (onoff) - ret = af9015_set_reg_bit(adap->dev, 0xd503, 0); - else - ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0); - - return ret; -} - -static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, - int onoff) -{ - int ret; - u8 idx; - - deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n", - __func__, index, pid, onoff); - - ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff)); - if (ret) - goto error; - - ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8)); - if (ret) - goto error; - - idx = ((index & 0x1f) | (1 << 5)); - ret = af9015_write_reg(adap->dev, 0xd504, idx); - -error: - return ret; -} - -static int af9015_download_firmware(struct usb_device *udev, - const struct firmware *fw) -{ - int i, len, packets, remainder, ret; - struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; - u16 addr = 0x5100; /* firmware start address */ - u16 checksum = 0; - - deb_info("%s:\n", __func__); - - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; - - af9015_config.firmware_size = fw->size; - af9015_config.firmware_checksum = checksum; - - #define FW_PACKET_MAX_DATA 55 - - packets = fw->size / FW_PACKET_MAX_DATA; - remainder = fw->size % FW_PACKET_MAX_DATA; - len = FW_PACKET_MAX_DATA; - for (i = 0; i <= packets; i++) { - if (i == packets) /* set size of the last packet */ - len = remainder; - - req.data_len = len; - req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); - req.addr = addr; - addr += FW_PACKET_MAX_DATA; - - ret = af9015_rw_udev(udev, &req); - if (ret) { - err("firmware download failed at packet %d with " \ - "code %d", i, ret); - goto error; - } - } - - /* firmware loaded, request boot */ - req.cmd = BOOT; - ret = af9015_rw_udev(udev, &req); - if (ret) { - err("firmware boot failed:%d", ret); - goto error; - } - - /* firmware is running, reconnect device in the usb bus */ - req.cmd = RECONNECT_USB; - ret = af9015_rw_udev(udev, &req); - if (ret) - err("reconnect failed: %d", ret); - -error: - return ret; -} - -static int af9015_read_config(struct usb_device *udev) -{ - int ret; - u8 val, i, offset = 0; - struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; - char manufacturer[10]; - - /* IR remote controller */ - req.addr = AF9015_EEPROM_IR_MODE; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - deb_info("%s: IR mode:%d\n", __func__, val); - for (i = 0; i < af9015_properties_count; i++) { - if (val == AF9015_IR_MODE_DISABLED || val == 0x04) { - af9015_properties[i].rc_key_map = NULL; - af9015_properties[i].rc_key_map_size = 0; - } else if (dvb_usb_af9015_remote) { - /* load remote defined as module param */ - switch (dvb_usb_af9015_remote) { - case AF9015_REMOTE_A_LINK_DTU_M: - af9015_properties[i].rc_key_map = - af9015_rc_keys_a_link; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_a_link); - af9015_config.ir_table = af9015_ir_table_a_link; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_a_link); - break; - case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3: - af9015_properties[i].rc_key_map = - af9015_rc_keys_msi; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_msi); - af9015_config.ir_table = af9015_ir_table_msi; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_msi); - break; - case AF9015_REMOTE_MYGICTV_U718: - af9015_properties[i].rc_key_map = - af9015_rc_keys_mygictv; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_mygictv); - af9015_config.ir_table = - af9015_ir_table_mygictv; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_mygictv); - break; - } - } else { - switch (udev->descriptor.idVendor) { - case USB_VID_LEADTEK: - af9015_properties[i].rc_key_map = - af9015_rc_keys_leadtek; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_leadtek); - af9015_config.ir_table = - af9015_ir_table_leadtek; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_leadtek); - break; - case USB_VID_VISIONPLUS: - if (udev->descriptor.idProduct == - USB_PID_AZUREWAVE_AD_TU700) { - af9015_properties[i].rc_key_map = - af9015_rc_keys_twinhan; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_twinhan); - af9015_config.ir_table = - af9015_ir_table_twinhan; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_twinhan); - } - break; - case USB_VID_KWORLD_2: - /* TODO: use correct rc keys */ - af9015_properties[i].rc_key_map = - af9015_rc_keys_twinhan; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_twinhan); - af9015_config.ir_table = af9015_ir_table_kworld; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_kworld); - break; - /* Check USB manufacturer and product strings and try - to determine correct remote in case of chip vendor - reference IDs are used. */ - case USB_VID_AFATECH: - memset(manufacturer, 0, sizeof(manufacturer)); - usb_string(udev, udev->descriptor.iManufacturer, - manufacturer, sizeof(manufacturer)); - if (!strcmp("Geniatech", manufacturer)) { - /* iManufacturer 1 Geniatech - iProduct 2 AF9015 */ - af9015_properties[i].rc_key_map = - af9015_rc_keys_mygictv; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_mygictv); - af9015_config.ir_table = - af9015_ir_table_mygictv; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_mygictv); - } else if (!strcmp("MSI", manufacturer)) { - /* iManufacturer 1 MSI - iProduct 2 MSI K-VOX */ - af9015_properties[i].rc_key_map = - af9015_rc_keys_msi; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_msi); - af9015_config.ir_table = - af9015_ir_table_msi; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_msi); - } - break; - } - } - } - - /* TS mode - one or two receivers */ - req.addr = AF9015_EEPROM_TS_MODE; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_config.dual_mode = val; - deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); - /* disable dual mode by default because it is buggy */ - if (!dvb_usb_af9015_dual_mode) - af9015_config.dual_mode = 0; - - /* set buffer size according to USB port speed */ - for (i = 0; i < af9015_properties_count; i++) { - /* USB1.1 set smaller buffersize and disable 2nd adapter */ - if (udev->speed == USB_SPEED_FULL) { - af9015_properties[i].adapter->stream.u.bulk.buffersize = - TS_USB11_MAX_PACKET_SIZE; - /* disable 2nd adapter because we don't have - PID-filters */ - af9015_config.dual_mode = 0; - } else { - af9015_properties[i].adapter->stream.u.bulk.buffersize = - TS_USB20_MAX_PACKET_SIZE; - } - } - - if (af9015_config.dual_mode) { - /* read 2nd demodulator I2C address */ - req.addr = AF9015_EEPROM_DEMOD2_I2C; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_af9013_config[1].demod_address = val; - - /* enable 2nd adapter */ - for (i = 0; i < af9015_properties_count; i++) - af9015_properties[i].num_adapters = 2; - - } else { - /* disable 2nd adapter */ - for (i = 0; i < af9015_properties_count; i++) - af9015_properties[i].num_adapters = 1; - } - - for (i = 0; i < af9015_properties[0].num_adapters; i++) { - if (i == 1) - offset = AF9015_EEPROM_OFFSET; - /* xtal */ - req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - switch (val) { - case 0: - af9015_af9013_config[i].adc_clock = 28800; - break; - case 1: - af9015_af9013_config[i].adc_clock = 20480; - break; - case 2: - af9015_af9013_config[i].adc_clock = 28000; - break; - case 3: - af9015_af9013_config[i].adc_clock = 25000; - break; - }; - deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i, - val, af9015_af9013_config[i].adc_clock); - - /* tuner IF */ - req.addr = AF9015_EEPROM_IF1H + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_af9013_config[i].tuner_if = val << 8; - req.addr = AF9015_EEPROM_IF1L + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_af9013_config[i].tuner_if += val; - deb_info("%s: [%d] IF1:%d\n", __func__, i, - af9015_af9013_config[0].tuner_if); - - /* MT2060 IF1 */ - req.addr = AF9015_EEPROM_MT2060_IF1H + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_config.mt2060_if1[i] = val << 8; - req.addr = AF9015_EEPROM_MT2060_IF1L + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_config.mt2060_if1[i] += val; - deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i, - af9015_config.mt2060_if1[i]); - - /* tuner */ - req.addr = AF9015_EEPROM_TUNER_ID1 + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - switch (val) { - case AF9013_TUNER_ENV77H11D5: - case AF9013_TUNER_MT2060: - case AF9013_TUNER_MC44S803: - case AF9013_TUNER_QT1010: - case AF9013_TUNER_UNKNOWN: - case AF9013_TUNER_MT2060_2: - case AF9013_TUNER_TDA18271: - case AF9013_TUNER_QT1010A: - af9015_af9013_config[i].rf_spec_inv = 1; - break; - case AF9013_TUNER_MXL5003D: - case AF9013_TUNER_MXL5005D: - case AF9013_TUNER_MXL5005R: - af9015_af9013_config[i].rf_spec_inv = 0; - break; - default: - warn("tuner id:%d not supported, please report!", val); - return -ENODEV; - }; - - af9015_af9013_config[i].tuner = val; - deb_info("%s: [%d] tuner id:%d\n", __func__, i, val); - } - -error: - if (ret) - err("eeprom read failed:%d", ret); - - return ret; -} - -static int af9015_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - int ret; - u8 reply; - struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; - - ret = af9015_rw_udev(udev, &req); - if (ret) - return ret; - - deb_info("%s: reply:%02x\n", __func__, reply); - if (reply == 0x02) - *cold = 0; - else - *cold = 1; - - return ret; -} - -static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 buf[8]; - struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - int i, ret; - - memset(buf, 0, sizeof(buf)); - - ret = af9015_ctrl_msg(d, &req); - if (ret) - return ret; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (!buf[1] && keymap[i].custom == buf[0] && - keymap[i].data == buf[2]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - break; - } - } - if (!buf[1]) - deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", - __func__, buf[0], buf[1], buf[2], buf[3], buf[4], - buf[5], buf[6], buf[7]); - - return 0; -} - -/* init 2nd I2C adapter */ -int af9015_i2c_init(struct dvb_usb_device *d) -{ - int ret; - struct af9015_state *state = d->priv; - deb_info("%s:\n", __func__); - - strncpy(state->i2c_adap.name, d->desc->name, - sizeof(state->i2c_adap.name)); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, -#else - state->i2c_adap.class = I2C_CLASS_TV_DIGITAL, -#endif - state->i2c_adap.algo = d->props.i2c_algo; - state->i2c_adap.algo_data = NULL; - state->i2c_adap.dev.parent = &d->udev->dev; - - i2c_set_adapdata(&state->i2c_adap, d); - - ret = i2c_add_adapter(&state->i2c_adap); - if (ret < 0) - err("could not add i2c adapter"); - - return ret; -} - -static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) -{ - int ret; - struct af9015_state *state = adap->dev->priv; - struct i2c_adapter *i2c_adap; - - if (adap->id == 0) { - /* select I2C adapter */ - i2c_adap = &adap->dev->i2c_adap; - - deb_info("%s: init I2C\n", __func__); - ret = af9015_i2c_init(adap->dev); - - /* dump eeprom (debug) */ - ret = af9015_eeprom_dump(adap->dev); - if (ret) - return ret; - } else { - /* select I2C adapter */ - i2c_adap = &state->i2c_adap; - - /* copy firmware to 2nd demodulator */ - if (af9015_config.dual_mode) { - ret = af9015_copy_firmware(adap->dev); - if (ret) { - err("firmware copy to 2nd frontend " \ - "failed, will disable it"); - af9015_config.dual_mode = 0; - return -ENODEV; - } - } else { - return -ENODEV; - } - } - - /* attach demodulator */ - adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], - i2c_adap); - - return adap->fe == NULL ? -ENODEV : 0; -} - -static struct mt2060_config af9015_mt2060_config = { - .i2c_address = 0xc0, - .clock_out = 0, -}; - -static struct qt1010_config af9015_qt1010_config = { - .i2c_address = 0xc4, -}; - -static struct tda18271_config af9015_tda18271_config = { - .gate = TDA18271_GATE_DIGITAL, - .small_i2c = 1, -}; - -static struct mxl5005s_config af9015_mxl5003_config = { - .i2c_address = 0xc6, - .if_freq = IF_FREQ_4570000HZ, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_DEFAULT, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -static struct mxl5005s_config af9015_mxl5005_config = { - .i2c_address = 0xc6, - .if_freq = IF_FREQ_4570000HZ, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_OFF, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -static int af9015_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct af9015_state *state = adap->dev->priv; - struct i2c_adapter *i2c_adap; - int ret; - deb_info("%s: \n", __func__); - - /* select I2C adapter */ - if (adap->id == 0) - i2c_adap = &adap->dev->i2c_adap; - else - i2c_adap = &state->i2c_adap; - - switch (af9015_af9013_config[adap->id].tuner) { - case AF9013_TUNER_MT2060: - case AF9013_TUNER_MT2060_2: - ret = dvb_attach(mt2060_attach, adap->fe, i2c_adap, - &af9015_mt2060_config, - af9015_config.mt2060_if1[adap->id]) - == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_QT1010: - case AF9013_TUNER_QT1010A: - ret = dvb_attach(qt1010_attach, adap->fe, i2c_adap, - &af9015_qt1010_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_TDA18271: - ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, - &af9015_tda18271_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_MXL5003D: - ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, - &af9015_mxl5003_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_MXL5005D: - case AF9013_TUNER_MXL5005R: - ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, - &af9015_mxl5005_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_ENV77H11D5: - ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0, i2c_adap, - DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_MC44S803: -#if 0 - ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap) - == NULL ? -ENODEV : 0; -#else - ret = -ENODEV; - info("Freescale MC44S803 tuner found but no driver for that" \ - "tuner. Look at the Linuxtv.org for tuner driver" \ - "status."); -#endif - break; - case AF9013_TUNER_UNKNOWN: - default: - ret = -ENODEV; - err("Unknown tuner id:%d", - af9015_af9013_config[adap->id].tuner); - } - return ret; -} - -static struct usb_device_id af9015_usb_table[] = { -/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, - {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, - {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, -/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_TINYTWIN)}, - {USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_AZUREWAVE_AD_TU700)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, -/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, - {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, - {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, -/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, - {0}, -}; -MODULE_DEVICE_TABLE(usb, af9015_usb_table); - -static struct dvb_usb_device_properties af9015_properties[] = { - { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .download_firmware = af9015_download_firmware, - .firmware = "dvb-usb-af9015.fw", - - .size_of_priv = sizeof(struct af9015_state), \ - - .num_adapters = 2, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 32, - .pid_filter = af9015_pid_filter, - .pid_filter_ctrl = af9015_pid_filter_ctrl, - - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x84, - }, - }, - { - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x85, - }, - } - }, - - .identify_state = af9015_identify_state, - - .rc_query = af9015_rc_query, - .rc_interval = 150, - - .i2c_algo = &af9015_i2c_algo, - - .num_device_descs = 9, - .devices = { - { - .name = "Afatech AF9015 DVB-T USB2.0 stick", - .cold_ids = {&af9015_usb_table[0], - &af9015_usb_table[1], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Leadtek WinFast DTV Dongle Gold", - .cold_ids = {&af9015_usb_table[2], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Pinnacle PCTV 71e", - .cold_ids = {&af9015_usb_table[3], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "KWorld PlusTV Dual DVB-T Stick " \ - "(DVB-T 399U)", - .cold_ids = {&af9015_usb_table[4], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "DigitalNow TinyTwin DVB-T Receiver", - .cold_ids = {&af9015_usb_table[5], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "TwinHan AzureWave AD-TU700(704J)", - .cold_ids = {&af9015_usb_table[6], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9015_usb_table[7], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "KWorld PlusTV Dual DVB-T PCI " \ - "(DVB-T PC160-2T)", - .cold_ids = {&af9015_usb_table[8], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "AVerMedia AVerTV DVB-T Volar X", - .cold_ids = {&af9015_usb_table[9], NULL}, - .warm_ids = {NULL}, - }, - } - }, { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .download_firmware = af9015_download_firmware, - .firmware = "dvb-usb-af9015.fw", - - .size_of_priv = sizeof(struct af9015_state), \ - - .num_adapters = 2, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 32, - .pid_filter = af9015_pid_filter, - .pid_filter_ctrl = af9015_pid_filter_ctrl, - - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x84, - }, - }, - { - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x85, - }, - } - }, - - .identify_state = af9015_identify_state, - - .rc_query = af9015_rc_query, - .rc_interval = 150, - - .i2c_algo = &af9015_i2c_algo, - - .num_device_descs = 6, - .devices = { - { - .name = "Xtensions XD-380", - .cold_ids = {&af9015_usb_table[10], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "MSI DIGIVOX Duo", - .cold_ids = {&af9015_usb_table[11], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Fujitsu-Siemens Slim Mobile USB DVB-T", - .cold_ids = {&af9015_usb_table[12], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Telestar Starstick 2", - .cold_ids = {&af9015_usb_table[13], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "AVerMedia A309", - .cold_ids = {&af9015_usb_table[14], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "MSI Digi VOX mini III", - .cold_ids = {&af9015_usb_table[15], NULL}, - .warm_ids = {NULL}, - }, - } - } -}; - -static int af9015_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int ret = 0; - struct dvb_usb_device *d = NULL; - struct usb_device *udev = interface_to_usbdev(intf); - u8 i; - - deb_info("%s: interface:%d\n", __func__, - intf->cur_altsetting->desc.bInterfaceNumber); - - /* interface 0 is used by DVB-T receiver and - interface 1 is for remote controller (HID) */ - if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { - ret = af9015_read_config(udev); - if (ret) - return ret; - - for (i = 0; i < af9015_properties_count; i++) { - ret = dvb_usb_device_init(intf, &af9015_properties[i], - THIS_MODULE, &d, adapter_nr); - if (!ret) - break; - if (ret != -ENODEV) - return ret; - } - if (ret) - return ret; - - if (d) - ret = af9015_init(d); - } - - return ret; -} - -void af9015_i2c_exit(struct dvb_usb_device *d) -{ - struct af9015_state *state = d->priv; - deb_info("%s: \n", __func__); - - /* remove 2nd I2C adapter */ - if (d->state & DVB_USB_STATE_I2C) - i2c_del_adapter(&state->i2c_adap); -} - -static void af9015_usb_device_exit(struct usb_interface *intf) -{ - struct dvb_usb_device *d = usb_get_intfdata(intf); - deb_info("%s: \n", __func__); - - /* remove 2nd I2C adapter */ - if (d != NULL && d->desc != NULL) - af9015_i2c_exit(d); - - dvb_usb_device_exit(intf); -} - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver af9015_usb_driver = { - .name = "dvb_usb_af9015", - .probe = af9015_usb_probe, - .disconnect = af9015_usb_device_exit, - .id_table = af9015_usb_table, -}; - -/* module stuff */ -static int __init af9015_usb_module_init(void) -{ - int ret; - ret = usb_register(&af9015_usb_driver); - if (ret) - err("module init failed:%d", ret); - - return ret; -} - -static void __exit af9015_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&af9015_usb_driver); -} - -module_init(af9015_usb_module_init); -module_exit(af9015_usb_module_exit); - -MODULE_AUTHOR("Antti Palosaari "); -MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/dvb-usb/af9015.h b/trunk/drivers/media/dvb/dvb-usb/af9015.h deleted file mode 100644 index 882e8a4b3681..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/af9015.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _DVB_USB_AF9015_H_ -#define _DVB_USB_AF9015_H_ - -#define DVB_USB_LOG_PREFIX "af9015" -#include "dvb-usb.h" - -extern int dvb_usb_af9015_debug; -#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) -#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) -#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) -#define deb_reg(args...) dprintk(dvb_usb_af9015_debug, 0x08, args) -#define deb_i2c(args...) dprintk(dvb_usb_af9015_debug, 0x10, args) -#define deb_fw(args...) dprintk(dvb_usb_af9015_debug, 0x20, args) - -#define AF9015_I2C_EEPROM 0xa0 -#define AF9015_I2C_DEMOD 0x38 -#define AF9015_USB_TIMEOUT 2000 - -/* EEPROM locations */ -#define AF9015_EEPROM_IR_MODE 0x18 -#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34 -#define AF9015_EEPROM_TS_MODE 0x31 -#define AF9015_EEPROM_DEMOD2_I2C 0x32 - -#define AF9015_EEPROM_SAW_BW1 0x35 -#define AF9015_EEPROM_XTAL_TYPE1 0x36 -#define AF9015_EEPROM_SPEC_INV1 0x37 -#define AF9015_EEPROM_IF1L 0x38 -#define AF9015_EEPROM_IF1H 0x39 -#define AF9015_EEPROM_MT2060_IF1L 0x3a -#define AF9015_EEPROM_MT2060_IF1H 0x3b -#define AF9015_EEPROM_TUNER_ID1 0x3c - -#define AF9015_EEPROM_SAW_BW2 0x45 -#define AF9015_EEPROM_XTAL_TYPE2 0x46 -#define AF9015_EEPROM_SPEC_INV2 0x47 -#define AF9015_EEPROM_IF2L 0x48 -#define AF9015_EEPROM_IF2H 0x49 -#define AF9015_EEPROM_MT2060_IF2L 0x4a -#define AF9015_EEPROM_MT2060_IF2H 0x4b -#define AF9015_EEPROM_TUNER_ID2 0x4c - -#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1) - -#define AF9015_GPIO_ON (1 << 0) -#define AF9015_GPIO_EN (1 << 1) -#define AF9015_GPIO_O (1 << 2) -#define AF9015_GPIO_I (1 << 3) - -#define AF9015_GPIO_TUNER_ON (AF9015_GPIO_ON|AF9015_GPIO_EN) -#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O) - -struct req_t { - u8 cmd; /* [0] */ - /* seq */ /* [1] */ - u8 i2c_addr; /* [2] */ - u16 addr; /* [3|4] */ - u8 mbox; /* [5] */ - u8 addr_len; /* [6] */ - u8 data_len; /* [7] */ - u8 *data; -}; - -enum af9015_cmd { - GET_CONFIG = 0x10, - DOWNLOAD_FIRMWARE = 0x11, - BOOT = 0x13, - READ_MEMORY = 0x20, - WRITE_MEMORY = 0x21, - READ_WRITE_I2C = 0x22, - COPY_FIRMWARE = 0x23, - RECONNECT_USB = 0x5a, - WRITE_VIRTUAL_MEMORY = 0x26, - GET_IR_CODE = 0x27, - READ_I2C, - WRITE_I2C, -}; - -enum af9015_ir_mode { - AF9015_IR_MODE_DISABLED = 0, - AF9015_IR_MODE_HID, - AF9015_IR_MODE_RLC, - AF9015_IR_MODE_RC6, -}; - -struct af9015_state { - struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ -}; - -struct af9015_config { - u8 dual_mode:1; - u16 mt2060_if1[2]; - u16 firmware_size; - u16 firmware_checksum; - u8 *ir_table; - u16 ir_table_size; -}; - -enum af9015_remote { - AF9015_REMOTE_NONE = 0, - AF9015_REMOTE_A_LINK_DTU_M, - AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, - AF9015_REMOTE_MYGICTV_U718, -}; - -/* Leadtek WinFast DTV Dongle Gold */ -static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x28, KEY_ENTER }, - { 0x00, 0x4f, KEY_VOLUMEUP }, - { 0x00, 0x50, KEY_VOLUMEDOWN }, - { 0x00, 0x51, KEY_CHANNELDOWN }, - { 0x00, 0x52, KEY_CHANNELUP }, -}; - -static u8 af9015_ir_table_leadtek[] = { - 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, - 0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, - 0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, - 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, - 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, - 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, - 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, - 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, - 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, - 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, - 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, - 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, - 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, - 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, - 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, - 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, - 0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, - 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, - 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, - 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, - 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, - 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, - 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, - 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, - 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, - 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, - 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, - 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, - 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, - 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, - 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, - 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, - 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, - 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, - 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, - 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, - 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, - 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, - 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, - 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, - 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, - 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, - 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, - 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, - 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, -}; - -/* TwinHan AzureWave AD-TU700(704J) */ -static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = { - { 0x05, 0x3f, KEY_POWER }, - { 0x00, 0x19, KEY_FAVORITES }, /* Favorite List */ - { 0x00, 0x04, KEY_TEXT }, /* Teletext */ - { 0x00, 0x0e, KEY_POWER }, - { 0x00, 0x0e, KEY_INFO }, /* Preview */ - { 0x00, 0x08, KEY_EPG }, /* Info/EPG */ - { 0x00, 0x0f, KEY_LIST }, /* Record List */ - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x29, KEY_CANCEL }, /* Cancel */ - { 0x00, 0x4c, KEY_CLEAR }, /* Clear */ - { 0x00, 0x2a, KEY_BACK }, /* Back */ - { 0x00, 0x2b, KEY_TAB }, /* Tab */ - { 0x00, 0x52, KEY_UP }, /* up arrow */ - { 0x00, 0x51, KEY_DOWN }, /* down arrow */ - { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */ - { 0x00, 0x50, KEY_LEFT }, /* left arrow */ - { 0x00, 0x28, KEY_ENTER }, /* Enter / ok */ - { 0x02, 0x52, KEY_VOLUMEUP }, - { 0x02, 0x51, KEY_VOLUMEDOWN }, - { 0x00, 0x4e, KEY_CHANNELDOWN }, - { 0x00, 0x4b, KEY_CHANNELUP }, - { 0x00, 0x4a, KEY_RECORD }, - { 0x01, 0x11, KEY_PLAY }, - { 0x00, 0x17, KEY_PAUSE }, - { 0x00, 0x0c, KEY_REWIND }, /* FR << */ - { 0x00, 0x11, KEY_FASTFORWARD }, /* FF >> */ - { 0x01, 0x15, KEY_PREVIOUS }, /* Replay */ - { 0x01, 0x0e, KEY_NEXT }, /* Skip */ - { 0x00, 0x13, KEY_CAMERA }, /* Capture */ - { 0x01, 0x0f, KEY_LANGUAGE }, /* SAP */ - { 0x01, 0x13, KEY_TV2 }, /* PIP */ - { 0x00, 0x1d, KEY_ZOOM }, /* Full Screen */ - { 0x01, 0x17, KEY_SUBTITLE }, /* Subtitle / CC */ - { 0x00, 0x10, KEY_MUTE }, - { 0x01, 0x19, KEY_AUDIO }, /* L/R */ /* TODO better event */ - { 0x01, 0x16, KEY_SLEEP }, /* Hibernate */ - { 0x01, 0x16, KEY_SWITCHVIDEOMODE }, - /* A/V */ /* TODO does not work */ - { 0x00, 0x06, KEY_AGAIN }, /* Recall */ - { 0x01, 0x16, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */ - { 0x01, 0x16, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */ - { 0x02, 0x15, KEY_RED }, - { 0x02, 0x0a, KEY_GREEN }, - { 0x02, 0x1c, KEY_YELLOW }, - { 0x02, 0x05, KEY_BLUE }, -}; - -static u8 af9015_ir_table_twinhan[] = { - 0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00, - 0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00, - 0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00, - 0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00, - 0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00, - 0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00, - 0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00, - 0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00, - 0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00, - 0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00, - 0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00, - 0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00, - 0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00, - 0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00, - 0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00, - 0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00, - 0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00, - 0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00, - 0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00, - 0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00, - 0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00, - 0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00, - 0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00, - 0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00, - 0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00, - 0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00, - 0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00, - 0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00, - 0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00, - 0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00, - 0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00, - 0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00, - 0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00, - 0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00, - 0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00, - 0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00, - 0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00, - 0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00, - 0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00, - 0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00, - 0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00, - 0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00, - 0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00, - 0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00, - 0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00, - 0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00, - 0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00, - 0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00, - 0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00, -}; - -/* A-Link DTU(m) */ -static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = { - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x2e, KEY_CHANNELUP }, - { 0x00, 0x2d, KEY_CHANNELDOWN }, - { 0x04, 0x28, KEY_ZOOM }, - { 0x00, 0x41, KEY_MUTE }, - { 0x00, 0x42, KEY_VOLUMEDOWN }, - { 0x00, 0x43, KEY_VOLUMEUP }, - { 0x00, 0x44, KEY_GOTO }, /* jump */ - { 0x05, 0x45, KEY_POWER }, -}; - -static u8 af9015_ir_table_a_link[] = { - 0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */ - 0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */ - 0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */ - 0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */ - 0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */ - 0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */ - 0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */ - 0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */ - 0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */ - 0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */ - 0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */ - 0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */ - 0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */ - 0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */ - 0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */ - 0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */ - 0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */ - 0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */ -}; - -/* MSI DIGIVOX mini II V3.0 */ -static struct dvb_usb_rc_key af9015_rc_keys_msi[] = { - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x03, 0x0f, KEY_CHANNELUP }, - { 0x03, 0x0e, KEY_CHANNELDOWN }, - { 0x00, 0x42, KEY_VOLUMEDOWN }, - { 0x00, 0x43, KEY_VOLUMEUP }, - { 0x05, 0x45, KEY_POWER }, - { 0x00, 0x52, KEY_UP }, /* up */ - { 0x00, 0x51, KEY_DOWN }, /* down */ - { 0x00, 0x28, KEY_ENTER }, -}; - -static u8 af9015_ir_table_msi[] = { - 0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */ - 0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */ - 0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */ - 0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */ - 0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */ - 0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */ - 0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */ - 0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */ - 0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */ - 0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */ - 0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */ - 0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */ - 0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */ - 0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */ - 0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */ - 0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */ - 0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */ - 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */ -}; - -/* MYGICTV U718 */ -static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = { - { 0x00, 0x3d, KEY_SWITCHVIDEOMODE }, - /* TV / AV */ - { 0x05, 0x45, KEY_POWER }, - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x41, KEY_MUTE }, - { 0x00, 0x2a, KEY_ESC }, /* Esc */ - { 0x00, 0x2e, KEY_CHANNELUP }, - { 0x00, 0x2d, KEY_CHANNELDOWN }, - { 0x00, 0x42, KEY_VOLUMEDOWN }, - { 0x00, 0x43, KEY_VOLUMEUP }, - { 0x00, 0x52, KEY_UP }, /* up arrow */ - { 0x00, 0x51, KEY_DOWN }, /* down arrow */ - { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */ - { 0x00, 0x50, KEY_LEFT }, /* left arrow */ - { 0x00, 0x28, KEY_ENTER }, /* ok */ - { 0x01, 0x15, KEY_RECORD }, - { 0x03, 0x13, KEY_PLAY }, - { 0x01, 0x13, KEY_PAUSE }, - { 0x01, 0x16, KEY_STOP }, - { 0x03, 0x07, KEY_REWIND }, /* FR << */ - { 0x03, 0x09, KEY_FASTFORWARD }, /* FF >> */ - { 0x00, 0x3b, KEY_TIME }, /* TimeShift */ - { 0x00, 0x3e, KEY_CAMERA }, /* Snapshot */ - { 0x03, 0x16, KEY_CYCLEWINDOWS }, /* yellow, min / max */ - { 0x00, 0x00, KEY_ZOOM }, /* 'select' (?) */ - { 0x03, 0x16, KEY_SHUFFLE }, /* Shuffle */ - { 0x03, 0x45, KEY_POWER }, -}; - -static u8 af9015_ir_table_mygictv[] = { - 0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */ - 0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */ - 0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */ - 0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */ - 0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */ - 0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */ - 0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */ - 0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */ - 0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */ - 0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */ - 0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */ - 0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */ - 0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */ - 0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */ - 0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */ - 0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */ - 0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */ - 0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */ - 0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */ - 0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */ - 0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */ - 0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */ - 0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */ - 0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */ - 0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */ - 0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */ - 0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */ - 0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */ - 0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */ - 0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */ - 0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */ - 0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */ - 0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */ - 0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */ - 0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */ -}; - -/* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */ -static u8 af9015_ir_table_kworld[] = { - 0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00, - 0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00, - 0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00, - 0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00, - 0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00, - 0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00, - 0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00, - 0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00, - 0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00, - 0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00, - 0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00, - 0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00, - 0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00, - 0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00, - 0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00, - 0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00, - 0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00, - 0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00, - 0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00, - 0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00, - 0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00, - 0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00, - 0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00, - 0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00, - 0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00, - 0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00, - 0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00, - 0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00, - 0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00, - 0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00, - 0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00, - 0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00, - 0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00, - 0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00, - 0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00, - 0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00, - 0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00, - 0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00, - 0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00, - 0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00, - 0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00, - 0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00, - 0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00, - 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00, -}; - -#endif diff --git a/trunk/drivers/media/dvb/dvb-usb/anysee.c b/trunk/drivers/media/dvb/dvb-usb/anysee.c index c786359fba03..2f408d2e1ef3 100644 --- a/trunk/drivers/media/dvb/dvb-usb/anysee.c +++ b/trunk/drivers/media/dvb/dvb-usb/anysee.c @@ -41,9 +41,6 @@ static int dvb_usb_anysee_debug; module_param_named(debug, dvb_usb_anysee_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -int dvb_usb_anysee_delsys; -module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644); -MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static struct mutex anysee_usb_mutex; @@ -181,14 +178,14 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, inc = 1; } if (ret) - break; + return ret; i += inc; } mutex_unlock(&d->i2c_mutex); - return ret ? ret : i; + return i; } static u32 anysee_i2c_func(struct i2c_adapter *adapter) @@ -275,11 +272,9 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) model demod hw firmware 1. E30 MT352 02 0.2.1 2. E30 ZL10353 02 0.2.1 - 3. E30 Combo ZL10353 0f 0.1.2 DVB-T/C combo - 4. E30 Plus ZL10353 06 0.1.0 - 5. E30C Plus TDA10023 0a 0.1.0 rev 0.2 - E30C Plus TDA10023 0f 0.1.2 rev 0.4 - E30 Combo TDA10023 0f 0.1.2 DVB-T/C combo + 3. E30 Plus ZL10353 06 0.1.0 + 4. E30C Plus TDA10023 0a 0.1.0 rev 0.2 + 4. E30C Plus TDA10023 0f 0.1.2 rev 0.4 */ /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ @@ -298,21 +293,6 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) return 0; } - /* for E30 Combo Plus DVB-T demodulator */ - if (dvb_usb_anysee_delsys) { - ret = anysee_write_reg(adap->dev, 0xb0, 0x01); - if (ret) - return ret; - - /* Zarlink ZL10353 DVB-T demod */ - adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe != NULL) { - state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; - return 0; - } - } - /* connect demod on IO port D for TDA10023 & ZL10353 */ ret = anysee_write_reg(adap->dev, 0xb0, 0x25); if (ret) diff --git a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/trunk/drivers/media/dvb/dvb-usb/cinergyT2-core.c deleted file mode 100644 index 3ac9f74e9fbf..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-core.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * TerraTec Cinergy T2/qanu USB2 DVB-T adapter. - * - * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi) - * - * Based on the dvb-usb-framework code and the - * original Terratec Cinergy T2 driver by: - * - * Copyright (C) 2004 Daniel Mack and - * Holger Waechtler - * - * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "cinergyT2.h" - - -/* debug */ -int dvb_usb_cinergyt2_debug; -int disable_remote; - -module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 " - "(or-able))."); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct cinergyt2_state { - u8 rc_counter; -}; - -/* We are missing a release hook with usb_device data */ -struct dvb_usb_device *cinergyt2_usb_device; - -static struct dvb_usb_device_properties cinergyt2_properties; - -static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable) -{ - char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 }; - char result[64]; - return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result, - sizeof(result), 0); -} - -static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable) -{ - char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 }; - char state[3]; - return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0); -} - -static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) -{ - char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION }; - char state[3]; - int ret; - - adap->fe = cinergyt2_fe_attach(adap->dev); - - ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state, - sizeof(state), 0); - if (ret < 0) { - deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep " - "state info\n"); - } - - /* Copy this pointer as we are gonna need it in the release phase */ - cinergyt2_usb_device = adap->dev; - - return 0; -} - -static struct dvb_usb_rc_key cinergyt2_rc_keys[] = { - { 0x04, 0x01, KEY_POWER }, - { 0x04, 0x02, KEY_1 }, - { 0x04, 0x03, KEY_2 }, - { 0x04, 0x04, KEY_3 }, - { 0x04, 0x05, KEY_4 }, - { 0x04, 0x06, KEY_5 }, - { 0x04, 0x07, KEY_6 }, - { 0x04, 0x08, KEY_7 }, - { 0x04, 0x09, KEY_8 }, - { 0x04, 0x0a, KEY_9 }, - { 0x04, 0x0c, KEY_0 }, - { 0x04, 0x0b, KEY_VIDEO }, - { 0x04, 0x0d, KEY_REFRESH }, - { 0x04, 0x0e, KEY_SELECT }, - { 0x04, 0x0f, KEY_EPG }, - { 0x04, 0x10, KEY_UP }, - { 0x04, 0x14, KEY_DOWN }, - { 0x04, 0x11, KEY_LEFT }, - { 0x04, 0x13, KEY_RIGHT }, - { 0x04, 0x12, KEY_OK }, - { 0x04, 0x15, KEY_TEXT }, - { 0x04, 0x16, KEY_INFO }, - { 0x04, 0x17, KEY_RED }, - { 0x04, 0x18, KEY_GREEN }, - { 0x04, 0x19, KEY_YELLOW }, - { 0x04, 0x1a, KEY_BLUE }, - { 0x04, 0x1c, KEY_VOLUMEUP }, - { 0x04, 0x1e, KEY_VOLUMEDOWN }, - { 0x04, 0x1d, KEY_MUTE }, - { 0x04, 0x1b, KEY_CHANNELUP }, - { 0x04, 0x1f, KEY_CHANNELDOWN }, - { 0x04, 0x40, KEY_PAUSE }, - { 0x04, 0x4c, KEY_PLAY }, - { 0x04, 0x58, KEY_RECORD }, - { 0x04, 0x54, KEY_PREVIOUS }, - { 0x04, 0x48, KEY_STOP }, - { 0x04, 0x5c, KEY_NEXT } -}; - -/* Number of keypresses to ignore before detect repeating */ -#define RC_REPEAT_DELAY 3 - -static int repeatable_keys[] = { - KEY_UP, - KEY_DOWN, - KEY_LEFT, - KEY_RIGHT, - KEY_VOLUMEUP, - KEY_VOLUMEDOWN, - KEY_CHANNELUP, - KEY_CHANNELDOWN -}; - -static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct cinergyt2_state *st = d->priv; - u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS; - int i; - - *state = REMOTE_NO_KEY_PRESSED; - - dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0); - if (key[4] == 0xff) { - /* key repeat */ - st->rc_counter++; - if (st->rc_counter > RC_REPEAT_DELAY) { - for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) { - if (d->last_event == repeatable_keys[i]) { - *state = REMOTE_KEY_REPEAT; - *event = d->last_event; - deb_rc("repeat key, event %x\n", - *event); - return 0; - } - } - deb_rc("repeated key (non repeatable)\n"); - } - return 0; - } - - /* hack to pass checksum on the custom field */ - key[2] = ~key[1]; - dvb_usb_nec_rc_key_to_event(d, key, event, state); - if (key[0] != 0) { - if (*event != d->last_event) - st->rc_counter = 0; - - deb_rc("key: %x %x %x %x %x\n", - key[0], key[1], key[2], key[3], key[4]); - } - return 0; -} - -static int cinergyt2_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &cinergyt2_properties, - THIS_MODULE, NULL, adapter_nr); -} - - -static struct usb_device_id cinergyt2_usb_table[] = { - { USB_DEVICE(USB_VID_TERRATEC, 0x0038) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table); - -static struct dvb_usb_device_properties cinergyt2_properties = { - .size_of_priv = sizeof(struct cinergyt2_state), - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cinergyt2_streaming_ctrl, - .frontend_attach = cinergyt2_frontend_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - } - }, - - .power_ctrl = cinergyt2_power_ctrl, - - .rc_interval = 50, - .rc_key_map = cinergyt2_rc_keys, - .rc_key_map_size = ARRAY_SIZE(cinergyt2_rc_keys), - .rc_query = cinergyt2_rc_query, - - .generic_bulk_ctrl_endpoint = 1, - - .num_device_descs = 1, - .devices = { - { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver", - .cold_ids = {NULL}, - .warm_ids = { &cinergyt2_usb_table[0], NULL }, - }, - { NULL }, - } -}; - - -static struct usb_driver cinergyt2_driver = { - .name = "cinergyT2", - .probe = cinergyt2_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = cinergyt2_usb_table -}; - -static int __init cinergyt2_usb_init(void) -{ - int err; - - err = usb_register(&cinergyt2_driver); - if (err) { - err("usb_register() failed! (err %i)\n", err); - return err; - } - return 0; -} - -static void __exit cinergyt2_usb_exit(void) -{ - usb_deregister(&cinergyt2_driver); -} - -module_init(cinergyt2_usb_init); -module_exit(cinergyt2_usb_exit); - -MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tomi Orava"); diff --git a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c deleted file mode 100644 index 649f25cca49e..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * TerraTec Cinergy T2/qanu USB2 DVB-T adapter. - * - * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi) - * - * Based on the dvb-usb-framework code and the - * original Terratec Cinergy T2 driver by: - * - * Copyright (C) 2004 Daniel Mack and - * Holger Waechtler - * - * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "cinergyT2.h" - - -/** - * convert linux-dvb frontend parameter set into TPS. - * See ETSI ETS-300744, section 4.6.2, table 9 for details. - * - * This function is probably reusable and may better get placed in a support - * library. - * - * We replace errornous fields by default TPS fields (the ones with value 0). - */ - -static uint16_t compute_tps(struct dvb_frontend_parameters *p) -{ - struct dvb_ofdm_parameters *op = &p->u.ofdm; - uint16_t tps = 0; - - switch (op->code_rate_HP) { - case FEC_2_3: - tps |= (1 << 7); - break; - case FEC_3_4: - tps |= (2 << 7); - break; - case FEC_5_6: - tps |= (3 << 7); - break; - case FEC_7_8: - tps |= (4 << 7); - break; - case FEC_1_2: - case FEC_AUTO: - default: - /* tps |= (0 << 7) */; - } - - switch (op->code_rate_LP) { - case FEC_2_3: - tps |= (1 << 4); - break; - case FEC_3_4: - tps |= (2 << 4); - break; - case FEC_5_6: - tps |= (3 << 4); - break; - case FEC_7_8: - tps |= (4 << 4); - break; - case FEC_1_2: - case FEC_AUTO: - default: - /* tps |= (0 << 4) */; - } - - switch (op->constellation) { - case QAM_16: - tps |= (1 << 13); - break; - case QAM_64: - tps |= (2 << 13); - break; - case QPSK: - default: - /* tps |= (0 << 13) */; - } - - switch (op->transmission_mode) { - case TRANSMISSION_MODE_8K: - tps |= (1 << 0); - break; - case TRANSMISSION_MODE_2K: - default: - /* tps |= (0 << 0) */; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_16: - tps |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - tps |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - tps |= (3 << 2); - break; - case GUARD_INTERVAL_1_32: - default: - /* tps |= (0 << 2) */; - } - - switch (op->hierarchy_information) { - case HIERARCHY_1: - tps |= (1 << 10); - break; - case HIERARCHY_2: - tps |= (2 << 10); - break; - case HIERARCHY_4: - tps |= (3 << 10); - break; - case HIERARCHY_NONE: - default: - /* tps |= (0 << 10) */; - } - - return tps; -} - -struct cinergyt2_fe_state { - struct dvb_frontend fe; - struct dvb_usb_device *d; -}; - -static int cinergyt2_fe_read_status(struct dvb_frontend *fe, - fe_status_t *status) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg result; - u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result, - sizeof(result), 0); - if (ret < 0) - return ret; - - *status = 0; - - if (0xffff - le16_to_cpu(result.gain) > 30) - *status |= FE_HAS_SIGNAL; - if (result.lock_bits & (1 << 6)) - *status |= FE_HAS_LOCK; - if (result.lock_bits & (1 << 5)) - *status |= FE_HAS_SYNC; - if (result.lock_bits & (1 << 4)) - *status |= FE_HAS_CARRIER; - if (result.lock_bits & (1 << 1)) - *status |= FE_HAS_VITERBI; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, - sizeof(status), 0); - if (ret < 0) - return ret; - - *ber = le32_to_cpu(status.viterbi_error_rate); - return 0; -} - -static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status, - sizeof(status), 0); - if (ret < 0) { - err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n", - ret); - return ret; - } - *unc = le32_to_cpu(status.uncorrected_block_count); - return 0; -} - -static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe, - u16 *strength) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, - sizeof(status), 0); - if (ret < 0) { - err("cinergyt2_fe_read_signal_strength() Failed!" - " (Error=%d)\n", ret); - return ret; - } - *strength = (0xffff - le16_to_cpu(status.gain)); - return 0; -} - -static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, - sizeof(status), 0); - if (ret < 0) { - err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret); - return ret; - } - *snr = (status.snr << 8) | status.snr; - return 0; -} - -static int cinergyt2_fe_init(struct dvb_frontend *fe) -{ - return 0; -} - -static int cinergyt2_fe_sleep(struct dvb_frontend *fe) -{ - deb_info("cinergyt2_fe_sleep() Called\n"); - return 0; -} - -static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 800; - return 0; -} - -static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_set_parameters_msg param; - char result[2]; - int err; - - param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; - param.tps = cpu_to_le16(compute_tps(fep)); - param.freq = cpu_to_le32(fep->frequency / 1000); - param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; - - err = dvb_usb_generic_rw(state->d, - (char *)¶m, sizeof(param), - result, sizeof(result), 0); - if (err < 0) - err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err); - - return (err < 0) ? err : 0; -} - -static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - -static void cinergyt2_fe_release(struct dvb_frontend *fe) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - if (state != NULL) - kfree(state); -} - -static struct dvb_frontend_ops cinergyt2_fe_ops; - -struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) -{ - struct cinergyt2_fe_state *s = kzalloc(sizeof( - struct cinergyt2_fe_state), GFP_KERNEL); - if (s == NULL) - return NULL; - - s->d = d; - memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; - return &s->fe; -} - - -static struct dvb_frontend_ops cinergyt2_fe_ops = { - .info = { - .name = DRIVER_NAME, - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 - | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 - | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 - | FE_CAN_FEC_AUTO | FE_CAN_QPSK - | FE_CAN_QAM_16 | FE_CAN_QAM_64 - | FE_CAN_QAM_AUTO - | FE_CAN_TRANSMISSION_MODE_AUTO - | FE_CAN_GUARD_INTERVAL_AUTO - | FE_CAN_HIERARCHY_AUTO - | FE_CAN_RECOVER - | FE_CAN_MUTE_TS - }, - - .release = cinergyt2_fe_release, - - .init = cinergyt2_fe_init, - .sleep = cinergyt2_fe_sleep, - - .set_frontend = cinergyt2_fe_set_frontend, - .get_frontend = cinergyt2_fe_get_frontend, - .get_tune_settings = cinergyt2_fe_get_tune_settings, - - .read_status = cinergyt2_fe_read_status, - .read_ber = cinergyt2_fe_read_ber, - .read_signal_strength = cinergyt2_fe_read_signal_strength, - .read_snr = cinergyt2_fe_read_snr, - .read_ucblocks = cinergyt2_fe_read_unc_blocks, -}; diff --git a/trunk/drivers/media/dvb/dvb-usb/cinergyT2.h b/trunk/drivers/media/dvb/dvb-usb/cinergyT2.h deleted file mode 100644 index 11d79eb384c8..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/cinergyT2.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * TerraTec Cinergy T2/qanu USB2 DVB-T adapter. - * - * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi) - * - * Based on the dvb-usb-framework code and the - * original Terratec Cinergy T2 driver by: - * - * Copyright (C) 2004 Daniel Mack and - * Holger Waechtler - * - * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _DVB_USB_CINERGYT2_H_ -#define _DVB_USB_CINERGYT2_H_ - -#include - -#define DVB_USB_LOG_PREFIX "cinergyT2" -#include "dvb-usb.h" - -#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver" - -extern int dvb_usb_cinergyt2_debug; - -#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args) -#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args) -#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args) -#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args) -#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args) -#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args) -#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args) -#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args) -#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args) - - - -enum cinergyt2_ep1_cmd { - CINERGYT2_EP1_PID_TABLE_RESET = 0x01, - CINERGYT2_EP1_PID_SETUP = 0x02, - CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03, - CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04, - CINERGYT2_EP1_GET_TUNER_STATUS = 0x05, - CINERGYT2_EP1_START_SCAN = 0x06, - CINERGYT2_EP1_CONTINUE_SCAN = 0x07, - CINERGYT2_EP1_GET_RC_EVENTS = 0x08, - CINERGYT2_EP1_SLEEP_MODE = 0x09, - CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A -}; - - -struct dvbt_get_status_msg { - uint32_t freq; - uint8_t bandwidth; - uint16_t tps; - uint8_t flags; - uint16_t gain; - uint8_t snr; - uint32_t viterbi_error_rate; - uint32_t rs_error_rate; - uint32_t uncorrected_block_count; - uint8_t lock_bits; - uint8_t prev_lock_bits; -} __attribute__((packed)); - - -struct dvbt_set_parameters_msg { - uint8_t cmd; - uint32_t freq; - uint8_t bandwidth; - uint16_t tps; - uint8_t flags; -} __attribute__((packed)); - - -extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d); - -#endif /* _DVB_USB_CINERGYT2_H_ */ - diff --git a/trunk/drivers/media/dvb/dvb-usb/cxusb.c b/trunk/drivers/media/dvb/dvb-usb/cxusb.c index 406d7fba369d..563400277a42 100644 --- a/trunk/drivers/media/dvb/dvb-usb/cxusb.c +++ b/trunk/drivers/media/dvb/dvb-usb/cxusb.c @@ -36,9 +36,6 @@ #include "tuner-xc2028.h" #include "tuner-simple.h" #include "mxl5005s.h" -#include "dib7000p.h" -#include "dib0070.h" -#include "lgs8gl5.h" /* debug */ static int dvb_usb_cxusb_debug; @@ -112,25 +109,6 @@ static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff) cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); } -static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, - u8 addr, int onoff) -{ - u8 o[2] = {addr, onoff}; - u8 i; - int rc; - - rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - - if (rc < 0) - return rc; - if (i == 0x01) - return 0; - else { - deb_info("gpio_write failed.\n"); - return -EIO; - } -} - /* I2C */ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) @@ -284,20 +262,6 @@ static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff) return rc; } -static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - int ret; - u8 b; - ret = cxusb_power_ctrl(d, onoff); - if (!onoff) - return ret; - - msleep(128); - cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1); - msleep(100); - return ret; -} - static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { u8 buf[2] = { 0x03, 0x00 }; @@ -319,67 +283,6 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return 0; } -static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) -{ - int ep = d->props.generic_bulk_ctrl_endpoint; - const int timeout = 100; - const int junk_len = 32; - u8 *junk; - int rd_count; - - /* Discard remaining data in video pipe */ - junk = kmalloc(junk_len, GFP_KERNEL); - if (!junk) - return; - while (1) { - if (usb_bulk_msg(d->udev, - usb_rcvbulkpipe(d->udev, ep), - junk, junk_len, &rd_count, timeout) < 0) - break; - if (!rd_count) - break; - } - kfree(junk); -} - -static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) -{ - struct usb_data_stream_properties *p = &d->props.adapter[0].stream; - const int timeout = 100; - const int junk_len = p->u.bulk.buffersize; - u8 *junk; - int rd_count; - - /* Discard remaining data in video pipe */ - junk = kmalloc(junk_len, GFP_KERNEL); - if (!junk) - return; - while (1) { - if (usb_bulk_msg(d->udev, - usb_rcvbulkpipe(d->udev, p->endpoint), - junk, junk_len, &rd_count, timeout) < 0) - break; - if (!rd_count) - break; - } - kfree(junk); -} - -static int cxusb_d680_dmb_streaming_ctrl( - struct dvb_usb_adapter *adap, int onoff) -{ - if (onoff) { - u8 buf[2] = { 0x03, 0x00 }; - cxusb_d680_dmb_drain_video(adap->dev); - return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, - buf, sizeof(buf), NULL, 0); - } else { - int ret = cxusb_ctrl_msg(adap->dev, - CMD_STREAMING_OFF, NULL, 0, NULL, 0); - return ret; - } -} - static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { struct dvb_usb_rc_key *keymap = d->props.rc_key_map; @@ -432,32 +335,6 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, return 0; } -static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, - int *state) -{ - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - u8 ircode[2]; - int i; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) - return 0; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == ircode[0] && - keymap[i].data == ircode[1]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - - return 0; - } - } - - return 0; -} - static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { { 0xfe, 0x02, KEY_TV }, { 0xfe, 0x0e, KEY_MP3 }, @@ -545,44 +422,6 @@ static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ }; -static struct dvb_usb_rc_key d680_dmb_rc_keys[] = { - { 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */ - { 0x08, 0x0c, KEY_ZOOM }, - { 0x08, 0x00, KEY_0 }, - { 0x00, 0x01, KEY_1 }, - { 0x08, 0x02, KEY_2 }, - { 0x00, 0x03, KEY_3 }, - { 0x08, 0x04, KEY_4 }, - { 0x00, 0x05, KEY_5 }, - { 0x08, 0x06, KEY_6 }, - { 0x00, 0x07, KEY_7 }, - { 0x08, 0x08, KEY_8 }, - { 0x00, 0x09, KEY_9 }, - { 0x00, 0x0a, KEY_MUTE }, - { 0x08, 0x29, KEY_BACK }, - { 0x00, 0x12, KEY_CHANNELUP }, - { 0x08, 0x13, KEY_CHANNELDOWN }, - { 0x00, 0x2b, KEY_VOLUMEUP }, - { 0x08, 0x2c, KEY_VOLUMEDOWN }, - { 0x00, 0x20, KEY_UP }, - { 0x08, 0x21, KEY_DOWN }, - { 0x00, 0x11, KEY_LEFT }, - { 0x08, 0x10, KEY_RIGHT }, - { 0x00, 0x0d, KEY_OK }, - { 0x08, 0x1f, KEY_RECORD }, - { 0x00, 0x17, KEY_PLAYPAUSE }, - { 0x08, 0x16, KEY_PLAYPAUSE }, - { 0x00, 0x0b, KEY_STOP }, - { 0x08, 0x27, KEY_FASTFORWARD }, - { 0x00, 0x26, KEY_REWIND }, - { 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */ - { 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */ - { 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */ - { 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */ - { 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */ - { 0x00, 0x25, KEY_POWER }, -}; - static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) { static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; @@ -688,24 +527,6 @@ static struct mxl5005s_config aver_a868r_tuner = { .AgcMasterByte = 0x00, }; -/* FIXME: needs tweaking */ -static struct mxl5005s_config d680_dmb_tuner = { - .i2c_address = 0x63, - .if_freq = 36125000UL, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_C, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - /* Callbacks for DVB USB */ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) { @@ -742,8 +563,7 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static int dvico_bluebird_xc2028_callback(void *ptr, int component, - int command, int arg) +static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) { struct dvb_usb_adapter *adap = ptr; struct dvb_usb_device *d = adap->dev; @@ -771,16 +591,14 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) struct xc2028_config cfg = { .i2c_adap = &adap->dev->i2c_adap, .i2c_addr = 0x61, + .callback = dvico_bluebird_xc2028_callback, }; static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, + .fname = "xc3028-v27.fw", .max_len = 64, .demod = XC3028_FE_ZARLINK456, }; - /* FIXME: generalize & move to common area */ - adap->fe->callback = dvico_bluebird_xc2028_callback; - fe = dvb_attach(xc2028_attach, adap->fe, &cfg); if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) return -EIO; @@ -797,14 +615,6 @@ static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_frontend *fe; - fe = dvb_attach(mxl5005s_attach, adap->fe, - &adap->dev->i2c_adap, &d680_dmb_tuner); - return (fe == NULL) ? -EIO : 0; -} - static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) { u8 b; @@ -916,159 +726,6 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static struct dibx000_agc_config dib7070_agc_config = { - .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, - - /* - * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, - * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 - */ - .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | - (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - .inv_gain = 600, - .time_stabiliz = 10, - .alpha_level = 0, - .thlock = 118, - .wbd_inv = 0, - .wbd_ref = 3530, - .wbd_sel = 1, - .wbd_alpha = 5, - .agc1_max = 65535, - .agc1_min = 0, - .agc2_max = 65535, - .agc2_min = 0, - .agc1_pt1 = 0, - .agc1_pt2 = 40, - .agc1_pt3 = 183, - .agc1_slope1 = 206, - .agc1_slope2 = 255, - .agc2_pt1 = 72, - .agc2_pt2 = 152, - .agc2_slope1 = 88, - .agc2_slope2 = 90, - .alpha_mant = 17, - .alpha_exp = 27, - .beta_mant = 23, - .beta_exp = 51, - .perform_agc_softsplit = 0, -}; - -static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { - .internal = 60000, - .sampling = 15000, - .pll_prediv = 1, - .pll_ratio = 20, - .pll_range = 3, - .pll_reset = 1, - .pll_bypass = 0, - .enable_refdiv = 0, - .bypclk_div = 0, - .IO_CLK_en_core = 1, - .ADClkSrc = 1, - .modulo = 2, - /* refsel, sel, freq_15k */ - .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), - .ifreq = (0 << 25) | 0, - .timf = 20452225, - .xtal_hz = 12000000, -}; - -static struct dib7000p_config cxusb_dualdig4_rev2_config = { - .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 1, - .agc = &dib7070_agc_config, - .bw = &dib7070_bw_config_12_mhz, - .tuner_is_baseband = 1, - .spur_protect = 1, - - .gpio_dir = 0xfcef, - .gpio_val = 0x0110, - - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .hostbus_diversity = 1, -}; - -static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (usb_set_interface(adap->dev->udev, 0, 1) < 0) - err("set interface failed"); - - cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - - cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); - - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &cxusb_dualdig4_rev2_config); - - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, - &cxusb_dualdig4_rev2_config); - if (adap->fe == NULL) - return -EIO; - - return 0; -} - -static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) -{ - return dib7000p_set_gpio(fe, 8, 0, !onoff); -} - -static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) -{ - return 0; -} - -static struct dib0070_config dib7070p_dib0070_config = { - .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, - .reset = dib7070_tuner_reset, - .sleep = dib7070_tuner_sleep, - .clock_khz = 12000, -}; - -struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, - struct dvb_frontend_parameters *); -}; - -static int dib7070_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dib0700_adapter_state *state = adap->priv; - - u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); - switch (band) { - case BAND_VHF: offset = 950; break; - default: - case BAND_UHF: offset = 550; break; - } - - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - - return state->set_param_save(fe, fep); -} - -static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = - dib7000p_get_i2c_master(adap->fe, - DIBX000_I2C_INTERFACE_TUNER, 1); - - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, - &dib7070p_dib0070_config) == NULL) - return -ENODEV; - - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override; - return 0; -} - static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev, 0, 1) < 0) @@ -1094,54 +751,6 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } -static struct lgs8gl5_config lgs8gl5_cfg = { - .demod_address = 0x19, -}; - -static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_usb_device *d = adap->dev; - int n; - - /* Select required USB configuration */ - if (usb_set_interface(d->udev, 0, 0) < 0) - err("set interface failed"); - - /* Unblock all USB pipes */ - usb_clear_halt(d->udev, - usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint)); - - /* Drain USB pipes to avoid hang after reboot */ - for (n = 0; n < 5; n++) { - cxusb_d680_dmb_drain_message(d); - cxusb_d680_dmb_drain_video(d); - msleep(200); - } - - /* Reset the tuner */ - if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { - err("clear tuner gpio failed"); - return -EIO; - } - msleep(100); - if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { - err("set tuner gpio failed"); - return -EIO; - } - msleep(100); - - /* Attach frontend */ - adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap); - if (adap->fe == NULL) - return -EIO; - - return 0; -} - /* * DViCO has shipped two devices with the same USB ID, but only one of them * needs a firmware download. Check the device class details to see if they @@ -1217,11 +826,9 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; -static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; static struct dvb_usb_device_properties cxusb_aver_a868r_properties; -static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1245,11 +852,6 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, - &cxusb_bluebird_dualdig4_rev2_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, - THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -1274,8 +876,6 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, - { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -1721,104 +1321,6 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { } }; -static -struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, - .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, - .size_of_priv = sizeof(struct dib0700_adapter_state), - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - }, - }, - - .power_ctrl = cxusb_bluebird_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = dvico_mce_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), - .rc_query = cxusb_rc_query, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", - { NULL }, - { &cxusb_table[17], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, - .frontend_attach = cxusb_d680_dmb_frontend_attach, - .tuner_attach = cxusb_d680_dmb_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_d680_dmb_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = d680_dmb_rc_keys, - .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys), - .rc_query = cxusb_d680_dmb_rc_query, - - .num_device_descs = 1, - .devices = { - { - "Conexant DMB-TH Stick", - { NULL }, - { &cxusb_table[18], NULL }, - }, - } -}; - static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700.h b/trunk/drivers/media/dvb/dvb-usb/dib0700.h index 739193943c17..66d4dc6ba46f 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700.h +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700.h @@ -31,8 +31,6 @@ extern int dvb_usb_dib0700_debug; // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) #define REQUEST_SET_RC 0x11 -#define REQUEST_NEW_I2C_READ 0x12 -#define REQUEST_NEW_I2C_WRITE 0x13 #define REQUEST_GET_VERSION 0x15 struct dib0700_state { @@ -41,8 +39,6 @@ struct dib0700_state { u8 rc_toggle; u8 rc_counter; u8 is_dib7000pc; - u8 fw_use_new_i2c_api; - u8 disable_streaming_master_mode; }; extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c index dd53cee3896d..595a04696c87 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -82,98 +82,9 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_ } /* - * I2C master xfer function (supported in 1.20 firmware) + * I2C master xfer function */ -static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, - int num) -{ - /* The new i2c firmware messages are more reliable and in particular - properly support i2c read calls not preceded by a write */ - - struct dvb_usb_device *d = i2c_get_adapdata(adap); - uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */ - uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */ - uint8_t en_start = 0; - uint8_t en_stop = 0; - uint8_t buf[255]; /* TBV: malloc ? */ - int result, i; - - /* Ensure nobody else hits the i2c bus while we're sending our - sequence of messages, (such as the remote control thread) */ - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - if (i == 0) { - /* First message in the transaction */ - en_start = 1; - } else if (!(msg[i].flags & I2C_M_NOSTART)) { - /* Device supports repeated-start */ - en_start = 1; - } else { - /* Not the first packet and device doesn't support - repeated start */ - en_start = 0; - } - if (i == (num - 1)) { - /* Last message in the transaction */ - en_stop = 1; - } - - if (msg[i].flags & I2C_M_RD) { - /* Read request */ - u16 index, value; - uint8_t i2c_dest; - - i2c_dest = (msg[i].addr << 1); - value = ((en_start << 7) | (en_stop << 6) | - (msg[i].len & 0x3F)) << 8 | i2c_dest; - /* I2C ctrl + FE bus; */ - index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30); - - result = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev, 0), - REQUEST_NEW_I2C_READ, - USB_TYPE_VENDOR | USB_DIR_IN, - value, index, msg[i].buf, - msg[i].len, - USB_CTRL_GET_TIMEOUT); - if (result < 0) { - err("i2c read error (status = %d)\n", result); - break; - } - } else { - /* Write request */ - buf[0] = REQUEST_NEW_I2C_WRITE; - buf[1] = (msg[i].addr << 1); - buf[2] = (en_start << 7) | (en_stop << 6) | - (msg[i].len & 0x3F); - /* I2C ctrl + FE bus; */ - buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30); - /* The Actual i2c payload */ - memcpy(&buf[4], msg[i].buf, msg[i].len); - - result = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev, 0), - REQUEST_NEW_I2C_WRITE, - USB_TYPE_VENDOR | USB_DIR_OUT, - 0, 0, buf, msg[i].len + 4, - USB_CTRL_GET_TIMEOUT); - if (result < 0) { - err("i2c write error (status = %d)\n", result); - break; - } - } - } - mutex_unlock(&d->i2c_mutex); - return i; -} - -/* - * I2C master xfer function (pre-1.20 firmware) - */ -static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, - struct i2c_msg *msg, int num) +static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i,len; @@ -213,21 +124,6 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, return i; } -static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - struct dib0700_state *st = d->priv; - - if (st->fw_use_new_i2c_api == 1) { - /* User running at least fw 1.20 */ - return dib0700_i2c_xfer_new(adap, msg, num); - } else { - /* Use legacy calls */ - return dib0700_i2c_xfer_legacy(adap, msg, num); - } -} - static u32 dib0700_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; @@ -350,12 +246,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) b[0] = REQUEST_ENABLE_VIDEO; b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ - - if (st->disable_streaming_master_mode == 1) - b[2] = 0x00; - else - b[2] = (0x01 << 4); /* Master mode */ - + b[2] = (0x01 << 4); /* Master mode */ b[3] = 0x00; deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c index 0cfccc24b190..6c0e5c5f4362 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -14,8 +14,6 @@ #include "mt2060.h" #include "mt2266.h" #include "tuner-xc2028.h" -#include "xc5000.h" -#include "s5h1411.h" #include "dib0070.h" static int force_lna_activation; @@ -368,8 +366,7 @@ static struct dib7000p_config stk7700ph_dib7700_xc3028_config = { .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, }; -static int stk7700ph_xc3028_callback(void *ptr, int component, - int command, int arg) +static int stk7700ph_xc3028_callback(void *ptr, int command, int arg) { struct dvb_usb_adapter *adap = ptr; @@ -397,6 +394,7 @@ static struct xc2028_ctrl stk7700ph_xc3028_ctrl = { static struct xc2028_config stk7700ph_xc3028_config = { .i2c_addr = 0x61, + .callback = stk7700ph_xc3028_callback, .ctrl = &stk7700ph_xc3028_ctrl, }; @@ -437,9 +435,7 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) DIBX000_I2C_INTERFACE_TUNER, 1); stk7700ph_xc3028_config.i2c_adap = tun_i2c; - - /* FIXME: generalize & move to common area */ - adap->fe->callback = stk7700ph_xc3028_callback; + stk7700ph_xc3028_config.video_dev = adap; return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) == NULL ? -ENODEV : 0; @@ -681,43 +677,6 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = { { 0x01, 0x7d, KEY_VOLUMEDOWN }, { 0x02, 0x42, KEY_CHANNELUP }, { 0x00, 0x7d, KEY_CHANNELDOWN }, - - /* Key codes for Nova-TD "credit card" remote control. */ - { 0x1d, 0x00, KEY_0 }, - { 0x1d, 0x01, KEY_1 }, - { 0x1d, 0x02, KEY_2 }, - { 0x1d, 0x03, KEY_3 }, - { 0x1d, 0x04, KEY_4 }, - { 0x1d, 0x05, KEY_5 }, - { 0x1d, 0x06, KEY_6 }, - { 0x1d, 0x07, KEY_7 }, - { 0x1d, 0x08, KEY_8 }, - { 0x1d, 0x09, KEY_9 }, - { 0x1d, 0x0a, KEY_TEXT }, - { 0x1d, 0x0d, KEY_MENU }, - { 0x1d, 0x0f, KEY_MUTE }, - { 0x1d, 0x10, KEY_VOLUMEUP }, - { 0x1d, 0x11, KEY_VOLUMEDOWN }, - { 0x1d, 0x12, KEY_CHANNEL }, - { 0x1d, 0x14, KEY_UP }, - { 0x1d, 0x15, KEY_DOWN }, - { 0x1d, 0x16, KEY_LEFT }, - { 0x1d, 0x17, KEY_RIGHT }, - { 0x1d, 0x1c, KEY_TV }, - { 0x1d, 0x1e, KEY_NEXT }, - { 0x1d, 0x1f, KEY_BACK }, - { 0x1d, 0x20, KEY_CHANNELUP }, - { 0x1d, 0x21, KEY_CHANNELDOWN }, - { 0x1d, 0x24, KEY_LAST }, - { 0x1d, 0x25, KEY_OK }, - { 0x1d, 0x30, KEY_PAUSE }, - { 0x1d, 0x32, KEY_REWIND }, - { 0x1d, 0x34, KEY_FASTFORWARD }, - { 0x1d, 0x35, KEY_PLAY }, - { 0x1d, 0x36, KEY_STOP }, - { 0x1d, 0x37, KEY_RECORD }, - { 0x1d, 0x3b, KEY_GOTO }, - { 0x1d, 0x3d, KEY_POWER }, }; /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ @@ -1119,97 +1078,6 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) return adap->fe == NULL ? -ENODEV : 0; } -/* S5H1411 */ -static struct s5h1411_config pinnacle_801e_config = { - .output_mode = S5H1411_PARALLEL_OUTPUT, - .gpio = S5H1411_GPIO_OFF, - .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, - .qam_if = S5H1411_IF_44000, - .vsb_if = S5H1411_IF_44000, - .inversion = S5H1411_INVERSION_OFF, - .status_mode = S5H1411_DEMODLOCKING -}; - -/* Pinnacle PCTV HD Pro 801e GPIOs map: - GPIO0 - currently unknown - GPIO1 - xc5000 tuner reset - GPIO2 - CX25843 sleep - GPIO3 - currently unknown - GPIO4 - currently unknown - GPIO6 - currently unknown - GPIO7 - currently unknown - GPIO9 - currently unknown - GPIO10 - CX25843 reset - */ -static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dib0700_state *st = adap->dev->priv; - - /* Make use of the new i2c functions from FW 1.20 */ - st->fw_use_new_i2c_api = 1; - - /* The s5h1411 requires the dib0700 to not be in master mode */ - st->disable_streaming_master_mode = 1; - - /* All msleep values taken from Windows USB trace */ - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0); - dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0); - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(400); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(60); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(30); - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0); - msleep(30); - - /* Put the CX25843 to sleep for now since we're in digital mode */ - dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1); - - /* GPIOs are initialized, do the attach */ - adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config, - &adap->dev->i2c_adap); - return adap->fe == NULL ? -ENODEV : 0; -} - -static int dib0700_xc5000_tuner_callback(void *priv, int component, - int command, int arg) -{ - struct dvb_usb_adapter *adap = priv; - - if (command == XC5000_TUNER_RESET) { - /* Reset the tuner */ - dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0); - msleep(330); /* from Windows USB trace */ - dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1); - msleep(330); /* from Windows USB trace */ - } else { - err("xc5000: unknown tuner callback command: %d\n", command); - return -EINVAL; - } - - return 0; -} - -static struct xc5000_config s5h1411_xc5000_tunerconfig = { - .i2c_address = 0x64, - .if_khz = 5380, -}; - -static int xc5000_tuner_attach(struct dvb_usb_adapter *adap) -{ - /* FIXME: generalize & move to common area */ - adap->fe->callback = dib0700_xc5000_tuner_callback; - - return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap, - &s5h1411_xc5000_tunerconfig) - == NULL ? -ENODEV : 0; -} - /* DVB-USB and USB stuff follows */ struct usb_device_id dib0700_usb_id_table[] = { /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, @@ -1251,11 +1119,6 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, /* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) }, - { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) }, - { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) }, - { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) }, -/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1263,7 +1126,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); #define DIB0700_DEFAULT_DEVICE_PROPERTIES \ .caps = DVB_USB_IS_AN_I2C_ADAPTER, \ .usb_ctrl = DEVICE_SPECIFIC, \ - .firmware = "dvb-usb-dib0700-1.20.fw", \ + .firmware = "dvb-usb-dib0700-1.10.fw", \ .download_firmware = dib0700_download_firmware, \ .no_reconnect = 1, \ .size_of_priv = sizeof(struct dib0700_state), \ @@ -1430,12 +1293,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[31], NULL }, { NULL }, } - }, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query + } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -1550,7 +1408,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 5, + .num_device_descs = 3, .devices = { { "Terratec Cinergy HT USB XE", { &dib0700_usb_id_table[27], NULL }, @@ -1564,47 +1422,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[32], NULL }, { NULL }, }, - { "Gigabyte U8000-RH", - { &dib0700_usb_id_table[37], NULL }, - { NULL }, - }, - { "YUAN High-Tech STK7700PH", - { &dib0700_usb_id_table[38], NULL }, - { NULL }, - }, - { "Asus My Cinema-U3000Hybrid", - { &dib0700_usb_id_table[39], NULL }, - { NULL }, - }, - }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - .num_adapters = 1, - .adapter = { - { - .frontend_attach = s5h1411_frontend_attach, - .tuner_attach = xc5000_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - - .size_of_priv = sizeof(struct - dib0700_adapter_state), - }, - }, - - .num_device_descs = 2, - .devices = { - { "Pinnacle PCTV HD Pro USB Stick", - { &dib0700_usb_id_table[40], NULL }, - { NULL }, - }, - { "Pinnacle PCTV HD USB Stick", - { &dib0700_usb_id_table[41], NULL }, - { NULL }, - }, }, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dib0700_rc_keys, diff --git a/trunk/drivers/media/dvb/dvb-usb/dtv5100.c b/trunk/drivers/media/dvb/dvb-usb/dtv5100.c deleted file mode 100644 index 078ce92ca436..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/dtv5100.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T - * - * Copyright (C) 2008 Antoine Jacquet - * http://royale.zerezo.com/dtv5100/ - * - * Inspired by gl861.c and au6610.c drivers - * - * 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 "dtv5100.h" -#include "zl10353.h" -#include "qt1010.h" - -/* debug */ -static int dvb_usb_dtv5100_debug; -module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u8 request; - u8 type; - u16 value; - u16 index; - - switch (wlen) { - case 1: - /* write { reg }, read { value } */ - request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : - DTV5100_TUNER_READ); - type = USB_TYPE_VENDOR | USB_DIR_IN; - value = 0; - break; - case 2: - /* write { reg, value } */ - request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE : - DTV5100_TUNER_WRITE); - type = USB_TYPE_VENDOR | USB_DIR_OUT; - value = wbuf[1]; - break; - default: - warn("wlen = %x, aborting.", wlen); - return -EINVAL; - } - index = (addr << 8) + wbuf[0]; - - msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request, - type, value, index, rbuf, rlen, - DTV5100_USB_TIMEOUT); -} - -/* I2C */ -static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, - msg[i+1].len) < 0) - break; - i++; - } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, NULL, 0) < 0) - break; - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static u32 dtv5100_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm dtv5100_i2c_algo = { - .master_xfer = dtv5100_i2c_xfer, - .functionality = dtv5100_i2c_func, -}; - -/* Callbacks for DVB USB */ -static struct zl10353_config dtv5100_zl10353_config = { - .demod_address = DTV5100_DEMOD_ADDR, - .no_tuner = 1, - .parallel_ts = 1, -}; - -static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap) -{ - adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe == NULL) - return -EIO; - - /* disable i2c gate, or it won't work... is this safe? */ - adap->fe->ops.i2c_gate_ctrl = NULL; - - return 0; -} - -static struct qt1010_config dtv5100_qt1010_config = { - .i2c_address = DTV5100_TUNER_ADDR -}; - -static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap) -{ - return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, - &dtv5100_qt1010_config) == NULL ? -ENODEV : 0; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties dtv5100_properties; - -static int dtv5100_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int i, ret; - struct usb_device *udev = interface_to_usbdev(intf); - - /* initialize non qt1010/zl10353 part? */ - for (i = 0; dtv5100_init[i].request; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - dtv5100_init[i].request, - USB_TYPE_VENDOR | USB_DIR_OUT, - dtv5100_init[i].value, - dtv5100_init[i].index, NULL, 0, - DTV5100_USB_TIMEOUT); - if (ret) - return ret; - } - - ret = dvb_usb_device_init(intf, &dtv5100_properties, - THIS_MODULE, NULL, adapter_nr); - if (ret) - return ret; - - return 0; -} - -static struct usb_device_id dtv5100_table[] = { - { USB_DEVICE(0x06be, 0xa232) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, dtv5100_table); - -static struct dvb_usb_device_properties dtv5100_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - - .size_of_priv = 0, - - .num_adapters = 1, - .adapter = {{ - .frontend_attach = dtv5100_frontend_attach, - .tuner_attach = dtv5100_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } }, - - .i2c_algo = &dtv5100_i2c_algo, - - .num_device_descs = 1, - .devices = { - { - .name = "AME DTV-5100 USB2.0 DVB-T", - .cold_ids = { NULL }, - .warm_ids = { &dtv5100_table[0], NULL }, - }, - } -}; - -static struct usb_driver dtv5100_driver = { - .name = "dvb_usb_dtv5100", - .probe = dtv5100_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dtv5100_table, -}; - -/* module stuff */ -static int __init dtv5100_module_init(void) -{ - int ret; - - ret = usb_register(&dtv5100_driver); - if (ret) - err("usb_register failed. Error number %d", ret); - - return ret; -} - -static void __exit dtv5100_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dtv5100_driver); -} - -module_init(dtv5100_module_init); -module_exit(dtv5100_module_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/dvb-usb/dtv5100.h b/trunk/drivers/media/dvb/dvb-usb/dtv5100.h deleted file mode 100644 index 93e96e04a82a..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/dtv5100.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T - * - * Copyright (C) 2008 Antoine Jacquet - * http://royale.zerezo.com/dtv5100/ - * - * 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 - */ - -#ifndef _DVB_USB_DTV5100_H_ -#define _DVB_USB_DTV5100_H_ - -#define DVB_USB_LOG_PREFIX "dtv5100" -#include "dvb-usb.h" - -#define DTV5100_USB_TIMEOUT 500 - -#define DTV5100_DEMOD_ADDR 0x00 -#define DTV5100_DEMOD_WRITE 0xc0 -#define DTV5100_DEMOD_READ 0xc1 - -#define DTV5100_TUNER_ADDR 0xc4 -#define DTV5100_TUNER_WRITE 0xc7 -#define DTV5100_TUNER_READ 0xc8 - -#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/" -#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T" - -static struct { - u8 request; - u8 value; - u16 index; -} dtv5100_init[] = { - { 0x000000c5, 0x00000000, 0x00000001 }, - { 0x000000c5, 0x00000001, 0x00000001 }, - { } /* Terminating entry */ -}; - -#endif diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 7380b94b3b36..03dfb9f2fe30 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -22,7 +22,6 @@ #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO_UNK 0x145f -#define USB_VID_CONEXANT 0x0572 #define USB_VID_CYPRESS 0x04b4 #define USB_VID_DIBCOM 0x10b8 #define USB_VID_DPOSH 0x1498 @@ -34,19 +33,16 @@ #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 #define USB_VID_KWORLD 0xeb2a -#define USB_VID_KWORLD_2 0x1b80 #define USB_VID_KYE 0x0458 #define USB_VID_LEADTEK 0x0413 #define USB_VID_LITEON 0x04ca #define USB_VID_MEDION 0x1660 #define USB_VID_MIGLIA 0x18f3 #define USB_VID_MSI 0x0db0 -#define USB_VID_MSI_2 0x1462 #define USB_VID_OPERA1 0x695c #define USB_VID_PINNACLE 0x2304 #define USB_VID_TECHNOTREND 0x0b48 #define USB_VID_TERRATEC 0x0ccd -#define USB_VID_TELESTAR 0x10b9 #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 @@ -54,18 +50,15 @@ #define USB_VID_WIDEVIEW 0x14aa #define USB_VID_GIGABYTE 0x1044 #define USB_VID_YUAN 0x1164 -#define USB_VID_XTENSIONS 0x1ae7 + /* Product IDs */ #define USB_PID_ADSTECH_USB2_COLD 0xa333 #define USB_PID_ADSTECH_USB2_WARM 0xa334 #define USB_PID_AFATECH_AF9005 0x9020 -#define USB_PID_AFATECH_AF9015_9015 0x9015 -#define USB_PID_AFATECH_AF9015_9016 0x9016 #define USB_VID_ALINK_DTU 0xf170 #define USB_PID_ANSONIC_DVBT_USB 0x6000 #define USB_PID_ANYSEE 0x861f -#define USB_PID_AZUREWAVE_AD_TU700 0x3237 #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 @@ -76,7 +69,6 @@ #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d #define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 #define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 -#define USB_PID_CONEXANT_D680_DMB 0x86d6 #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 @@ -95,12 +87,9 @@ #define USB_PID_UNIWILL_STK7700P 0x6003 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 -#define USB_PID_KWORLD_399U 0xe399 -#define USB_PID_KWORLD_PC160_2T 0xc160 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_WARM 0x17df #define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 -#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069 #define USB_PID_TWINHAN_VP7041_COLD 0x3201 #define USB_PID_TWINHAN_VP7041_WARM 0x3202 #define USB_PID_TWINHAN_VP7020_COLD 0x3203 @@ -109,7 +98,6 @@ #define USB_PID_TWINHAN_VP7045_WARM 0x3206 #define USB_PID_TWINHAN_VP7021_COLD 0x3207 #define USB_PID_TWINHAN_VP7021_WARM 0x3208 -#define USB_PID_TINYTWIN 0x3226 #define USB_PID_DNTV_TINYUSB2_COLD 0x3223 #define USB_PID_DNTV_TINYUSB2_WARM 0x3224 #define USB_PID_ULTIMA_TVBOX_COLD 0x8105 @@ -156,9 +144,6 @@ #define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039 #define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039 #define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039 -#define USB_PID_AVERMEDIA_VOLAR_X 0xa815 -#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150 -#define USB_PID_AVERMEDIA_A309 0xa309 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 @@ -168,11 +153,8 @@ #define USB_PID_PINNACLE_PCTV2000E 0x022c #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 #define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229 -#define USB_PID_PINNACLE_PCTV71E 0x022b #define USB_PID_PINNACLE_PCTV72E 0x0236 #define USB_PID_PINNACLE_PCTV73E 0x0237 -#define USB_PID_PINNACLE_PCTV801E 0x023a -#define USB_PID_PINNACLE_PCTV801E_SE 0x023b #define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_400E 0x020f #define USB_PID_PCTV_450E 0x0222 @@ -189,7 +171,6 @@ #define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58 #define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59 #define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78 -#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2 0xdb98 #define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70 #define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 @@ -209,7 +190,6 @@ #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 -#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 #define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 #define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201 #define USB_PID_GENPIX_8PSK_REV_2 0x0202 @@ -217,21 +197,14 @@ #define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204 #define USB_PID_SIGMATEK_DVB_110 0x6610 #define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 -#define USB_PID_MSI_DIGIVOX_DUO 0x8801 #define USB_PID_OPERA1_COLD 0x2830 #define USB_PID_OPERA1_WARM 0x3829 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 #define USB_PID_GIGABYTE_U7000 0x7001 -#define USB_PID_GIGABYTE_U8000 0x7002 #define USB_PID_ASUS_U3000 0x171f -#define USB_PID_ASUS_U3000H 0x1736 #define USB_PID_ASUS_U3100 0x173f #define USB_PID_YUAN_EC372S 0x1edc -#define USB_PID_YUAN_STK7700PH 0x1f08 #define USB_PID_DW2102 0x2102 -#define USB_PID_XTENSIONS_XD_380 0x0381 -#define USB_PID_TELESTAR_STARSTICK_2 0x8000 -#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 #endif diff --git a/trunk/drivers/media/dvb/dvb-usb/dw2102.c b/trunk/drivers/media/dvb/dvb-usb/dw2102.c index ca53df61caa8..a4d898b44e55 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dw2102.c +++ b/trunk/drivers/media/dvb/dvb-usb/dw2102.c @@ -1,5 +1,4 @@ -/* DVB USB framework compliant Linux driver for the -* DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card +/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card * * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) * @@ -11,74 +10,62 @@ */ #include #include "dw2102.h" -#include "si21xx.h" #include "stv0299.h" #include "z0194a.h" -#include "stv0288.h" -#include "stb6000.h" -#include "eds1547.h" -#include "cx24116.h" #ifndef USB_PID_DW2102 #define USB_PID_DW2102 0x2102 #endif -#ifndef USB_PID_DW2104 -#define USB_PID_DW2104 0x2104 -#endif - -#define DW210X_READ_MSG 0 -#define DW210X_WRITE_MSG 1 +#define DW2102_READ_MSG 0 +#define DW2102_WRITE_MSG 1 #define REG_1F_SYMBOLRATE_BYTE0 0x1f #define REG_20_SYMBOLRATE_BYTE1 0x20 #define REG_21_SYMBOLRATE_BYTE2 0x21 -/* on my own*/ + #define DW2102_VOLTAGE_CTRL (0x1800) #define DW2102_RC_QUERY (0x1a00) -struct dw210x_state { +struct dw2102_state { u32 last_key_pressed; }; -struct dw210x_rc_keys { +struct dw2102_rc_keys { u32 keycode; u32 event; }; -/* debug */ -static int dvb_usb_dw2102_debug; -module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); - DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, - u16 index, u8 * data, u16 len, int flags) +static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, + u8 *data, u16 len, int flags) { int ret; u8 u8buf[len]; - unsigned int pipe = (flags == DW210X_READ_MSG) ? - usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); - u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; + unsigned int pipe = (flags == DW2102_READ_MSG) ? + usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); + u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; - if (flags == DW210X_WRITE_MSG) + if (flags == DW2102_WRITE_MSG) memcpy(u8buf, data, len); - ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, - value, index , u8buf, len, 2000); + ret = usb_control_msg(dev, pipe, request, + request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000); - if (flags == DW210X_READ_MSG) + if (flags == DW2102_READ_MSG) memcpy(data, u8buf, len); return ret; } /* I2C */ + static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i = 0, ret = 0; u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; + u8 request; u16 value; if (!d) @@ -89,12 +76,14 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); switch (num) { case 2: /* read stv0299 register */ + request = 0xb5; value = msg[0].buf[0];/* register */ for (i = 0; i < msg[1].len; i++) { value = value + i; - ret = dw210x_op_rw(d->udev, 0xb5, value, 0, - buf6, 2, DW210X_READ_MSG); + ret = dw2102_op_rw(d->udev, 0xb5, + value, buf6, 2, DW2102_READ_MSG); msg[1].buf[i] = buf6[0]; + } break; case 1: @@ -104,8 +93,8 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); buf6[0] = 0x2a; buf6[1] = msg[0].buf[0]; buf6[2] = msg[0].buf[1]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 3, DW210X_WRITE_MSG); + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 3, DW2102_WRITE_MSG); break; case 0x60: if (msg[0].flags == 0) { @@ -117,26 +106,26 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); buf6[4] = msg[0].buf[1]; buf6[5] = msg[0].buf[2]; buf6[6] = msg[0].buf[3]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 7, DW210X_WRITE_MSG); + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 7, DW2102_WRITE_MSG); } else { - /* read from tuner */ - ret = dw210x_op_rw(d->udev, 0xb5, 0, 0, - buf6, 1, DW210X_READ_MSG); + /* write to tuner pll */ + ret = dw2102_op_rw(d->udev, 0xb5, + 0, buf6, 1, DW2102_READ_MSG); msg[0].buf[0] = buf6[0]; } break; case (DW2102_RC_QUERY): - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); + ret = dw2102_op_rw(d->udev, 0xb8, + 0, buf6, 2, DW2102_READ_MSG); msg[0].buf[0] = buf6[0]; msg[0].buf[1] = buf6[1]; break; case (DW2102_VOLTAGE_CTRL): buf6[0] = 0x30; buf6[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 2, DW210X_WRITE_MSG); + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 2, DW2102_WRITE_MSG); break; } @@ -147,265 +136,17 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); return num; } -static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, - struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0; - u8 buf6[] = {0, 0, 0, 0, 0, 0, 0}; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: - /* read si2109 register by number */ - buf6[0] = 0xd0; - buf6[1] = msg[0].len; - buf6[2] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - buf6, msg[0].len + 2, DW210X_WRITE_MSG); - /* read si2109 register */ - ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0, - buf6, msg[1].len + 2, DW210X_READ_MSG); - memcpy(msg[1].buf, buf6 + 2, msg[1].len); - - break; - case 1: - switch (msg[0].addr) { - case 0x68: - /* write to si2109 register */ - buf6[0] = 0xd0; - buf6[1] = msg[0].len; - memcpy(buf6 + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, - msg[0].len + 2, DW210X_WRITE_MSG); - break; - case(DW2102_RC_QUERY): - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); - msg[0].buf[0] = buf6[0]; - msg[0].buf[1] = buf6[1]; - break; - case(DW2102_VOLTAGE_CTRL): - buf6[0] = 0x30; - buf6[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 2, DW210X_WRITE_MSG); - break; - } - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} -static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: { - /* read */ - /* first write first register number */ - u8 ibuf [msg[1].len + 2], obuf[3]; - obuf[0] = 0xd0; - obuf[1] = msg[0].len; - obuf[2] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - /* second read registers */ - ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, - ibuf, msg[1].len + 2, DW210X_READ_MSG); - memcpy(msg[1].buf, ibuf + 2, msg[1].len); - - break; - } - case 1: - switch (msg[0].addr) { - case 0x68: { - /* write to register */ - u8 obuf[msg[0].len + 2]; - obuf[0] = 0xd0; - obuf[1] = msg[0].len; - memcpy(obuf + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - break; - } - case 0x61: { - /* write to tuner */ - u8 obuf[msg[0].len + 2]; - obuf[0] = 0xc2; - obuf[1] = msg[0].len; - memcpy(obuf + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - break; - } - case(DW2102_RC_QUERY): { - u8 ibuf[2]; - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[0].buf, ibuf , 2); - break; - } - case(DW2102_VOLTAGE_CTRL): { - u8 obuf[2]; - obuf[0] = 0x30; - obuf[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - obuf, 2, DW210X_WRITE_MSG); - break; - } - } - - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} - -static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0; - int len, i; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: { - /* read */ - /* first write first register number */ - u8 ibuf [msg[1].len + 2], obuf[3]; - obuf[0] = 0xaa; - obuf[1] = msg[0].len; - obuf[2] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - /* second read registers */ - ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0, - ibuf, msg[1].len + 2, DW210X_READ_MSG); - memcpy(msg[1].buf, ibuf + 2, msg[1].len); - - break; - } - case 1: - switch (msg[0].addr) { - case 0x55: { - if (msg[0].buf[0] == 0xf7) { - /* firmware */ - /* Write in small blocks */ - u8 obuf[19]; - obuf[0] = 0xaa; - obuf[1] = 0x11; - obuf[2] = 0xf7; - len = msg[0].len - 1; - i = 1; - do { - memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len)); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG); - i += 16; - len -= 16; - } while (len > 0); - } else { - /* write to register */ - u8 obuf[msg[0].len + 2]; - obuf[0] = 0xaa; - obuf[1] = msg[0].len; - memcpy(obuf + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - } - break; - } - case(DW2102_RC_QUERY): { - u8 ibuf[2]; - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[0].buf, ibuf , 2); - break; - } - case(DW2102_VOLTAGE_CTRL): { - u8 obuf[2]; - obuf[0] = 0x30; - obuf[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - obuf, 2, DW210X_WRITE_MSG); - break; - } - } - - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} - -static u32 dw210x_i2c_func(struct i2c_adapter *adapter) +static u32 dw2102_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; } static struct i2c_algorithm dw2102_i2c_algo = { .master_xfer = dw2102_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static struct i2c_algorithm dw2102_serit_i2c_algo = { - .master_xfer = dw2102_serit_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static struct i2c_algorithm dw2102_earda_i2c_algo = { - .master_xfer = dw2102_earda_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static struct i2c_algorithm dw2104_i2c_algo = { - .master_xfer = dw2104_i2c_transfer, - .functionality = dw210x_i2c_func, + .functionality = dw2102_i2c_func, }; -static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -{ - int i; - u8 ibuf[] = {0, 0}; - u8 eeprom[256], eepromline[16]; - - for (i = 0; i < 256; i++) { - if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { - err("read eeprom failed."); - return -1; - } else { - eepromline[i%16] = ibuf[0]; - eeprom[i] = ibuf[0]; - } - if ((i % 16) == 15) { - deb_xfer("%02x: ", i - 15); - debug_dump(eepromline, 16, deb_xfer); - } - } - memcpy(mac, eeprom + 8, 6); - return 0; -}; - -static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { static u8 command_13v[1] = {0x00}; static u8 command_18v[1] = {0x01}; @@ -422,62 +163,14 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } -static struct cx24116_config dw2104_config = { - .demod_address = 0x55, - .mpg_clk_pos_pol = 0x01, -}; - -static struct si21xx_config serit_sp1511lhb_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - -}; - -static int dw2104_frontend_attach(struct dvb_usb_adapter *d) -{ - if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, - &d->dev->i2c_adap)) != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached cx24116!\n"); - return 0; - } - return -EIO; -} - -static struct dvb_usb_device_properties dw2102_properties; - static int dw2102_frontend_attach(struct dvb_usb_adapter *d) { - if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) { - /*dw2102_properties.adapter->tuner_attach = NULL;*/ - d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config, - &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached si21xx!\n"); - return 0; - } - } - if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { - /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ - d->fe = dvb_attach(stv0288_attach, &earda_config, - &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached stv0288!\n"); - return 0; - } - } - - if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { - /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ - d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, - &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached stv0299!\n"); - return 0; - } + d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, + &d->dev->i2c_adap); + if (d->fe != NULL) { + d->fe->ops.set_voltage = dw2102_set_voltage; + info("Attached stv0299!\n"); + return 0; } return -EIO; } @@ -489,15 +182,7 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(stb6000_attach, adap->fe, 0x61, - &adap->dev->i2c_adap); - - return 0; -} - -static struct dvb_usb_rc_key dw210x_rc_keys[] = { +static struct dvb_usb_rc_key dw2102_rc_keys[] = { { 0xf8, 0x0a, KEY_Q }, /*power*/ { 0xf8, 0x0c, KEY_M }, /*mute*/ { 0xf8, 0x11, KEY_1 }, @@ -536,7 +221,7 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = { static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct dw210x_state *st = d->priv; + struct dw2102_state *st = d->priv; u8 key[2]; struct i2c_msg msg[] = { {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, @@ -546,12 +231,12 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) *state = REMOTE_NO_KEY_PRESSED; if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { - for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { - if (dw210x_rc_keys[i].data == msg[0].buf[0]) { + for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) { + if (dw2102_rc_keys[i].data == msg[0].buf[0]) { *state = REMOTE_KEY_PRESSED; - *event = dw210x_rc_keys[i].event; + *event = dw2102_rc_keys[i].event; st->last_key_pressed = - dw210x_rc_keys[i].event; + dw2102_rc_keys[i].event; break; } st->last_key_pressed = 0; @@ -564,8 +249,6 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static struct usb_device_id dw2102_table[] = { {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, - {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, - {USB_DEVICE(0x9022, 0xd650)}, { } }; @@ -577,7 +260,7 @@ static int dw2102_load_firmware(struct usb_device *dev, u8 *b, *p; int ret = 0, i; u8 reset; - u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; + u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; const struct firmware *fw; const char *filename = "dvb-usb-dw2101.fw"; switch (dev->descriptor.idProduct) { @@ -590,23 +273,25 @@ static int dw2102_load_firmware(struct usb_device *dev, return ret; } break; - default: + case USB_PID_DW2102: fw = frmwr; break; } - info("start downloading DW210X firmware"); + info("start downloading DW2102 firmware"); p = kmalloc(fw->size, GFP_KERNEL); reset = 1; /*stop the CPU*/ - dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG); + dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG); + dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG); if (p != NULL) { memcpy(p, fw->data, fw->size); for (i = 0; i < fw->size; i += 0x40) { b = (u8 *) p + i; - if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40, - DW210X_WRITE_MSG) != 0x40) { + if (dw2102_op_rw + (dev, 0xa0, i, b , 0x40, + DW2102_WRITE_MSG) != 0x40 + ) { err("error while transferring firmware"); ret = -EINVAL; break; @@ -614,66 +299,43 @@ static int dw2102_load_firmware(struct usb_device *dev, } /* restart the CPU */ reset = 0; - if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, - DW210X_WRITE_MSG) != 1) { + if (ret || dw2102_op_rw + (dev, 0xa0, 0x7f92, &reset, 1, + DW2102_WRITE_MSG) != 1) { err("could not restart the USB controller CPU."); ret = -EINVAL; } - if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, - DW210X_WRITE_MSG) != 1) { + if (ret || dw2102_op_rw + (dev, 0xa0, 0xe600, &reset, 1, + DW2102_WRITE_MSG) != 1) { err("could not restart the USB controller CPU."); ret = -EINVAL; } /* init registers */ switch (dev->descriptor.idProduct) { - case USB_PID_DW2104: - case 0xd650: - reset = 1; - dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, - DW210X_WRITE_MSG); - reset = 0; - dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, - DW210X_WRITE_MSG); - break; case USB_PID_DW2102: - dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, - DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, - DW210X_READ_MSG); - /* check STV0299 frontend */ - dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, - DW210X_READ_MSG); - if (reset16[0] == 0xa1) { - dw2102_properties.i2c_algo = &dw2102_i2c_algo; - dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach; - break; - } else { - /* check STV0288 frontend */ - reset16[0] = 0xd0; - reset16[1] = 1; - reset16[2] = 0; - dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, - DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, - DW210X_READ_MSG); - if (reset16[2] == 0x11) { - dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; - dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach; - break; - } - } + dw2102_op_rw + (dev, 0xbf, 0x0040, &reset, 0, + DW2102_WRITE_MSG); + dw2102_op_rw + (dev, 0xb9, 0x0000, &reset16[0], 2, + DW2102_READ_MSG); + break; case 0x2101: - dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, - DW210X_READ_MSG); - dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, - DW210X_READ_MSG); - dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, - DW210X_READ_MSG); - dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, - DW210X_READ_MSG); + dw2102_op_rw + (dev, 0xbc, 0x0030, &reset16[0], 2, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xba, 0x0000, &reset16[0], 7, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xba, 0x0000, &reset16[0], 7, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xb9, 0x0000, &reset16[0], 2, + DW2102_READ_MSG); break; } - msleep(100); kfree(p); } return ret; @@ -683,12 +345,12 @@ static struct dvb_usb_device_properties dw2102_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-dw2102.fw", - .size_of_priv = sizeof(struct dw210x_state), + .size_of_priv = sizeof(struct dw2102_state), .no_reconnect = 1, - .i2c_algo = &dw2102_serit_i2c_algo, - .rc_key_map = dw210x_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), + .i2c_algo = &dw2102_i2c_algo, + .rc_key_map = dw2102_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys), .rc_interval = 150, .rc_query = dw2102_rc_query, @@ -696,12 +358,11 @@ static struct dvb_usb_device_properties dw2102_properties = { /* parameter for the MPEG2-data transfer */ .num_adapters = 1, .download_firmware = dw2102_load_firmware, - .read_mac_address = dw210x_read_mac_address, - .adapter = { + .adapter = { { .frontend_attach = dw2102_frontend_attach, .streaming_ctrl = NULL, - .tuner_attach = NULL, + .tuner_attach = dw2102_tuner_attach, .stream = { .type = USB_BULK, .count = 8, @@ -727,64 +388,11 @@ static struct dvb_usb_device_properties dw2102_properties = { } }; -static struct dvb_usb_device_properties dw2104_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-dw2104.fw", - .size_of_priv = sizeof(struct dw210x_state), - .no_reconnect = 1, - - .i2c_algo = &dw2104_i2c_algo, - .rc_key_map = dw210x_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), - .rc_interval = 150, - .rc_query = dw2102_rc_query, - - .generic_bulk_ctrl_endpoint = 0x81, - /* parameter for the MPEG2-data transfer */ - .num_adapters = 1, - .download_firmware = dw2102_load_firmware, - .read_mac_address = dw210x_read_mac_address, - .adapter = { - { - .frontend_attach = dw2104_frontend_attach, - .streaming_ctrl = NULL, - /*.tuner_attach = dw2104_tuner_attach,*/ - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .num_device_descs = 2, - .devices = { - { "DVBWorld DW2104 USB2.0", - {&dw2102_table[2], NULL}, - {NULL}, - }, - { "TeVii S650 USB2.0", - {&dw2102_table[3], NULL}, - {NULL}, - }, - } -}; - static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (0 == dvb_usb_device_init(intf, &dw2102_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &dw2104_properties, - THIS_MODULE, NULL, adapter_nr)) { - return 0; - } - return -ENODEV; + return dvb_usb_device_init(intf, &dw2102_properties, + THIS_MODULE, NULL, adapter_nr); } static struct usb_driver dw2102_driver = { @@ -812,6 +420,6 @@ module_init(dw2102_module_init); module_exit(dw2102_module_exit); MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); -MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); +MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/dvb-usb/dw2102.h b/trunk/drivers/media/dvb/dvb-usb/dw2102.h index e3370734e95a..7a310f906837 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dw2102.h +++ b/trunk/drivers/media/dvb/dvb-usb/dw2102.h @@ -4,5 +4,6 @@ #define DVB_USB_LOG_PREFIX "dw2102" #include "dvb-usb.h" +extern int dvb_usb_dw2102_debug; #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) #endif diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig index 96b93e21a84b..7dbb4a223c99 100644 --- a/trunk/drivers/media/dvb/frontends/Kconfig +++ b/trunk/drivers/media/dvb/frontends/Kconfig @@ -43,20 +43,6 @@ config DVB_S5H1420 help A DVB-S tuner module. Say Y when you want to support this frontend. -config DVB_STV0288 - tristate "ST STV0288 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_STB6000 - tristate "ST STB6000 silicon tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S silicon tuner module. Say Y when you want to support this tuner. - config DVB_STV0299 tristate "ST STV0299 based" depends on DVB_CORE && I2C @@ -106,20 +92,6 @@ config DVB_TUA6100 help A DVB-S PLL chip. -config DVB_CX24116 - tristate "Conexant CX24116 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S/S2 tuner module. Say Y when you want to support this frontend. - -config DVB_SI21XX - tristate "Silicon Labs SI21XX based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - comment "DVB-T (terrestrial) frontends" depends on DVB_CORE @@ -413,23 +385,4 @@ config DVB_ISL6421 help An SEC control chip. -config DVB_LGS8GL5 - tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DMB-TH tuner module. Say Y when you want to support this frontend. - -comment "Tools to develop new frontends" - -config DVB_DUMMY_FE - tristate "Dummy frontend driver" - default n - -config DVB_AF9013 - tristate "Afatech AF9013 demodulator" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - Say Y when you want to support this frontend. endmenu diff --git a/trunk/drivers/media/dvb/frontends/Makefile b/trunk/drivers/media/dvb/frontends/Makefile index aba79f4a63a7..028da55611c0 100644 --- a/trunk/drivers/media/dvb/frontends/Makefile +++ b/trunk/drivers/media/dvb/frontends/Makefile @@ -48,10 +48,3 @@ obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o obj-$(CONFIG_DVB_AU8522) += au8522.o obj-$(CONFIG_DVB_TDA10048) += tda10048.o obj-$(CONFIG_DVB_S5H1411) += s5h1411.o -obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o -obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o -obj-$(CONFIG_DVB_AF9013) += af9013.o -obj-$(CONFIG_DVB_CX24116) += cx24116.o -obj-$(CONFIG_DVB_SI21XX) += si21xx.o -obj-$(CONFIG_DVB_STV0288) += stv0288.o -obj-$(CONFIG_DVB_STB6000) += stb6000.o diff --git a/trunk/drivers/media/dvb/frontends/af9013.c b/trunk/drivers/media/dvb/frontends/af9013.c deleted file mode 100644 index 21c1060cf10e..000000000000 --- a/trunk/drivers/media/dvb/frontends/af9013.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "af9013_priv.h" -#include "af9013.h" - -int af9013_debug; - -struct af9013_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - - struct af9013_config config; - - u16 signal_strength; - u32 ber; - u32 ucblocks; - u16 snr; - u32 frequency; - unsigned long next_statistics_check; -}; - -static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg, - u8 *val, u8 len) -{ - u8 buf[3+len]; - struct i2c_msg msg = { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(buf), - .buf = buf }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = mbox; - memcpy(&buf[3], val, len); - - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - warn("I2C write failed reg:%04x len:%d", reg, len); - return -EREMOTEIO; - } - return 0; -} - -static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) -{ - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7); - return af9013_write_regs(state, mbox, reg, val, len); -} - -static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) -{ - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7); - return af9013_write_regs(state, mbox, reg, val, len); -} - -/* write single register */ -static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val) -{ - return af9013_write_ofdm_regs(state, reg, &val, 1); -} - -/* read single register */ -static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val) -{ - u8 obuf[3] = { reg >> 8, reg & 0xff, 0 }; - u8 ibuf[1]; - struct i2c_msg msg[2] = { - { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(obuf), - .buf = obuf - }, { - .addr = state->config.demod_address, - .flags = I2C_M_RD, - .len = sizeof(ibuf), - .buf = ibuf - } - }; - - if (i2c_transfer(state->i2c, msg, 2) != 2) { - warn("I2C read failed reg:%04x", reg); - return -EREMOTEIO; - } - *val = ibuf[0]; - return 0; -} - -static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 val) -{ - int ret; - u8 tmp, mask; - - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; - - mask = regmask[len - 1] << pos; - tmp = (tmp & ~mask) | ((val << pos) & mask); - - return af9013_write_reg(state, reg, tmp); -} - -static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 *val) -{ - int ret; - u8 tmp; - - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; - *val = (tmp >> pos) & regmask[len - 1]; - return 0; -} - -static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) -{ - int ret; - u8 pos; - u16 addr; - deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval); - -/* GPIO0 & GPIO1 0xd735 - GPIO2 & GPIO3 0xd736 */ - - switch (gpio) { - case 0: - case 1: - addr = 0xd735; - break; - case 2: - case 3: - addr = 0xd736; - break; - - default: - err("invalid gpio:%d\n", gpio); - ret = -EINVAL; - goto error; - }; - - switch (gpio) { - case 0: - case 2: - pos = 0; - break; - case 1: - case 3: - default: - pos = 4; - break; - }; - - ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval); - -error: - return ret; -} - -static u32 af913_div(u32 a, u32 b, u32 x) -{ - u32 r = 0, c = 0, i; - deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x); - - if (a > b) { - c = a / b; - a = a - c * b; - } - - for (i = 0; i < x; i++) { - if (a >= b) { - r += 1; - a -= b; - } - a <<= 1; - r <<= 1; - } - r = (c << (u32)x) + r; - - deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r); - return r; -} - -static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) -{ - int ret = 0; - u8 i = 0; - u8 buf[24]; - u32 ns_coeff1_2048nu; - u32 ns_coeff1_8191nu; - u32 ns_coeff1_8192nu; - u32 ns_coeff1_8193nu; - u32 ns_coeff2_2k; - u32 ns_coeff2_8k; - - deb_info("%s: adc_clock:%d bw:%d\n", __func__, - state->config.adc_clock, bw); - - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01e79e7a; - ns_coeff1_8191nu = 0x0079eb6e; - ns_coeff1_8192nu = 0x0079e79e; - ns_coeff1_8193nu = 0x0079e3cf; - ns_coeff2_2k = 0x00f3cf3d; - ns_coeff2_8k = 0x003cf3cf; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x0238e38e; - ns_coeff1_8191nu = 0x008e3d55; - ns_coeff1_8192nu = 0x008e38e4; - ns_coeff1_8193nu = 0x008e3472; - ns_coeff2_2k = 0x011c71c7; - ns_coeff2_8k = 0x00471c72; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x028a28a3; - ns_coeff1_8191nu = 0x00a28f3d; - ns_coeff1_8192nu = 0x00a28a29; - ns_coeff1_8193nu = 0x00a28514; - ns_coeff2_2k = 0x01451451; - ns_coeff2_8k = 0x00514514; - break; - default: - ret = -EINVAL; - } - break; - case 20480: /* 20.480 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x02adb6dc; - ns_coeff1_8191nu = 0x00ab7313; - ns_coeff1_8192nu = 0x00ab6db7; - ns_coeff1_8193nu = 0x00ab685c; - ns_coeff2_2k = 0x0156db6e; - ns_coeff2_8k = 0x0055b6dc; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x03200001; - ns_coeff1_8191nu = 0x00c80640; - ns_coeff1_8192nu = 0x00c80000; - ns_coeff1_8193nu = 0x00c7f9c0; - ns_coeff2_2k = 0x01900000; - ns_coeff2_8k = 0x00640000; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x03924926; - ns_coeff1_8191nu = 0x00e4996e; - ns_coeff1_8192nu = 0x00e49249; - ns_coeff1_8193nu = 0x00e48b25; - ns_coeff2_2k = 0x01c92493; - ns_coeff2_8k = 0x00724925; - break; - default: - ret = -EINVAL; - } - break; - case 28000: /* 28.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01f58d10; - ns_coeff1_8191nu = 0x007d672f; - ns_coeff1_8192nu = 0x007d6344; - ns_coeff1_8193nu = 0x007d5f59; - ns_coeff2_2k = 0x00fac688; - ns_coeff2_8k = 0x003eb1a2; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x02492492; - ns_coeff1_8191nu = 0x00924db7; - ns_coeff1_8192nu = 0x00924925; - ns_coeff1_8193nu = 0x00924492; - ns_coeff2_2k = 0x01249249; - ns_coeff2_8k = 0x00492492; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x029cbc15; - ns_coeff1_8191nu = 0x00a7343f; - ns_coeff1_8192nu = 0x00a72f05; - ns_coeff1_8193nu = 0x00a729cc; - ns_coeff2_2k = 0x014e5e0a; - ns_coeff2_8k = 0x00539783; - break; - default: - ret = -EINVAL; - } - break; - case 25000: /* 25.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x0231bcb5; - ns_coeff1_8191nu = 0x008c7391; - ns_coeff1_8192nu = 0x008c6f2d; - ns_coeff1_8193nu = 0x008c6aca; - ns_coeff2_2k = 0x0118de5b; - ns_coeff2_8k = 0x00463797; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x028f5c29; - ns_coeff1_8191nu = 0x00a3dc29; - ns_coeff1_8192nu = 0x00a3d70a; - ns_coeff1_8193nu = 0x00a3d1ec; - ns_coeff2_2k = 0x0147ae14; - ns_coeff2_8k = 0x0051eb85; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x02ecfb9d; - ns_coeff1_8191nu = 0x00bb44c1; - ns_coeff1_8192nu = 0x00bb3ee7; - ns_coeff1_8193nu = 0x00bb390d; - ns_coeff2_2k = 0x01767dce; - ns_coeff2_8k = 0x005d9f74; - break; - default: - ret = -EINVAL; - } - break; - default: - err("invalid xtal"); - return -EINVAL; - } - if (ret) { - err("invalid bandwidth"); - return ret; - } - - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); - - deb_info("%s: coeff:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xae00 + i, buf[i]); - if (ret) - break; - } - - return ret; -} - -static int af9013_set_adc_ctrl(struct af9013_state *state) -{ - int ret; - u8 buf[3], tmp, i; - u32 adc_cw; - - deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock); - - /* adc frequency type */ - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - tmp = 0; - break; - case 20480: /* 20.480 MHz */ - tmp = 1; - break; - case 28000: /* 28.000 MHz */ - tmp = 2; - break; - case 25000: /* 25.000 MHz */ - tmp = 3; - break; - default: - err("invalid xtal"); - return -EINVAL; - } - - adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul); - - buf[0] = (u8) ((adc_cw & 0x000000ff)); - buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16); - - deb_info("%s: adc_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd180 + i, buf[i]); - if (ret) - goto error; - } - ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp); -error: - return ret; -} - -static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) -{ - int ret; - u16 addr; - u8 buf[3], i, j; - u32 adc_freq, freq_cw; - s8 bfs_spec_inv; - int if_sample_freq; - - for (j = 0; j < 3; j++) { - if (j == 0) { - addr = 0xd140; /* fcw normal */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else if (j == 1) { - addr = 0x9be7; /* fcw dummy ram */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else { - addr = 0x9bea; /* fcw inverted */ - bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; - } - - adc_freq = state->config.adc_clock * 1000; - if_sample_freq = state->config.tuner_if * 1000; - - /* TDA18271 uses different sampling freq for every bw */ - if (state->config.tuner == AF9013_TUNER_TDA18271) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3300000; /* 3.3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3800000; /* 3.8 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4300000; /* 4.3 MHz */ - break; - } - } - - while (if_sample_freq > (adc_freq / 2)) - if_sample_freq = if_sample_freq - adc_freq; - - if (if_sample_freq >= 0) - bfs_spec_inv = bfs_spec_inv * (-1); - else - if_sample_freq = if_sample_freq * (-1); - - freq_cw = af913_div(if_sample_freq, adc_freq, 23ul); - - if (bfs_spec_inv == -1) - freq_cw = 0x00800000 - freq_cw; - - buf[0] = (u8) ((freq_cw & 0x000000ff)); - buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16); - - - deb_info("%s: freq_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, addr++, buf[i]); - if (ret) - goto error; - } - } -error: - return ret; -} - -static int af9013_set_ofdm_params(struct af9013_state *state, - struct dvb_ofdm_parameters *params, u8 *auto_mode) -{ - int ret; - u8 i, buf[3] = {0, 0, 0}; - *auto_mode = 0; /* set if parameters are requested to auto set */ - - switch (params->transmission_mode) { - case TRANSMISSION_MODE_AUTO: - *auto_mode = 1; - case TRANSMISSION_MODE_2K: - break; - case TRANSMISSION_MODE_8K: - buf[0] |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (params->guard_interval) { - case GUARD_INTERVAL_AUTO: - *auto_mode = 1; - case GUARD_INTERVAL_1_32: - break; - case GUARD_INTERVAL_1_16: - buf[0] |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - buf[0] |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - buf[0] |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (params->hierarchy_information) { - case HIERARCHY_AUTO: - *auto_mode = 1; - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - buf[0] |= (1 << 4); - break; - case HIERARCHY_2: - buf[0] |= (2 << 4); - break; - case HIERARCHY_4: - buf[0] |= (3 << 4); - break; - default: - return -EINVAL; - }; - - switch (params->constellation) { - case QAM_AUTO: - *auto_mode = 1; - case QPSK: - break; - case QAM_16: - buf[1] |= (1 << 6); - break; - case QAM_64: - buf[1] |= (2 << 6); - break; - default: - return -EINVAL; - } - - /* Use HP. How and which case we can switch to LP? */ - buf[1] |= (1 << 4); - - switch (params->code_rate_HP) { - case FEC_AUTO: - *auto_mode = 1; - case FEC_1_2: - break; - case FEC_2_3: - buf[2] |= (1 << 0); - break; - case FEC_3_4: - buf[2] |= (2 << 0); - break; - case FEC_5_6: - buf[2] |= (3 << 0); - break; - case FEC_7_8: - buf[2] |= (4 << 0); - break; - default: - return -EINVAL; - } - - switch (params->code_rate_LP) { - case FEC_AUTO: - /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO - by dvb_frontend.c for compatibility */ - if (params->hierarchy_information != HIERARCHY_NONE) - *auto_mode = 1; - case FEC_1_2: - break; - case FEC_2_3: - buf[2] |= (1 << 3); - break; - case FEC_3_4: - buf[2] |= (2 << 3); - break; - case FEC_5_6: - buf[2] |= (3 << 3); - break; - case FEC_7_8: - buf[2] |= (4 << 3); - break; - case FEC_NONE: - if (params->hierarchy_information == HIERARCHY_AUTO) - break; - default: - return -EINVAL; - } - - switch (params->bandwidth) { - case BANDWIDTH_6_MHZ: - break; - case BANDWIDTH_7_MHZ: - buf[1] |= (1 << 2); - break; - case BANDWIDTH_8_MHZ: - buf[1] |= (2 << 2); - break; - default: - return -EINVAL; - } - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]); - if (ret) - break; - } - - return ret; -} - -static int af9013_reset(struct af9013_state *state, u8 sleep) -{ - int ret; - u8 tmp, i; - deb_info("%s\n", __func__); - - /* enable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1); - if (ret) - goto error; - - /* start reset mechanism */ - ret = af9013_write_reg(state, 0xaeff, 1); - if (ret) - goto error; - - /* reset is done when bit 1 is set */ - for (i = 0; i < 150; i++) { - ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp); - if (ret) - goto error; - if (tmp) - break; /* reset done */ - msleep(10); - } - if (!tmp) - return -ETIMEDOUT; - - /* don't clear reset when going to sleep */ - if (!sleep) { - /* clear OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - - /* disable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } -error: - return ret; -} - -static int af9013_power_ctrl(struct af9013_state *state, u8 onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); - - if (onoff) { - /* power on */ - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } else { - /* power off */ - ret = af9013_reset(state, 1); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1); - } -error: - return ret; -} - -static int af9013_lock_led(struct af9013_state *state, u8 onoff) -{ - deb_info("%s: onoff:%d\n", __func__, onoff); - - return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff); -} - -static int af9013_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 auto_mode; /* auto set TPS */ - - deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, - params->u.ofdm.bandwidth); - - state->frequency = params->frequency; - - /* program CFOE coefficients */ - ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* program frequency control */ - ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* clear TPS lock flag (inverted flag) */ - ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1); - if (ret) - goto error; - - /* clear MPEG2 lock flag */ - ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0); - if (ret) - goto error; - - /* empty channel function */ - ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0); - if (ret) - goto error; - - /* empty DVB-T channel function */ - ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0); - if (ret) - goto error; - - /* program tuner */ - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); - - /* program TPS and bandwidth, check if auto mode needed */ - ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); - if (ret) - goto error; - - if (auto_mode) { - /* clear easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 0); - deb_info("%s: auto TPS\n", __func__); - } else { - /* set easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 1); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xaefe, 0); - deb_info("%s: manual TPS\n", __func__); - } - if (ret) - goto error; - - /* everything is set, lets try to receive channel - OFSM GO! */ - ret = af9013_write_reg(state, 0xffff, 0); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 i, buf[3]; - deb_info("%s\n", __func__); - - /* read TPS registers */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]); - if (ret) - goto error; - } - - switch ((buf[1] >> 6) & 3) { - case 0: - p->u.ofdm.constellation = QPSK; - break; - case 1: - p->u.ofdm.constellation = QAM_16; - break; - case 2: - p->u.ofdm.constellation = QAM_64; - break; - } - - switch ((buf[0] >> 0) & 3) { - case 0: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - } - - switch ((buf[0] >> 2) & 3) { - case 0: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - - switch ((buf[0] >> 4) & 7) { - case 0: - p->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - p->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - p->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - } - - switch ((buf[2] >> 0) & 7) { - case 0: - p->u.ofdm.code_rate_HP = FEC_1_2; - break; - case 1: - p->u.ofdm.code_rate_HP = FEC_2_3; - break; - case 2: - p->u.ofdm.code_rate_HP = FEC_3_4; - break; - case 3: - p->u.ofdm.code_rate_HP = FEC_5_6; - break; - case 4: - p->u.ofdm.code_rate_HP = FEC_7_8; - break; - } - - switch ((buf[2] >> 3) & 7) { - case 0: - p->u.ofdm.code_rate_LP = FEC_1_2; - break; - case 1: - p->u.ofdm.code_rate_LP = FEC_2_3; - break; - case 2: - p->u.ofdm.code_rate_LP = FEC_3_4; - break; - case 3: - p->u.ofdm.code_rate_LP = FEC_5_6; - break; - case 4: - p->u.ofdm.code_rate_LP = FEC_7_8; - break; - } - - switch ((buf[1] >> 2) & 3) { - case 0: - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - case 1: - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 2: - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - } - - p->inversion = INVERSION_AUTO; - p->frequency = state->frequency; - -error: - return ret; -} - -static int af9013_update_ber_unc(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i; - u32 error_bit_count = 0; - u32 total_bit_count = 0; - u32 abort_packet_count = 0; - - state->ber = 0; - - /* check if error bit count is ready */ - ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]); - if (ret) - goto error; - if (!buf[0]) - goto exit; - - /* get RSD packet abort count */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd38a + i, &buf[i]); - if (ret) - goto error; - } - abort_packet_count = (buf[1] << 8) + buf[0]; - - /* get error bit count */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd387 + i, &buf[i]); - if (ret) - goto error; - } - error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - error_bit_count = error_bit_count - abort_packet_count * 8 * 8; - - /* get used RSD counting period (10000 RSD packets used) */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd385 + i, &buf[i]); - if (ret) - goto error; - } - total_bit_count = (buf[1] << 8) + buf[0]; - total_bit_count = total_bit_count - abort_packet_count; - total_bit_count = total_bit_count * 204 * 8; - - if (total_bit_count) - state->ber = error_bit_count * 1000000000 / total_bit_count; - - state->ucblocks += abort_packet_count; - - deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__, - error_bit_count, total_bit_count, abort_packet_count); - - /* set BER counting range */ - ret = af9013_write_reg(state, 0xd385, 10000 & 0xff); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xd386, 10000 >> 8); - if (ret) - goto error; - /* reset and start BER counter */ - ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1); - if (ret) - goto error; - -exit: -error: - return ret; -} - -static int af9013_update_snr(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i, len; - u32 quant = 0; - struct snr_table *snr_table; - - /* check if quantizer ready (for snr) */ - ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); - if (ret) - goto error; - if (buf[0]) { - /* quantizer ready - read it */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]); - if (ret) - goto error; - } - quant = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - - /* read current constellation */ - ret = af9013_read_reg(state, 0xd3c1, &buf[0]); - if (ret) - goto error; - - switch ((buf[0] >> 6) & 3) { - case 0: - len = ARRAY_SIZE(qpsk_snr_table); - snr_table = qpsk_snr_table; - break; - case 1: - len = ARRAY_SIZE(qam16_snr_table); - snr_table = qam16_snr_table; - break; - case 2: - len = ARRAY_SIZE(qam64_snr_table); - snr_table = qam64_snr_table; - break; - default: - len = 0; - break; - } - - if (len) { - for (i = 0; i < len; i++) { - if (quant < snr_table[i].val) { - state->snr = snr_table[i].snr * 10; - break; - } - } - } - - /* set quantizer super frame count */ - ret = af9013_write_reg(state, 0xd2e2, 1); - if (ret) - goto error; - - /* check quantizer availability */ - for (i = 0; i < 10; i++) { - msleep(10); - ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1, - &buf[0]); - if (ret) - goto error; - if (!buf[0]) - break; - } - - /* reset quantizer */ - ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1); - if (ret) - goto error; - } - -error: - return ret; -} - -static int af9013_update_signal_strength(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 tmp0; - u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; - int signal_strength; - - deb_info("%s\n", __func__); - - state->signal_strength = 0; - - ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); - if (ret) - goto error; - if (tmp0) { - ret = af9013_read_reg(state, 0x9bbd, &rf_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9bd0, &rf_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be2, &if_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be4, &if_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07c, &rf_gain); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07d, &if_gain); - if (ret) - goto error; - signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ - 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ - 11 * (rf_80 + if_80)); - if (signal_strength < 0) - signal_strength = 0; - else if (signal_strength > 0xffff) - signal_strength = 0xffff; - - state->signal_strength = signal_strength; - } - -error: - return ret; -} - -static int af9013_update_statistics(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - - if (time_before(jiffies, state->next_statistics_check)) - return 0; - - /* set minimum statistic update interval */ - state->next_statistics_check = jiffies + msecs_to_jiffies(1200); - - ret = af9013_update_signal_strength(fe); - if (ret) - goto error; - ret = af9013_update_snr(fe); - if (ret) - goto error; - ret = af9013_update_ber_unc(fe); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 800; - fesettings->step_size = 0; - fesettings->max_drift = 0; - - return 0; -} - -static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret = 0; - u8 tmp; - *status = 0; - - /* TPS lock */ - ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - /* MPEG2 lock */ - ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - if (!*status & FE_HAS_SIGNAL) { - /* AGC lock */ - ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SIGNAL; - } - - if (!*status & FE_HAS_CARRIER) { - /* CFO lock */ - ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_CARRIER; - } - - if (!*status & FE_HAS_CARRIER) { - /* SFOE lock */ - ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_CARRIER; - } - - ret = af9013_update_statistics(fe); - -error: - return ret; -} - - -static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ber = state->ber; - return ret; -} - -static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *strength = state->signal_strength; - return ret; -} - -static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *snr = state->snr; - return ret; -} - -static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ucblocks = state->ucblocks; - return ret; -} - -static int af9013_sleep(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - deb_info("%s\n", __func__); - - ret = af9013_lock_led(state, 0); - if (ret) - goto error; - - ret = af9013_power_ctrl(state, 0); -error: - return ret; -} - -static int af9013_init(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret, i, len; - u8 tmp0, tmp1; - struct regdesc *init; - deb_info("%s\n", __func__); - - /* reset OFDM */ - ret = af9013_reset(state, 0); - if (ret) - goto error; - - /* power on */ - ret = af9013_power_ctrl(state, 1); - if (ret) - goto error; - - /* enable ADC */ - ret = af9013_write_reg(state, 0xd73a, 0xa4); - if (ret) - goto error; - - /* write API version to firmware */ - for (i = 0; i < sizeof(state->config.api_version); i++) { - ret = af9013_write_reg(state, 0x9bf2 + i, - state->config.api_version[i]); - if (ret) - goto error; - } - - /* program ADC control */ - ret = af9013_set_adc_ctrl(state); - if (ret) - goto error; - - /* set I2C master clock */ - ret = af9013_write_reg(state, 0xd416, 0x14); - if (ret) - goto error; - - /* set 16 embx */ - ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1); - if (ret) - goto error; - - /* set no trigger */ - ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0); - if (ret) - goto error; - - /* set read-update bit for constellation */ - ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1); - if (ret) - goto error; - - /* enable FEC monitor */ - ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1); - if (ret) - goto error; - - /* load OFSM settings */ - deb_info("%s: load ofsm settings\n", __func__); - len = ARRAY_SIZE(ofsm_init); - init = ofsm_init; - for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, - init[i].len, init[i].val); - if (ret) - goto error; - } - - /* load tuner specific settings */ - deb_info("%s: load tuner specific settings\n", __func__); - switch (state->config.tuner) { - case AF9013_TUNER_MXL5003D: - len = ARRAY_SIZE(tuner_init_mxl5003d); - init = tuner_init_mxl5003d; - break; - case AF9013_TUNER_MXL5005D: - case AF9013_TUNER_MXL5005R: - len = ARRAY_SIZE(tuner_init_mxl5005); - init = tuner_init_mxl5005; - break; - case AF9013_TUNER_ENV77H11D5: - len = ARRAY_SIZE(tuner_init_env77h11d5); - init = tuner_init_env77h11d5; - break; - case AF9013_TUNER_MT2060: - len = ARRAY_SIZE(tuner_init_mt2060); - init = tuner_init_mt2060; - break; - case AF9013_TUNER_MC44S803: - len = ARRAY_SIZE(tuner_init_mc44s803); - init = tuner_init_mc44s803; - break; - case AF9013_TUNER_QT1010: - case AF9013_TUNER_QT1010A: - len = ARRAY_SIZE(tuner_init_qt1010); - init = tuner_init_qt1010; - break; - case AF9013_TUNER_MT2060_2: - len = ARRAY_SIZE(tuner_init_mt2060_2); - init = tuner_init_mt2060_2; - break; - case AF9013_TUNER_TDA18271: - len = ARRAY_SIZE(tuner_init_tda18271); - init = tuner_init_tda18271; - break; - case AF9013_TUNER_UNKNOWN: - default: - len = ARRAY_SIZE(tuner_init_unknown); - init = tuner_init_unknown; - break; - } - - for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, - init[i].len, init[i].val); - if (ret) - goto error; - } - - /* set TS mode */ - deb_info("%s: setting ts mode\n", __func__); - tmp0 = 0; /* parallel mode */ - tmp1 = 0; /* serial mode */ - switch (state->config.output_mode) { - case AF9013_OUTPUT_MODE_PARALLEL: - tmp0 = 1; - break; - case AF9013_OUTPUT_MODE_SERIAL: - tmp1 = 1; - break; - case AF9013_OUTPUT_MODE_USB: - /* usb mode for AF9015 */ - default: - break; - } - ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */ - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */ - if (ret) - goto error; - - /* enable lock led */ - ret = af9013_lock_led(state, 1); - if (ret) - goto error; - -error: - return ret; -} - -static struct dvb_frontend_ops af9013_ops; - -static int af9013_download_firmware(struct af9013_state *state) -{ - int i, len, packets, remainder, ret; - const struct firmware *fw; - u16 addr = 0x5100; /* firmware start address */ - u16 checksum = 0; - u8 val; - u8 fw_params[4]; - u8 *data; - u8 *fw_file = AF9013_DEFAULT_FIRMWARE; - - msleep(100); - /* check whether firmware is already running */ - ret = af9013_read_reg(state, 0x98be, &val); - if (ret) - goto error; - else - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; - - info("found a '%s' in cold state, will try to load a firmware", - af9013_ops.info.name); - - /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, &state->i2c->dev); - if (ret) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details" \ - " on firmware-problems. (%d)", - fw_file, ret); - goto error; - } - - info("downloading firmware from file '%s'", fw_file); - - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; - - fw_params[0] = checksum >> 8; - fw_params[1] = checksum & 0xff; - fw_params[2] = fw->size >> 8; - fw_params[3] = fw->size & 0xff; - - /* write fw checksum & size */ - ret = af9013_write_ofsm_regs(state, 0x50fc, - fw_params, sizeof(fw_params)); - if (ret) - goto error_release; - - #define FW_PACKET_MAX_DATA 16 - - packets = fw->size / FW_PACKET_MAX_DATA; - remainder = fw->size % FW_PACKET_MAX_DATA; - len = FW_PACKET_MAX_DATA; - for (i = 0; i <= packets; i++) { - if (i == packets) /* set size of the last packet */ - len = remainder; - - data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); - ret = af9013_write_ofsm_regs(state, addr, data, len); - addr += FW_PACKET_MAX_DATA; - - if (ret) { - err("firmware download failed at %d with %d", i, ret); - goto error_release; - } - } - - /* request boot firmware */ - ret = af9013_write_reg(state, 0xe205, 1); - if (ret) - goto error_release; - - for (i = 0; i < 15; i++) { - msleep(100); - - /* check firmware status */ - ret = af9013_read_reg(state, 0x98be, &val); - if (ret) - goto error_release; - - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c || val == 0x04) /* success or fail */ - break; - } - - if (val == 0x04) { - err("firmware did not run"); - ret = -1; - } else if (val != 0x0c) { - err("firmware boot timeout"); - ret = -1; - } - -error_release: - release_firmware(fw); -error: -exit: - if (!ret) - info("found a '%s' in warm state.", af9013_ops.info.name); - return ret; -} - -static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int ret; - struct af9013_state *state = fe->demodulator_priv; - deb_info("%s: enable:%d\n", __func__, enable); - - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) - ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable); - else - ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable); - - return ret; -} - -static void af9013_release(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops af9013_ops; - -struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c) -{ - int ret; - struct af9013_state *state = NULL; - u8 buf[3], i; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct af9013_config)); - - /* chip version */ - ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); - if (ret) - goto error; - - /* ROM version */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0x116b + i, &buf[i]); - if (ret) - goto error; - } - deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, - buf[2], buf[0], buf[1]); - - /* download firmware */ - if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { - ret = af9013_download_firmware(state); - if (ret) - goto error; - } - - /* firmware version */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0x5103 + i, &buf[i]); - if (ret) - goto error; - } - info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]); - - /* settings for mp2if */ - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { - /* AF9015 split PSB to 1.5k + 0.5k */ - ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1); - } else { - /* AF9013 change the output bit to data7 */ - ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1); - if (ret) - goto error; - /* AF9013 set mpeg to full speed */ - ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1); - } - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1); - if (ret) - goto error; - - /* set GPIOs */ - for (i = 0; i < sizeof(state->config.gpio); i++) { - ret = af9013_set_gpio(state, i, state->config.gpio[i]); - if (ret) - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &af9013_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(af9013_attach); - -static struct dvb_frontend_ops af9013_ops = { - .info = { - .name = "Afatech AF9013 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 250000, - .frequency_tolerance = 0, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = af9013_release, - .init = af9013_init, - .sleep = af9013_sleep, - .i2c_gate_ctrl = af9013_i2c_gate_ctrl, - - .set_frontend = af9013_set_frontend, - .get_frontend = af9013_get_frontend, - - .get_tune_settings = af9013_get_tune_settings, - - .read_status = af9013_read_status, - .read_ber = af9013_read_ber, - .read_signal_strength = af9013_read_signal_strength, - .read_snr = af9013_read_snr, - .read_ucblocks = af9013_read_ucblocks, -}; - -module_param_named(debug, af9013_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_AUTHOR("Antti Palosaari "); -MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/af9013.h b/trunk/drivers/media/dvb/frontends/af9013.h deleted file mode 100644 index 28b90c91c766..000000000000 --- a/trunk/drivers/media/dvb/frontends/af9013.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _AF9013_H_ -#define _AF9013_H_ - -#include - -enum af9013_ts_mode { - AF9013_OUTPUT_MODE_PARALLEL, - AF9013_OUTPUT_MODE_SERIAL, - AF9013_OUTPUT_MODE_USB, /* only for AF9015 */ -}; - -enum af9013_tuner { - AF9013_TUNER_MXL5003D = 3, /* MaxLinear */ - AF9013_TUNER_MXL5005D = 13, /* MaxLinear */ - AF9013_TUNER_MXL5005R = 30, /* MaxLinear */ - AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */ - AF9013_TUNER_MT2060 = 130, /* Microtune */ - AF9013_TUNER_MC44S803 = 133, /* Freescale */ - AF9013_TUNER_QT1010 = 134, /* Quantek */ - AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */ - AF9013_TUNER_MT2060_2 = 147, /* Microtune */ - AF9013_TUNER_TDA18271 = 156, /* NXP */ - AF9013_TUNER_QT1010A = 162, /* Quantek */ -}; - -/* AF9013/5 GPIOs (mostly guessed) - demod#1-gpio#0 - set demod#2 i2c-addr for dual devices - demod#1-gpio#1 - xtal setting (?) - demod#1-gpio#3 - tuner#1 - demod#2-gpio#0 - tuner#2 - demod#2-gpio#1 - xtal setting (?) -*/ -#define AF9013_GPIO_ON (1 << 0) -#define AF9013_GPIO_EN (1 << 1) -#define AF9013_GPIO_O (1 << 2) -#define AF9013_GPIO_I (1 << 3) - -#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN) -#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN) -#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -struct af9013_config { - /* demodulator's I2C address */ - u8 demod_address; - - /* frequencies in kHz */ - u32 adc_clock; - - /* tuner ID */ - u8 tuner; - - /* tuner IF */ - u16 tuner_if; - - /* TS data output mode */ - u8 output_mode:2; - - /* RF spectrum inversion */ - u8 rf_spec_inv:1; - - /* API version */ - u8 api_version[4]; - - /* GPIOs */ - u8 gpio[4]; -}; - - -#if defined(CONFIG_DVB_AF9013) || \ - (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE)) -extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *af9013_attach( -const struct af9013_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_AF9013 */ - -#endif /* _AF9013_H_ */ diff --git a/trunk/drivers/media/dvb/frontends/af9013_priv.h b/trunk/drivers/media/dvb/frontends/af9013_priv.h deleted file mode 100644 index 163e251d0b73..000000000000 --- a/trunk/drivers/media/dvb/frontends/af9013_priv.h +++ /dev/null @@ -1,869 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _AF9013_PRIV_ -#define _AF9013_PRIV_ - -#define LOG_PREFIX "af9013" -extern int af9013_debug; - -#define dprintk(var, level, args...) \ - do { if ((var & level)) printk(args); } while (0) - -#define debug_dump(b, l, func) {\ - int loop_; \ - for (loop_ = 0; loop_ < l; loop_++) \ - func("%02x ", b[loop_]); \ - func("\n");\ -} - -#define deb_info(args...) dprintk(af9013_debug, 0x01, args) - -#undef err -#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) -#undef info -#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) -#undef warn -#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) - -#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw" - -struct regdesc { - u16 addr; - u8 pos:4; - u8 len:4; - u8 val; -}; - -struct snr_table { - u32 val; - u8 snr; -}; - -/* QPSK SNR lookup table */ -static struct snr_table qpsk_snr_table[] = { - { 0x0b4771, 0 }, - { 0x0c1aed, 1 }, - { 0x0d0d27, 2 }, - { 0x0e4d19, 3 }, - { 0x0e5da8, 4 }, - { 0x107097, 5 }, - { 0x116975, 6 }, - { 0x1252d9, 7 }, - { 0x131fa4, 8 }, - { 0x13d5e1, 9 }, - { 0x148e53, 10 }, - { 0x15358b, 11 }, - { 0x15dd29, 12 }, - { 0x168112, 13 }, - { 0x170b61, 14 }, - { 0xffffff, 15 }, -}; - -/* QAM16 SNR lookup table */ -static struct snr_table qam16_snr_table[] = { - { 0x05eb62, 5 }, - { 0x05fecf, 6 }, - { 0x060b80, 7 }, - { 0x062501, 8 }, - { 0x064865, 9 }, - { 0x069604, 10 }, - { 0x06f356, 11 }, - { 0x07706a, 12 }, - { 0x0804d3, 13 }, - { 0x089d1a, 14 }, - { 0x093e3d, 15 }, - { 0x09e35d, 16 }, - { 0x0a7c3c, 17 }, - { 0x0afaf8, 18 }, - { 0x0b719d, 19 }, - { 0xffffff, 20 }, -}; - -/* QAM64 SNR lookup table */ -static struct snr_table qam64_snr_table[] = { - { 0x03109b, 12 }, - { 0x0310d4, 13 }, - { 0x031920, 14 }, - { 0x0322d0, 15 }, - { 0x0339fc, 16 }, - { 0x0364a1, 17 }, - { 0x038bcc, 18 }, - { 0x03c7d3, 19 }, - { 0x0408cc, 20 }, - { 0x043bed, 21 }, - { 0x048061, 22 }, - { 0x04be95, 23 }, - { 0x04fa7d, 24 }, - { 0x052405, 25 }, - { 0x05570d, 26 }, - { 0xffffff, 27 }, -}; - -static struct regdesc ofsm_init[] = { - { 0xd73a, 0, 8, 0xa1 }, - { 0xd73b, 0, 8, 0x1f }, - { 0xd73c, 4, 4, 0x0a }, - { 0xd732, 3, 1, 0x00 }, - { 0xd731, 4, 2, 0x03 }, - { 0xd73d, 7, 1, 0x01 }, - { 0xd740, 0, 1, 0x00 }, - { 0xd740, 1, 1, 0x00 }, - { 0xd740, 2, 1, 0x00 }, - { 0xd740, 3, 1, 0x01 }, - { 0xd3c1, 4, 1, 0x01 }, - { 0xd3a2, 0, 8, 0x00 }, - { 0xd3a3, 0, 8, 0x04 }, - { 0xd305, 0, 8, 0x32 }, - { 0xd306, 0, 8, 0x10 }, - { 0xd304, 0, 8, 0x04 }, - { 0x9112, 0, 1, 0x01 }, - { 0x911d, 0, 1, 0x01 }, - { 0x911a, 0, 1, 0x01 }, - { 0x911b, 0, 1, 0x01 }, - { 0x9bce, 0, 4, 0x02 }, - { 0x9116, 0, 1, 0x01 }, - { 0x9bd1, 0, 1, 0x01 }, - { 0xd2e0, 0, 8, 0xd0 }, - { 0xd2e9, 0, 4, 0x0d }, - { 0xd38c, 0, 8, 0xfc }, - { 0xd38d, 0, 8, 0x00 }, - { 0xd38e, 0, 8, 0x7e }, - { 0xd38f, 0, 8, 0x00 }, - { 0xd390, 0, 8, 0x2f }, - { 0xd145, 4, 1, 0x01 }, - { 0xd1a9, 4, 1, 0x01 }, - { 0xd158, 5, 3, 0x01 }, - { 0xd159, 0, 6, 0x06 }, - { 0xd167, 0, 8, 0x00 }, - { 0xd168, 0, 4, 0x07 }, - { 0xd1c3, 5, 3, 0x00 }, - { 0xd1c4, 0, 6, 0x00 }, - { 0xd1c5, 0, 7, 0x10 }, - { 0xd1c6, 0, 3, 0x02 }, - { 0xd080, 2, 5, 0x03 }, - { 0xd081, 4, 4, 0x09 }, - { 0xd098, 4, 4, 0x0f }, - { 0xd098, 0, 4, 0x03 }, - { 0xdbc0, 3, 1, 0x01 }, - { 0xdbc0, 4, 1, 0x01 }, - { 0xdbc7, 0, 8, 0x08 }, - { 0xdbc8, 4, 4, 0x00 }, - { 0xdbc9, 0, 5, 0x01 }, - { 0xd280, 0, 8, 0xe0 }, - { 0xd281, 0, 8, 0xff }, - { 0xd282, 0, 8, 0xff }, - { 0xd283, 0, 8, 0xc3 }, - { 0xd284, 0, 8, 0xff }, - { 0xd285, 0, 4, 0x01 }, - { 0xd0f0, 0, 7, 0x1a }, - { 0xd0f1, 4, 1, 0x01 }, - { 0xd0f2, 0, 8, 0x0c }, - { 0xd103, 0, 4, 0x08 }, - { 0xd0f8, 0, 7, 0x20 }, - { 0xd111, 5, 1, 0x00 }, - { 0xd111, 6, 1, 0x00 }, - { 0x910b, 0, 8, 0x0a }, - { 0x9115, 0, 8, 0x02 }, - { 0x910c, 0, 8, 0x02 }, - { 0x910d, 0, 8, 0x08 }, - { 0x910e, 0, 8, 0x0a }, - { 0x9bf6, 0, 8, 0x06 }, - { 0x9bf8, 0, 8, 0x02 }, - { 0x9bf7, 0, 8, 0x05 }, - { 0x9bf9, 0, 8, 0x0f }, - { 0x9bfc, 0, 8, 0x13 }, - { 0x9bd3, 0, 8, 0xff }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, -}; - -/* Panasonic ENV77H11D5 tuner init - AF9013_TUNER_ENV77H11D5 = 129 */ -static struct regdesc tuner_init_env77h11d5[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x03 }, - { 0x9bbe, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0xd015, 0, 8, 0x50 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0xeb }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf4 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0xeb }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0x52 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* Microtune MT2060 tuner init - AF9013_TUNER_MT2060 = 130 */ -static struct regdesc tuner_init_mt2060[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x07 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bbe, 0, 1, 0x00 }, - { 0x9bcc, 0, 1, 0x00 }, - { 0x9bb9, 0, 8, 0x75 }, - { 0x9bcd, 0, 8, 0x24 }, - { 0x9bff, 0, 8, 0x30 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x32 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x36 }, - { 0xd00d, 0, 2, 0x03 }, - { 0xd00a, 0, 8, 0x35 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x90 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x36 }, - { 0x9bc6, 0, 8, 0x03 }, - { 0x9bba, 0, 8, 0xc9 }, - { 0x9bc9, 0, 8, 0x79 }, - { 0xd011, 0, 8, 0x10 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0x45 }, - { 0xd014, 0, 2, 0x03 }, - { 0xd040, 0, 8, 0x98 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0xcf }, - { 0xd043, 0, 2, 0x03 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xcc }, - { 0x9be4, 0, 8, 0xa0 }, - { 0x9bbd, 0, 8, 0x8e }, - { 0x9be2, 0, 8, 0x4d }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Microtune MT2060 tuner init - AF9013_TUNER_MT2060_2 = 147 */ -static struct regdesc tuner_init_mt2060_2[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x06 }, - { 0x9bbe, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x32 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x36 }, - { 0xd00d, 0, 2, 0x03 }, - { 0xd00a, 0, 8, 0x35 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x90 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x36 }, - { 0x9bc6, 0, 8, 0x03 }, - { 0x9bba, 0, 8, 0xc9 }, - { 0x9bc9, 0, 8, 0x79 }, - { 0xd011, 0, 8, 0x10 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0x45 }, - { 0xd014, 0, 2, 0x03 }, - { 0xd040, 0, 8, 0x98 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0xcf }, - { 0xd043, 0, 2, 0x03 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 8, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x96 }, - { 0xd054, 0, 8, 0x46 }, - { 0xd045, 7, 1, 0x00 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* MaxLinear MXL5003 tuner init - AF9013_TUNER_MXL5003D = 3 */ -static struct regdesc tuner_init_mxl5003d[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x09 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bfc, 0, 8, 0x0f }, - { 0x9bf6, 0, 8, 0x01 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0xd015, 0, 8, 0x33 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x40 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x6c }, - { 0xd007, 0, 2, 0x00 }, - { 0xd00c, 0, 8, 0x3d }, - { 0xd00d, 0, 2, 0x00 }, - { 0xd00a, 0, 8, 0x45 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x52 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x3d }, - { 0x9bc6, 0, 8, 0x00 }, - { 0x9bba, 0, 8, 0xa2 }, - { 0x9bc9, 0, 8, 0xa0 }, - { 0xd011, 0, 8, 0x56 }, - { 0xd012, 0, 2, 0x00 }, - { 0xd013, 0, 8, 0x50 }, - { 0xd014, 0, 2, 0x00 }, - { 0xd040, 0, 8, 0x56 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0x50 }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 8, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* MaxLinear MXL5005 tuner init - AF9013_TUNER_MXL5005D = 13 - AF9013_TUNER_MXL5005R = 30 */ -static struct regdesc tuner_init_mxl5005[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x07 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x28 }, - { 0x9bff, 0, 8, 0x24 }, - { 0xd015, 0, 8, 0x40 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x40 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x73 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0xfa }, - { 0xd00d, 0, 2, 0x01 }, - { 0xd00a, 0, 8, 0xff }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x23 }, - { 0x9bc8, 0, 8, 0x55 }, - { 0x9bc3, 0, 8, 0x01 }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0xfa }, - { 0x9bc6, 0, 8, 0x01 }, - { 0x9bba, 0, 8, 0xff }, - { 0x9bc9, 0, 8, 0xff }, - { 0x9bd3, 0, 8, 0x95 }, - { 0xd011, 0, 8, 0x70 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xfb }, - { 0xd014, 0, 2, 0x01 }, - { 0xd040, 0, 8, 0x70 }, - { 0xd041, 0, 2, 0x01 }, - { 0xd042, 0, 8, 0xfb }, - { 0xd043, 0, 2, 0x01 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0x93 }, - { 0x9be4, 0, 8, 0xfe }, - { 0x9bbd, 0, 8, 0x63 }, - { 0x9be2, 0, 8, 0xfe }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Quantek QT1010 tuner init - AF9013_TUNER_QT1010 = 134 - AF9013_TUNER_QT1010A = 162 */ -static struct regdesc tuner_init_qt1010[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x09 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x28 }, - { 0x9bff, 0, 8, 0x20 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x99 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x0f }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0x50 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x00 }, - { 0x9bc8, 0, 8, 0x00 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x0f }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bba, 0, 8, 0xc5 }, - { 0x9bc9, 0, 8, 0xff }, - { 0xd011, 0, 8, 0x58 }, - { 0xd012, 0, 2, 0x02 }, - { 0xd013, 0, 8, 0x89 }, - { 0xd014, 0, 2, 0x01 }, - { 0xd040, 0, 8, 0x58 }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x89 }, - { 0xd043, 0, 2, 0x01 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xcd }, - { 0x9be4, 0, 8, 0xbb }, - { 0x9bbd, 0, 8, 0x93 }, - { 0x9be2, 0, 8, 0x80 }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Freescale MC44S803 tuner init - AF9013_TUNER_MC44S803 = 133 */ -static struct regdesc tuner_init_mc44s803[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x06 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bf6, 0, 8, 0x01 }, - { 0x9bf8, 0, 8, 0x02 }, - { 0x9bf9, 0, 8, 0x02 }, - { 0x9bfc, 0, 8, 0x1f }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x24 }, - { 0x9bff, 0, 8, 0x24 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x01 }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x7b }, - { 0xd007, 0, 2, 0x00 }, - { 0xd00c, 0, 8, 0x7c }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xfe }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x08 }, - { 0x9bc8, 0, 8, 0x9a }, - { 0x9bc3, 0, 8, 0x01 }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x7c }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bba, 0, 8, 0xfc }, - { 0x9bc9, 0, 8, 0xaa }, - { 0xd011, 0, 8, 0x6b }, - { 0xd012, 0, 2, 0x00 }, - { 0xd013, 0, 8, 0x88 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x6b }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0x7c }, - { 0xd043, 0, 2, 0x02 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0x9e }, - { 0x9be4, 0, 8, 0xff }, - { 0x9bbd, 0, 8, 0x9e }, - { 0x9be2, 0, 8, 0x25 }, - { 0x9bee, 0, 1, 0x01 }, - { 0xd73b, 3, 1, 0x00 }, -}; - -/* unknown, probably for tin can tuner, tuner init - AF9013_TUNER_UNKNOWN = 140 */ -static struct regdesc tuner_init_unknown[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x02 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x18 }, - { 0x9bff, 0, 8, 0x2c }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x00 }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf6 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc8, 0, 8, 0xaa }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x00 }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0xf0 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* NXP TDA18271 tuner init - AF9013_TUNER_TDA18271 = 156 */ -static struct regdesc tuner_init_tda18271[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x04 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x18 }, - { 0x9bff, 0, 8, 0x2c }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x00 }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf6 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc8, 0, 8, 0xaa }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x00 }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0xf0 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xa8 }, - { 0x9be4, 0, 8, 0x7f }, - { 0x9bbd, 0, 8, 0xa8 }, - { 0x9be2, 0, 8, 0x20 }, - { 0x9bee, 0, 1, 0x01 }, -}; - -#endif /* _AF9013_PRIV_ */ diff --git a/trunk/drivers/media/dvb/frontends/au8522.c b/trunk/drivers/media/dvb/frontends/au8522.c index eabf9a68e7ec..0b82cc2a1e16 100644 --- a/trunk/drivers/media/dvb/frontends/au8522.c +++ b/trunk/drivers/media/dvb/frontends/au8522.c @@ -40,8 +40,6 @@ struct au8522_state { u32 current_frequency; fe_modulation_t current_modulation; - u32 fe_status; - unsigned int led_state; }; static int debug; @@ -540,98 +538,11 @@ static int au8522_init(struct dvb_frontend *fe) return 0; } -static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - u8 val; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_output || - !led_config->gpio_output_enable || !led_config->gpio_output_disable) - return 0; - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_output & ~0xc000)); - if (onoff) { - /* enable GPIO output */ - val &= ~((led_config->gpio_output_enable >> 8) & 0xff); - val |= (led_config->gpio_output_enable & 0xff); - } else { - /* disable GPIO output */ - val &= ~((led_config->gpio_output_disable >> 8) & 0xff); - val |= (led_config->gpio_output_disable & 0xff); - } - return au8522_writereg(state, 0x8000 | - (led_config->gpio_output & ~0xc000), val); -} - -/* led = 0 | off - * led = 1 | signal ok - * led = 2 | signal strong - * led < 0 | only light led if leds are currently off - */ -static int au8522_led_ctrl(struct au8522_state *state, int led) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int i, ret = 0; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_leds || - !led_config->num_led_states || !led_config->led_states) - return 0; - - if (led < 0) { - /* if LED is already lit, then leave it as-is */ - if (state->led_state) - return 0; - else - led *= -1; - } - - /* toggle LED if changing state */ - if (state->led_state != led) { - u8 val; - - dprintk("%s: %d\n", __func__, led); - - au8522_led_gpio_enable(state, 1); - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_leds & ~0xc000)); - - /* start with all leds off */ - for (i = 0; i < led_config->num_led_states; i++) - val &= ~led_config->led_states[i]; - - /* set selected LED state */ - if (led < led_config->num_led_states) - val |= led_config->led_states[led]; - else if (led_config->num_led_states) - val |= - led_config->led_states[led_config->num_led_states - 1]; - - ret = au8522_writereg(state, 0x8000 | - (led_config->gpio_leds & ~0xc000), val); - if (ret < 0) - return ret; - - state->led_state = led; - - if (led == 0) - au8522_led_gpio_enable(state, 0); - } - - return 0; -} - static int au8522_sleep(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); - /* turn off led */ - au8522_led_ctrl(state, 0); - state->current_frequency = 0; return 0; @@ -681,53 +592,12 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; break; } - state->fe_status = *status; - - if (*status & FE_HAS_LOCK) - /* turn on LED, if it isn't on already */ - au8522_led_ctrl(state, -1); - else - /* turn off LED */ - au8522_led_ctrl(state, 0); dprintk("%s() status 0x%08x\n", __func__, *status); return 0; } -static int au8522_led_status(struct au8522_state *state, const u16 *snr) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int led; - u16 strong; - - /* bail out if we cant control an LED */ - if (!led_config) - return 0; - - if (0 == (state->fe_status & FE_HAS_LOCK)) - return au8522_led_ctrl(state, 0); - else if (state->current_modulation == QAM_256) - strong = led_config->qam256_strong; - else if (state->current_modulation == QAM_64) - strong = led_config->qam64_strong; - else /* (state->current_modulation == VSB_8) */ - strong = led_config->vsb8_strong; - - if (*snr >= strong) - led = 2; - else - led = 1; - - if ((state->led_state) && - (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10)) - /* snr didn't change enough to bother - * changing the color of the led */ - return 0; - - return au8522_led_ctrl(state, led); -} - static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) { struct au8522_state *state = fe->demodulator_priv; @@ -751,9 +621,6 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) au8522_readreg(state, 0x4311), snr); - if (state->config->led_cfg) - au8522_led_status(state, snr); - return ret; } diff --git a/trunk/drivers/media/dvb/frontends/au8522.h b/trunk/drivers/media/dvb/frontends/au8522.h index 7b94f554a093..595915ade8c3 100644 --- a/trunk/drivers/media/dvb/frontends/au8522.h +++ b/trunk/drivers/media/dvb/frontends/au8522.h @@ -30,21 +30,6 @@ enum au8522_if_freq { AU8522_IF_3_25MHZ, }; -struct au8522_led_config { - u16 vsb8_strong; - u16 qam64_strong; - u16 qam256_strong; - - u16 gpio_output; - /* unset hi bits, set low bits */ - u16 gpio_output_enable; - u16 gpio_output_disable; - - u16 gpio_leds; - u8 *led_states; - unsigned int num_led_states; -}; - struct au8522_config { /* the demodulator's i2c address */ u8 demod_address; @@ -54,8 +39,6 @@ struct au8522_config { #define AU8522_DEMODLOCKING 1 u8 status_mode; - struct au8522_led_config *led_cfg; - enum au8522_if_freq vsb_if; enum au8522_if_freq qam_if; }; diff --git a/trunk/drivers/media/dvb/frontends/cx24110.h b/trunk/drivers/media/dvb/frontends/cx24110.h index fdcceee91f3a..1792adb23c4d 100644 --- a/trunk/drivers/media/dvb/frontends/cx24110.h +++ b/trunk/drivers/media/dvb/frontends/cx24110.h @@ -33,17 +33,12 @@ struct cx24110_config u8 demod_address; }; -static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) -{ - u8 buf[] = { - (u8)((val >> 24) & 0xff), - (u8)((val >> 16) & 0xff), - (u8)((val >> 8) & 0xff) - }; - +static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) { + int r = 0; + u8 buf[] = {(u8) (val>>24), (u8) (val>>16), (u8) (val>>8)}; if (fe->ops.write) - return fe->ops.write(fe, buf, 3); - return 0; + r = fe->ops.write(fe, buf, 3); + return r; } #if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) diff --git a/trunk/drivers/media/dvb/frontends/cx24116.c b/trunk/drivers/media/dvb/frontends/cx24116.c deleted file mode 100644 index deb36f469ada..000000000000 --- a/trunk/drivers/media/dvb/frontends/cx24116.c +++ /dev/null @@ -1,1423 +0,0 @@ -/* - Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver - - Copyright (C) 2006-2008 Steven Toth - Copyright (C) 2006-2007 Georg Acher - Copyright (C) 2007-2008 Darron Broad - March 2007 - Fixed some bugs. - Added diseqc support. - Added corrected signal strength support. - August 2007 - Sync with legacy version. - Some clean ups. - Copyright (C) 2008 Igor Liplianin - September, 9th 2008 - Fixed locking on high symbol rates (>30000). - Implement MPEG initialization parameter. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "cx24116.h" - -static int debug = 0; -#define dprintk(args...) \ - do { \ - if (debug) printk ("cx24116: " args); \ - } while (0) - -#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" -#define CX24116_SEARCH_RANGE_KHZ 5000 - -/* known registers */ -#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */ -#define CX24116_REG_EXECUTE (0x1f) /* execute command */ -#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */ -#define CX24116_REG_RESET (0x20) /* reset status > 0 */ -#define CX24116_REG_SIGNAL (0x9e) /* signal low */ -#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */ -#define CX24116_REG_QUALITY8 (0xa3) -#define CX24116_REG_QSTATUS (0xbc) -#define CX24116_REG_QUALITY0 (0xd5) -#define CX24116_REG_BER0 (0xc9) -#define CX24116_REG_BER8 (0xc8) -#define CX24116_REG_BER16 (0xc7) -#define CX24116_REG_BER24 (0xc6) -#define CX24116_REG_UCB0 (0xcb) -#define CX24116_REG_UCB8 (0xca) -#define CX24116_REG_CLKDIV (0xf3) -#define CX24116_REG_RATEDIV (0xf9) -#define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ - -/* FECSTATUS bits */ -#define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */ -#define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */ -#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ -#define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */ - -/* arg buffer size */ -#define CX24116_ARGLEN (0x1e) - -/* rolloff */ -#define CX24116_ROLLOFF_020 (0x00) -#define CX24116_ROLLOFF_025 (0x01) -#define CX24116_ROLLOFF_035 (0x02) - -/* pilot bit */ -#define CX24116_PILOT_OFF (0x00) -#define CX24116_PILOT_ON (0x40) - -/* signal status */ -#define CX24116_HAS_SIGNAL (0x01) -#define CX24116_HAS_CARRIER (0x02) -#define CX24116_HAS_VITERBI (0x04) -#define CX24116_HAS_SYNCLOCK (0x08) -#define CX24116_HAS_UNKNOWN1 (0x10) -#define CX24116_HAS_UNKNOWN2 (0x20) -#define CX24116_STATUS_MASK (0x3f) -#define CX24116_SIGNAL_MASK (0xc0) - -#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */ -#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */ -#define CX24116_DISEQC_MESGCACHE (2) /* message cached */ - -/* arg offset for DiSEqC */ -#define CX24116_DISEQC_BURST (1) -#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */ -#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */ -#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */ -#define CX24116_DISEQC_MSGLEN (5) -#define CX24116_DISEQC_MSGOFS (6) - -/* DiSEqC burst */ -#define CX24116_DISEQC_MINI_A (0) -#define CX24116_DISEQC_MINI_B (1) - -/* DiSEqC tone burst */ -static int toneburst = 1; - -/* SNR measurements */ -static int esno_snr = 0; - -enum cmds -{ - CMD_SET_VCO = 0x10, - CMD_TUNEREQUEST = 0x11, - CMD_MPEGCONFIG = 0x13, - CMD_TUNERINIT = 0x14, - CMD_BANDWIDTH = 0x15, - CMD_GETAGC = 0x19, - CMD_LNBCONFIG = 0x20, - CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ - CMD_SET_TONEPRE = 0x22, - CMD_SET_TONE = 0x23, - CMD_UPDFWVERS = 0x35, - CMD_TUNERSLEEP = 0x36, - CMD_AGCCONTROL = 0x3b, /* Unknown */ -}; - -/* The Demod/Tuner can't easily provide these, we cache them */ -struct cx24116_tuning -{ - u32 frequency; - u32 symbol_rate; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec; - - fe_modulation_t modulation; - fe_pilot_t pilot; - fe_rolloff_t rolloff; - - /* Demod values */ - u8 fec_val; - u8 fec_mask; - u8 inversion_val; - u8 pilot_val; - u8 rolloff_val; -}; - -/* Basic commands that are sent to the firmware */ -struct cx24116_cmd -{ - u8 len; - u8 args[CX24116_ARGLEN]; -}; - -struct cx24116_state -{ - struct i2c_adapter* i2c; - const struct cx24116_config* config; - - struct dvb_frontend frontend; - - struct cx24116_tuning dcur; - struct cx24116_tuning dnxt; - - u8 skip_fw_load; - u8 burst; - struct cx24116_cmd dsec_cmd; -}; - -static int cx24116_writereg(struct cx24116_state* state, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 2 }; - int err; - - if (debug>1) - printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", - __func__,reg, data); - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," - " value == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -/* Bulk byte writes to a single I2C address, for 32k firmware load */ -static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len) -{ - int ret = -EREMOTEIO; - struct i2c_msg msg; - u8 *buf; - - buf = kmalloc(len + 1, GFP_KERNEL); - if (buf == NULL) { - printk("Unable to kmalloc\n"); - ret = -ENOMEM; - goto error; - } - - *(buf) = reg; - memcpy(buf + 1, data, len); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = len + 1; - - if (debug>1) - printk("cx24116: %s: write regN 0x%02x, len = %d\n", - __func__,reg, len); - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x\n", - __func__, ret, reg); - ret = -EREMOTEIO; - } - -error: - kfree(buf); - - return ret; -} - -static int cx24116_readreg(struct cx24116_state* state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: reg=0x%x (error=%d)\n", __func__, reg, ret); - return ret; - } - - if (debug>1) - printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]); - - return b1[0]; -} - -static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion) -{ - dprintk("%s(%d)\n", __func__, inversion); - - switch (inversion) { - case INVERSION_OFF: - state->dnxt.inversion_val = 0x00; - break; - case INVERSION_ON: - state->dnxt.inversion_val = 0x04; - break; - case INVERSION_AUTO: - state->dnxt.inversion_val = 0x0C; - break; - default: - return -EINVAL; - } - - state->dnxt.inversion = inversion; - - return 0; -} - -/* - * modfec (modulation and FEC) - * =========================== - * - * MOD FEC mask/val standard - * ---- -------- ----------- -------- - * QPSK FEC_1_2 0x02 0x02+X DVB-S - * QPSK FEC_2_3 0x04 0x02+X DVB-S - * QPSK FEC_3_4 0x08 0x02+X DVB-S - * QPSK FEC_4_5 0x10 0x02+X DVB-S (?) - * QPSK FEC_5_6 0x20 0x02+X DVB-S - * QPSK FEC_6_7 0x40 0x02+X DVB-S - * QPSK FEC_7_8 0x80 0x02+X DVB-S - * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?) - * QPSK AUTO 0xff 0x02+X DVB-S - * - * For DVB-S high byte probably represents FEC - * and low byte selects the modulator. The high - * byte is search range mask. Bit 5 may turn - * on DVB-S and remaining bits represent some - * kind of calibration (how/what i do not know). - * - * Eg.(2/3) szap "Zone Horror" - * - * mask/val = 0x04, 0x20 - * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK - * - * mask/val = 0x04, 0x30 - * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK - * - * After tuning FECSTATUS contains actual FEC - * in use numbered 1 through to 8 for 1/2 .. 2/3 etc - * - * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only) - * - * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2 - * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2 - * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2 - * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2 - * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2 - * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2 - * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2 - * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2 - * - * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2 - * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2 - * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2 - * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2 - * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2 - * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2 - * - * For DVB-S2 low bytes selects both modulator - * and FEC. High byte is meaningless here. To - * set pilot, bit 6 (0x40) is set. When inspecting - * FECSTATUS bit 7 (0x80) represents the pilot - * selection whilst not tuned. When tuned, actual FEC - * in use is found in FECSTATUS as per above. Pilot - * value is reset. - */ - -/* A table of modulation, fec and configuration bytes for the demod. - * Not all S2 mmodulation schemes are support and not all rates with - * a scheme are support. Especially, no auto detect when in S2 mode. - */ -struct cx24116_modfec { - fe_delivery_system_t delivery_system; - fe_modulation_t modulation; - fe_code_rate_t fec; - u8 mask; /* In DVBS mode this is used to autodetect */ - u8 val; /* Passed to the firmware to indicate mode selection */ -} CX24116_MODFEC_MODES[] = { - /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */ - - /*mod fec mask val */ - { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 }, - { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */ - { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */ - { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */ - { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */ - { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */ - { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */ - { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */ - { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */ - { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 }, - /* NBC-QPSK */ - { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 }, - { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 }, - { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 }, - { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 }, - { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 }, - { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 }, - { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a }, - { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b }, - /* 8PSK */ - { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c }, - { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d }, - { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e }, - { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f }, - { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 }, - { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 }, - /* - * `val' can be found in the FECSTATUS register when tuning. - * FECSTATUS will give the actual FEC in use if tuning was successful. - */ -}; - -static int cx24116_lookup_fecmod(struct cx24116_state* state, - fe_modulation_t m, fe_code_rate_t f) -{ - int i, ret = -EOPNOTSUPP; - - dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); - - for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++) - { - if( (m == CX24116_MODFEC_MODES[i].modulation) && - (f == CX24116_MODFEC_MODES[i].fec) ) - { - ret = i; - break; - } - } - - return ret; -} - -static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec) -{ - int ret = 0; - - dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec); - - ret = cx24116_lookup_fecmod(state, mod, fec); - - if(ret < 0) - return ret; - - state->dnxt.fec = fec; - state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val; - state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask; - dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__, - state->dnxt.fec_mask, state->dnxt.fec_val); - - return 0; -} - -static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate) -{ - dprintk("%s(%d)\n", __func__, rate); - - /* check if symbol rate is within limits */ - if ((rate > state->frontend.ops.info.symbol_rate_max) || - (rate < state->frontend.ops.info.symbol_rate_min)) { - dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate); - return -EOPNOTSUPP; - } - - state->dnxt.symbol_rate = rate; - dprintk("%s() symbol_rate = %d\n", __func__, rate); - - return 0; -} - -static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw); - -static int cx24116_firmware_ondemand(struct dvb_frontend* fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - const struct firmware *fw; - int ret = 0; - - dprintk("%s()\n",__func__); - - if (cx24116_readreg(state, 0x20) > 0) - { - - if (state->skip_fw_load) - return 0; - - /* Load firmware */ - /* request the firmware, this will block until someone uploads it */ - printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev); - printk("%s: Waiting for firmware upload(2)...\n", __func__); - if (ret) { - printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__); - return ret; - } - - /* Make sure we don't recurse back through here during loading */ - state->skip_fw_load = 1; - - ret = cx24116_load_firmware(fe, fw); - if (ret) - printk("%s: Writing firmware to device failed\n", __func__); - - release_firmware(fw); - - printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed"); - - /* Ensure firmware is always loaded if required */ - state->skip_fw_load = 0; - } - - return ret; -} - -/* Take a basic firmware command structure, format it and forward it for processing */ -static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i, ret; - - dprintk("%s()\n", __func__); - - /* Load the firmware if required */ - if ( (ret = cx24116_firmware_ondemand(fe)) != 0) - { - printk("%s(): Unable initialise the firmware\n", __func__); - return ret; - } - - /* Write the command */ - for(i = 0; i < cmd->len ; i++) - { - dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); - cx24116_writereg(state, i, cmd->args[i]); - } - - /* Start execution and wait for cmd to terminate */ - cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); - while( cx24116_readreg(state, CX24116_REG_EXECUTE) ) - { - msleep(10); - if(i++ > 64) - { - /* Avoid looping forever if the firmware does no respond */ - printk("%s() Firmware not responding\n", __func__); - return -EREMOTEIO; - } - } - return 0; -} - -static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - struct cx24116_state* state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int i, ret; - unsigned char vers[4]; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n" - ,fw->size - ,fw->data[0] - ,fw->data[1] - ,fw->data[ fw->size-2 ] - ,fw->data[ fw->size-1 ] - ); - - /* Toggle 88x SRST pin to reset demod */ - if (state->config->reset_device) - state->config->reset_device(fe); - - /* Begin the firmware load process */ - /* Prepare the demod, load the firmware, cleanup after load */ - - /* Init PLL */ - cx24116_writereg(state, 0xE5, 0x00); - cx24116_writereg(state, 0xF1, 0x08); - cx24116_writereg(state, 0xF2, 0x13); - - /* Start PLL */ - cx24116_writereg(state, 0xe0, 0x03); - cx24116_writereg(state, 0xe0, 0x00); - - /* Unknown */ - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); - - /* Unknown */ - cx24116_writereg(state, 0xF0, 0x03); - cx24116_writereg(state, 0xF4, 0x81); - cx24116_writereg(state, 0xF5, 0x00); - cx24116_writereg(state, 0xF6, 0x00); - - /* write the entire firmware as one transaction */ - cx24116_writeregN(state, 0xF7, fw->data, fw->size); - - cx24116_writereg(state, 0xF4, 0x10); - cx24116_writereg(state, 0xF0, 0x00); - cx24116_writereg(state, 0xF8, 0x06); - - /* Firmware CMD 10: VCO config */ - cmd.args[0x00] = CMD_SET_VCO; - cmd.args[0x01] = 0x05; - cmd.args[0x02] = 0xdc; - cmd.args[0x03] = 0xda; - cmd.args[0x04] = 0xae; - cmd.args[0x05] = 0xaa; - cmd.args[0x06] = 0x04; - cmd.args[0x07] = 0x9d; - cmd.args[0x08] = 0xfc; - cmd.args[0x09] = 0x06; - cmd.len= 0x0a; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00); - - /* Firmware CMD 14: Tuner config */ - cmd.args[0x00] = CMD_TUNERINIT; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x00; - cmd.len= 0x03; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - cx24116_writereg(state, 0xe5, 0x00); - - /* Firmware CMD 13: MPEG config */ - cmd.args[0x00] = CMD_MPEGCONFIG; - cmd.args[0x01] = 0x01; - cmd.args[0x02] = 0x75; - cmd.args[0x03] = 0x00; - if (state->config->mpg_clk_pos_pol) - cmd.args[0x04] = state->config->mpg_clk_pos_pol; - else - cmd.args[0x04] = 0x02; - cmd.args[0x05] = 0x00; - cmd.len= 0x06; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Firmware CMD 35: Get firmware version */ - cmd.args[0x00] = CMD_UPDFWVERS; - cmd.len= 0x02; - for(i=0; i<4; i++) { - cmd.args[0x01] = i; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX); - } - printk("%s: FW version %i.%i.%i.%i\n", __func__, - vers[0], vers[1], vers[2], vers[3]); - - return 0; -} - -static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - /* The isl6421 module will override this function in the fops. */ - dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__); - - return -EOPNOTSUPP; -} - -static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct cx24116_state *state = fe->demodulator_priv; - - int lock = cx24116_readreg(state, CX24116_REG_SSTATUS); - - dprintk("%s: status = 0x%02x\n", __func__, lock); - - *status = 0; - - if (lock & CX24116_HAS_SIGNAL) - *status |= FE_HAS_SIGNAL; - if (lock & CX24116_HAS_CARRIER) - *status |= FE_HAS_CARRIER; - if (lock & CX24116_HAS_VITERBI) - *status |= FE_HAS_VITERBI; - if (lock & CX24116_HAS_SYNCLOCK) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - return 0; -} - -static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) | - ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) | - ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) | - cx24116_readreg(state, CX24116_REG_BER0 ); - - return 0; -} - -/* TODO Determine function and scale appropriately */ -static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - u16 sig_reading; - - dprintk("%s()\n", __func__); - - /* Firmware CMD 19: Get AGC */ - cmd.args[0x00] = CMD_GETAGC; - cmd.len= 0x01; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) | - ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 ); - *signal_strength= 0 - sig_reading; - - dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength); - - return 0; -} - -/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ -static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) -{ - struct cx24116_state *state = fe->demodulator_priv; - u8 snr_reading; - static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ - 0x00000,0x0199A,0x03333,0x04ccD,0x06667, - 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667, - 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 }; - - dprintk("%s()\n", __func__); - - snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); - - if(snr_reading >= 0xa0 /* 100% */) - *snr = 0xffff; - else - *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] + - ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 ); - - dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, - snr_reading, *snr); - - return 0; -} - -/* The reelbox patches show the value in the registers represents - * ESNO, from 0->30db (values 0->300). We provide this value by - * default. - */ -static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 | - cx24116_readreg(state, CX24116_REG_QUALITY0); - - dprintk("%s: raw 0x%04x\n", __func__, *snr); - - return 0; -} - -static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) -{ - if (esno_snr == 1) - return cx24116_read_snr_esno(fe, snr); - else - return cx24116_read_snr_pct(fe, snr); -} - -static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) | - cx24116_readreg(state, CX24116_REG_UCB0); - - return 0; -} - -/* Overwrite the current tuning params, we are about to tune */ -static void cx24116_clone_params(struct dvb_frontend* fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); -} - -/* Wait for LNB */ -static int cx24116_wait_for_lnb(struct dvb_frontend* fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i; - - dprintk("%s() qstatus = 0x%02x\n", __func__, - cx24116_readreg(state, CX24116_REG_QSTATUS)); - - /* Wait for up to 300 ms */ - for(i = 0; i < 30 ; i++) { - if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) - return 0; - msleep(10); - } - - dprintk("%s(): LNB not ready\n", __func__); - - return -ETIMEDOUT; /* -EBUSY ? */ -} - -static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct cx24116_cmd cmd; - int ret; - - dprintk("%s(%d)\n", __func__, tone); - if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) { - printk("%s: Invalid, tone=%d\n", __func__, tone); - return -EINVAL; - } - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if(ret != 0) - return ret; - - /* Min delay time after DiSEqC send */ - msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - - /* This is always done before the tone is set */ - cmd.args[0x00] = CMD_SET_TONEPRE; - cmd.args[0x01] = 0x00; - cmd.len= 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Now we set the tone */ - cmd.args[0x00] = CMD_SET_TONE; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x00; - - switch (tone) { - case SEC_TONE_ON: - dprintk("%s: setting tone on\n", __func__); - cmd.args[0x03] = 0x01; - break; - case SEC_TONE_OFF: - dprintk("%s: setting tone off\n",__func__); - cmd.args[0x03] = 0x00; - break; - } - cmd.len= 0x04; - - /* Min delay time before DiSEqC send */ - msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - - return cx24116_cmd_execute(fe, &cmd); -} - -/* Initialise DiSEqC */ -static int cx24116_diseqc_init(struct dvb_frontend* fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - /* Firmware CMD 20: LNB/DiSEqC config */ - cmd.args[0x00] = CMD_LNBCONFIG; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x10; - cmd.args[0x03] = 0x00; - cmd.args[0x04] = 0x8f; - cmd.args[0x05] = 0x28; - cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; - cmd.args[0x07] = 0x01; - cmd.len= 0x08; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Prepare a DiSEqC command */ - state->dsec_cmd.args[0x00] = CMD_LNBSEND; - - /* DiSEqC burst */ - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; - - /* Unknown */ - state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; - state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; - state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */ - - /* DiSEqC message length */ - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; - - /* Command length */ - state->dsec_cmd.len= CX24116_DISEQC_MSGOFS; - - return 0; -} - -/* Send DiSEqC message with derived burst (hack) || previous burst */ -static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i, ret; - - /* Dump DiSEqC message */ - if (debug) { - printk("cx24116: %s(", __func__); - for(i = 0 ; i < d->msg_len ;) { - printk("0x%02x", d->msg[i]); - if(++i < d->msg_len) - printk(", "); - } - printk(") toneburst=%d\n", toneburst); - } - - /* Validate length */ - if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) - return -EINVAL; - - /* DiSEqC message */ - for (i = 0; i < d->msg_len; i++) - state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i]; - - /* DiSEqC message length */ - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; - - /* Command length */ - state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; - - /* DiSEqC toneburst */ - if(toneburst == CX24116_DISEQC_MESGCACHE) - /* Message is cached */ - return 0; - - else if(toneburst == CX24116_DISEQC_TONEOFF) - /* Message is sent without burst */ - state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; - - else if(toneburst == CX24116_DISEQC_TONECACHE) { - /* - * Message is sent with derived else cached burst - * - * WRITE PORT GROUP COMMAND 38 - * - * 0/A/A: E0 10 38 F0..F3 - * 1/B/B: E0 10 38 F4..F7 - * 2/C/A: E0 10 38 F8..FB - * 3/D/B: E0 10 38 FC..FF - * - * databyte[3]= 8421:8421 - * ABCD:WXYZ - * CLR :SET - * - * WX= PORT SELECT 0..3 (X=TONEBURST) - * Y = VOLTAGE (0=13V, 1=18V) - * Z = BAND (0=LOW, 1=HIGH(22K)) - */ - if(d->msg_len >= 4 && d->msg[2] == 0x38) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2); - if(debug) - dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]); - } - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if(ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - /* Command */ - ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if(ret != 0) - return ret; - /* - * Wait for send - * - * Eutelsat spec: - * >15ms delay + (XXX determine if FW does this, see set_tone) - * 13.5ms per byte + - * >15ms delay + - * 12.5ms burst + - * >15ms delay (XXX determine if FW does this, see set_tone) - */ - msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) ); - - return 0; -} - -/* Send DiSEqC burst */ -static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct cx24116_state *state = fe->demodulator_priv; - int ret; - - dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst); - - /* DiSEqC burst */ - if (burst == SEC_MINI_A) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; - else if(burst == SEC_MINI_B) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B; - else - return -EINVAL; - - /* DiSEqC toneburst */ - if(toneburst != CX24116_DISEQC_MESGCACHE) - /* Burst is cached */ - return 0; - - /* Burst is to be sent with cached message */ - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if(ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - /* Command */ - ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if(ret != 0) - return ret; - - /* - * Wait for send - * - * Eutelsat spec: - * >15ms delay + (XXX determine if FW does this, see set_tone) - * 13.5ms per byte + - * >15ms delay + - * 12.5ms burst + - * >15ms delay (XXX determine if FW does this, see set_tone) - */ - msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 ); - - return 0; -} - -static void cx24116_release(struct dvb_frontend* fe) -{ - struct cx24116_state* state = fe->demodulator_priv; - dprintk("%s\n",__func__); - kfree(state); -} - -static struct dvb_frontend_ops cx24116_ops; - -struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, - struct i2c_adapter* i2c) -{ - struct cx24116_state* state = NULL; - int ret; - - dprintk("%s\n",__func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); - if (state == NULL) { - printk("Unable to kmalloc\n"); - goto error1; - } - - /* setup the state */ - memset(state, 0, sizeof(struct cx24116_state)); - - state->config = config; - state->i2c = i2c; - - /* check if the demod is present */ - ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE); - if (ret != 0x0501) { - printk("Invalid probe, probably not a CX24116 device\n"); - goto error2; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error2: kfree(state); -error1: return NULL; -} -/* - * Initialise or wake up device - * - * Power config will reset and load initial firmware if required - */ -static int cx24116_initfe(struct dvb_frontend* fe) -{ - struct cx24116_state* state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - dprintk("%s()\n",__func__); - - /* Power on */ - cx24116_writereg(state, 0xe0, 0); - cx24116_writereg(state, 0xe1, 0); - cx24116_writereg(state, 0xea, 0); - - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 0; - cmd.len= 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if(ret != 0) - return ret; - - return cx24116_diseqc_init(fe); -} - -/* - * Put device to sleep - */ -static int cx24116_sleep(struct dvb_frontend* fe) -{ - struct cx24116_state* state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - dprintk("%s()\n",__func__); - - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 1; - cmd.len= 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if(ret != 0) - return ret; - - /* Power off (Shutdown clocks) */ - cx24116_writereg(state, 0xea, 0xff); - cx24116_writereg(state, 0xe1, 1); - cx24116_writereg(state, 0xe0, 1); - - return 0; -} - -static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -/* dvb-core told us to tune, the tv property cache will be complete, - * it's safe for is to pull values and use them for tuning purposes. - */ -static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct cx24116_cmd cmd; - fe_status_t tunerstat; - int i, status, ret, retune; - - dprintk("%s()\n",__func__); - - switch(c->delivery_system) { - case SYS_DVBS: - dprintk("%s: DVB-S delivery system selected\n",__func__); - - /* Only QPSK is supported for DVB-S */ - if(c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - /* Pilot doesn't exist in DVB-S, turn bit off */ - state->dnxt.pilot_val = CX24116_PILOT_OFF; - retune = 1; - - /* DVB-S only supports 0.35 */ - if(c->rolloff != ROLLOFF_35) { - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; - - case SYS_DVBS2: - dprintk("%s: DVB-S2 delivery system selected\n",__func__); - - /* - * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, - * but not hardware auto detection - */ - if(c->modulation != PSK_8 && c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - switch(c->pilot) { - case PILOT_AUTO: /* Not supported but emulated */ - retune = 2; /* Fall-through */ - case PILOT_OFF: - state->dnxt.pilot_val = CX24116_PILOT_OFF; - break; - case PILOT_ON: - state->dnxt.pilot_val = CX24116_PILOT_ON; - break; - default: - dprintk("%s: unsupported pilot mode selected (%d)\n", - __func__, c->pilot); - return -EOPNOTSUPP; - } - - switch(c->rolloff) { - case ROLLOFF_20: - state->dnxt.rolloff_val= CX24116_ROLLOFF_020; - break; - case ROLLOFF_25: - state->dnxt.rolloff_val= CX24116_ROLLOFF_025; - break; - case ROLLOFF_35: - state->dnxt.rolloff_val= CX24116_ROLLOFF_035; - break; - case ROLLOFF_AUTO: /* Rolloff must be explicit */ - default: - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - break; - - default: - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - state->dnxt.modulation = c->modulation; - state->dnxt.frequency = c->frequency; - state->dnxt.pilot = c->pilot; - state->dnxt.rolloff = c->rolloff; - - if ((ret = cx24116_set_inversion(state, c->inversion)) != 0) - return ret; - - /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ - if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0) - return ret; - - if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0) - return ret; - - /* discard the 'current' tuning parameters and prepare to tune */ - cx24116_clone_params(fe); - - dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation); - dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); - dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__, - state->dcur.pilot, state->dcur.pilot_val); - dprintk("%s: retune = %d\n", __func__, retune); - dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__, - state->dcur.rolloff, state->dcur.rolloff_val); - dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); - dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, - state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); - dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__, - state->dcur.inversion, state->dcur.inversion_val); - - /* This is also done in advise/acquire on HVR4000 but not on LITE */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* Set/Reset B/W */ - cmd.args[0x00] = CMD_BANDWIDTH; - cmd.args[0x01] = 0x01; - cmd.len= 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Prepare a tune request */ - cmd.args[0x00] = CMD_TUNEREQUEST; - - /* Frequency */ - cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16; - cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8; - cmd.args[0x03] = (state->dcur.frequency & 0x0000ff); - - /* Symbol Rate */ - cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8; - cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff); - - /* Automatic Inversion */ - cmd.args[0x06] = state->dcur.inversion_val; - - /* Modulation / FEC / Pilot */ - cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val; - - cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8; - cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff; - cmd.args[0x0a] = 0x00; - cmd.args[0x0b] = 0x00; - cmd.args[0x0c] = state->dcur.rolloff_val; - cmd.args[0x0d] = state->dcur.fec_mask; - - if (state->dcur.symbol_rate > 30000000) { - cmd.args[0x0e] = 0x04; - cmd.args[0x0f] = 0x00; - cmd.args[0x10] = 0x01; - cmd.args[0x11] = 0x77; - cmd.args[0x12] = 0x36; - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01); - } else { - cmd.args[0x0e] = 0x06; - cmd.args[0x0f] = 0x00; - cmd.args[0x10] = 0x00; - cmd.args[0x11] = 0xFA; - cmd.args[0x12] = 0x24; - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); - } - - cmd.len= 0x13; - - /* We need to support pilot and non-pilot tuning in the - * driver automatically. This is a workaround for because - * the demod does not support autodetect. - */ - do { - /* Reset status register */ - status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK; - cx24116_writereg(state, CX24116_REG_SSTATUS, status); - - /* Tune */ - ret = cx24116_cmd_execute(fe, &cmd); - if( ret != 0 ) - break; - - /* - * Wait for up to 500 ms before retrying - * - * If we are able to tune then generally it occurs within 100ms. - * If it takes longer, try a different toneburst setting. - */ - for(i = 0; i < 50 ; i++) { - cx24116_read_status(fe, &tunerstat); - status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); - if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { - dprintk("%s: Tuned\n",__func__); - goto tuned; - } - msleep(10); - } - - dprintk("%s: Not tuned\n",__func__); - - /* Toggle pilot bit when in auto-pilot */ - if(state->dcur.pilot == PILOT_AUTO) - cmd.args[0x07] ^= CX24116_PILOT_ON; - } - while(--retune); - -tuned: /* Set/Reset B/W */ - cmd.args[0x00] = CMD_BANDWIDTH; - cmd.args[0x01] = 0x00; - cmd.len= 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - return ret; -} - -static struct dvb_frontend_ops cx24116_ops = { - - .info = { - .name = "Conexant CX24116/CX24118", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24116_release, - - .init = cx24116_initfe, - .sleep = cx24116_sleep, - .read_status = cx24116_read_status, - .read_ber = cx24116_read_ber, - .read_signal_strength = cx24116_read_signal_strength, - .read_snr = cx24116_read_snr, - .read_ucblocks = cx24116_read_ucblocks, - .set_tone = cx24116_set_tone, - .set_voltage = cx24116_set_voltage, - .diseqc_send_master_cmd = cx24116_send_diseqc_msg, - .diseqc_send_burst = cx24116_diseqc_send_burst, - - .set_property = cx24116_set_property, - .get_property = cx24116_get_property, - .set_frontend = cx24116_set_frontend, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -module_param(toneburst, int, 0644); -MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)"); - -module_param(esno_snr, int, 0644); -MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)"); - -MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx24116_attach); diff --git a/trunk/drivers/media/dvb/frontends/cx24116.h b/trunk/drivers/media/dvb/frontends/cx24116.h deleted file mode 100644 index 8dbcec268394..000000000000 --- a/trunk/drivers/media/dvb/frontends/cx24116.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver - - Copyright (C) 2006 Steven Toth - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef CX24116_H -#define CX24116_H - -#include - -struct cx24116_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); - - /* Need to reset device during firmware loading */ - int (*reset_device)(struct dvb_frontend* fe); - - /* Need to set MPEG parameters */ - u8 mpg_clk_pos_pol:0x02; -}; - -#if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) -extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); - return NULL; -} -#endif // CONFIG_DVB_CX24116 - -#endif /* CX24116_H */ diff --git a/trunk/drivers/media/dvb/frontends/dib0070.h b/trunk/drivers/media/dvb/frontends/dib0070.h index 21f2c5161af4..3eedfdf505bc 100644 --- a/trunk/drivers/media/dvb/frontends/dib0070.h +++ b/trunk/drivers/media/dvb/frontends/dib0070.h @@ -41,7 +41,6 @@ struct dib0070_config { extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); -extern u16 dib0070_wbd_offset(struct dvb_frontend *); #else static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, @@ -50,14 +49,9 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } - -static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} #endif extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); +extern u16 dib0070_wbd_offset(struct dvb_frontend *); #endif diff --git a/trunk/drivers/media/dvb/frontends/dib7000m.c b/trunk/drivers/media/dvb/frontends/dib7000m.c index 0109720353bd..5f1375e30dfc 100644 --- a/trunk/drivers/media/dvb/frontends/dib7000m.c +++ b/trunk/drivers/media/dvb/frontends/dib7000m.c @@ -1284,10 +1284,7 @@ struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum di } EXPORT_SYMBOL(dib7000m_get_i2c_master); -#if 0 -/* used with some prototype boards */ -int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, - u8 default_addr, struct dib7000m_config cfg[]) +int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000m_config cfg[]) { struct dib7000m_state st = { .i2c_adap = i2c }; int k = 0; @@ -1332,7 +1329,6 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, return 0; } EXPORT_SYMBOL(dib7000m_i2c_enumeration); -#endif static struct dvb_frontend_ops dib7000m_ops; struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) diff --git a/trunk/drivers/media/dvb/frontends/dib7000p.c b/trunk/drivers/media/dvb/frontends/dib7000p.c index 8217e5b38f47..1a0142e0d741 100644 --- a/trunk/drivers/media/dvb/frontends/dib7000p.c +++ b/trunk/drivers/media/dvb/frontends/dib7000p.c @@ -1333,8 +1333,7 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, /* Ensure the output mode remains at the previous default if it's * not specifically set by the caller. */ - if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && - (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) + if (st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) st->cfg.output_mode = OUTMODE_MPEG2_FIFO; demod = &st->demod; diff --git a/trunk/drivers/media/dvb/frontends/dib7000p.h b/trunk/drivers/media/dvb/frontends/dib7000p.h index 3e8126857127..07c4d12ed5b7 100644 --- a/trunk/drivers/media/dvb/frontends/dib7000p.h +++ b/trunk/drivers/media/dvb/frontends/dib7000p.h @@ -41,14 +41,6 @@ struct dib7000p_config { extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); -extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, - enum dibx000_i2c_interface, - int); -extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib7000p_config cfg[]); -extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); -extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); #else static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, @@ -57,36 +49,13 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } - -static inline -struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, - enum dibx000_i2c_interface i, int x) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib7000p_config cfg[]) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - -extern int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - -extern int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} #endif +extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); + +extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); +extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); +extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); #endif diff --git a/trunk/drivers/media/dvb/frontends/drx397xD.c b/trunk/drivers/media/dvb/frontends/drx397xD.c index b9ca5c8d2dd9..3cbed874a6f8 100644 --- a/trunk/drivers/media/dvb/frontends/drx397xD.c +++ b/trunk/drivers/media/dvb/frontends/drx397xD.c @@ -38,32 +38,35 @@ static const char mod_name[] = "drx397xD"; #define F_SET_0D0h 1 #define F_SET_0D4h 2 -enum fw_ix { +typedef enum fw_ix { #define _FW_ENTRY(a, b) b #include "drx397xD_fw.h" -}; +} fw_ix_t; /* chip specifics */ struct drx397xD_state { struct i2c_adapter *i2c; struct dvb_frontend frontend; struct drx397xD_config config; - enum fw_ix chip_rev; + fw_ix_t chip_rev; int flags; u32 bandwidth_parm; /* internal bandwidth conversions */ u32 f_osc; /* w90: actual osc frequency [Hz] */ }; -/* Firmware */ +/******************************************************************************* + * Firmware + ******************************************************************************/ + static const char *blob_name[] = { #define _BLOB_ENTRY(a, b) a #include "drx397xD_fw.h" }; -enum blob_ix { +typedef enum blob_ix { #define _BLOB_ENTRY(a, b) b #include "drx397xD_fw.h" -}; +} blob_ix_t; static struct { const char *name; @@ -82,7 +85,7 @@ static struct { }; /* use only with writer lock aquired */ -static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix) +static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix) { memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); if (fw[ix].file) @@ -91,9 +94,9 @@ static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix) static void drx_release_fw(struct drx397xD_state *s) { - enum fw_ix ix = s->chip_rev; + fw_ix_t ix = s->chip_rev; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); write_lock(&fw[ix].lock); if (fw[ix].refcnt) { @@ -104,13 +107,13 @@ static void drx_release_fw(struct drx397xD_state *s) write_unlock(&fw[ix].lock); } -static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) +static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) { const u8 *data; size_t size, len; int i = 0, j, rc = -EINVAL; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); if (ix < 0 || ix >= ARRAY_SIZE(fw)) return -EINVAL; @@ -172,34 +175,32 @@ static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) goto exit_corrupt; } } while (i < size); - -exit_corrupt: + exit_corrupt: printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); -exit_err: + exit_err: _drx_release_fw(s, ix); fw[ix].refcnt--; -exit_ok: + exit_ok: fw[ix].refcnt++; write_unlock(&fw[ix].lock); - return rc; } -/* i2c bus IO */ -static int write_fw(struct drx397xD_state *s, enum blob_ix ix) +/******************************************************************************* + * i2c bus IO + ******************************************************************************/ + +static int write_fw(struct drx397xD_state *s, blob_ix_t ix) { + struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 }; const u8 *data; int len, rc = 0, i = 0; - struct i2c_msg msg = { - .addr = s->config.demod_address, - .flags = 0 - }; if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { - pr_debug("%s drx_fw_ix_t out of range\n", __func__); + pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__); return -EINVAL; } - pr_debug("%s %s\n", __func__, blob_name[ix]); + pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]); read_lock(&fw[s->chip_rev].lock); data = fw[s->chip_rev].data[ix]; @@ -228,33 +229,33 @@ static int write_fw(struct drx397xD_state *s, enum blob_ix ix) goto exit_rc; } } -exit_rc: + exit_rc: read_unlock(&fw[s->chip_rev].lock); - return 0; } /* Function is not endian safe, use the RD16 wrapper below */ -static int _read16(struct drx397xD_state *s, __le32 i2c_adr) +static int _read16(struct drx397xD_state *s, u32 i2c_adr) { int rc; u8 a[4]; - __le16 v; + u16 v; struct i2c_msg msg[2] = { { - .addr = s->config.demod_address, - .flags = 0, - .buf = a, - .len = sizeof(a) - }, { - .addr = s->config.demod_address, - .flags = I2C_M_RD, - .buf = (u8 *)&v, - .len = sizeof(v) - } + .addr = s->config.demod_address, + .flags = 0, + .buf = a, + .len = sizeof(a) + } + , { + .addr = s->config.demod_address, + .flags = I2C_M_RD, + .buf = (u8 *) & v, + .len = sizeof(v) + } }; - *(__le32 *) a = i2c_adr; + *(u32 *) a = i2c_adr; rc = i2c_transfer(s->i2c, msg, 2); if (rc != 2) @@ -264,7 +265,7 @@ static int _read16(struct drx397xD_state *s, __le32 i2c_adr) } /* Function is not endian safe, use the WR16.. wrappers below */ -static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val) +static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) { u8 a[6]; int rc; @@ -275,28 +276,28 @@ static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val) .len = sizeof(a) }; - *(__le32 *)a = i2c_adr; - *(__le16 *)&a[4] = val; + *(u32 *) a = i2c_adr; + *(u16 *) & a[4] = val; rc = i2c_transfer(s->i2c, &msg, 1); if (rc != 1) return -EIO; - return 0; } -#define WR16(ss, adr, val) \ +#define WR16(ss,adr, val) \ _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) -#define WR16_E0(ss, adr, val) \ +#define WR16_E0(ss,adr, val) \ _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) -#define RD16(ss, adr) \ +#define RD16(ss,adr) \ _read16(ss, I2C_ADR_C0(adr)) -#define EXIT_RC(cmd) \ - if ((rc = (cmd)) < 0) \ - goto exit_rc +#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc + +/******************************************************************************* + * Tuner callback + ******************************************************************************/ -/* Tuner callback */ static int PLL_Set(struct drx397xD_state *s, struct dvb_frontend_parameters *fep, int *df_tuner) { @@ -304,7 +305,7 @@ static int PLL_Set(struct drx397xD_state *s, u32 f_tuner, f = fep->frequency; int rc; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || (f < s->frontend.ops.tuner_ops.info.frequency_min)) @@ -324,26 +325,28 @@ static int PLL_Set(struct drx397xD_state *s, return rc; *df_tuner = f_tuner - f; - pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f, + pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f, f_tuner); return 0; } -/* Demodulator helper functions */ +/******************************************************************************* + * Demodulator helper functions + ******************************************************************************/ + static int SC_WaitForReady(struct drx397xD_state *s) { int cnt = 1000; int rc; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); while (cnt--) { rc = RD16(s, 0x820043); if (rc == 0) return 0; } - return -1; } @@ -351,14 +354,13 @@ static int SC_SendCommand(struct drx397xD_state *s, int cmd) { int rc; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); WR16(s, 0x820043, cmd); SC_WaitForReady(s); rc = RD16(s, 0x820042); if ((rc & 0xffff) == 0xffff) return -1; - return 0; } @@ -366,7 +368,7 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd) { int rc, cnt = 1000; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); rc = WR16(s, 0x420032, cmd); if (rc < 0) @@ -381,24 +383,22 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd) if (rc < 0) return rc; } while (--cnt); - return rc; } static int HI_CfgCommand(struct drx397xD_state *s) { - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); WR16(s, 0x420033, 0x3973); - WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */ - WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */ + WR16(s, 0x420034, s->config.w50); // code 4, log 4 + WR16(s, 0x420035, s->config.w52); // code 15, log 9 WR16(s, 0x420036, s->config.demod_address << 1); - WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */ - /* WR16(s, 0x420033, 0x3973); */ + WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1 +// WR16(s, 0x420033, 0x3973); if ((s->config.w56 & 8) == 0) return HI_Command(s, 3); - return WR16(s, 0x420032, 0x3); } @@ -419,7 +419,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) u16 w0C = agc->w0C; int quot, rem, i, rc = -EINVAL; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); if (agc->w04 > 0x3ff) goto exit_rc; @@ -468,7 +468,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) i = slowIncrDecLUT_15272[rem / 28]; EXIT_RC(WR16(s, 0x0c2002b, i)); rc = WR16(s, 0x0c2002c, i); -exit_rc: + exit_rc: return rc; } @@ -478,7 +478,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) u16 w06 = agc->w06; int rc = -1; - pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06); + pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06); if (w04 > 0x3ff) goto exit_rc; @@ -498,7 +498,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) rc &= ~2; break; case 0: - /* loc_8000659 */ + // loc_8000659 s->config.w9C &= ~2; EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); EXIT_RC(RD16(s, 0x0c20010)); @@ -522,8 +522,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) rc |= 2; } rc = WR16(s, 0x0c20013, rc); - -exit_rc: + exit_rc: return rc; } @@ -555,7 +554,7 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s) int lockstat; u32 clk, clk_limit; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); if (s->config.d5C == 0) { EXIT_RC(WR16(s, 0x08200e8, 0x010)); @@ -599,12 +598,11 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s) if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { s->f_osc = clk; - pr_debug("%s: osc %d %d [Hz]\n", __func__, + pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__, s->config.f_osc * 1000, clk - s->config.f_osc * 1000); } rc = WR16(s, 0x08200e8, 0); - -exit_rc: + exit_rc: return rc; } @@ -612,7 +610,7 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) { int rc, si, bp; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); si = s->config.wA0; if (s->config.w98 == 0) { @@ -622,17 +620,17 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) si &= ~1; bp = 0x200; } - if (s->config.w9A == 0) + if (s->config.w9A == 0) { si |= 0x80; - else + } else { si &= ~0x80; + } EXIT_RC(WR16(s, 0x2150045, 0)); EXIT_RC(WR16(s, 0x2150010, si)); EXIT_RC(WR16(s, 0x2150011, bp)); rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); - -exit_rc: + exit_rc: return rc; } @@ -648,7 +646,7 @@ static int drx_tune(struct drx397xD_state *s, int rc, df_tuner; int a, b, c, d; - pr_debug("%s %d\n", __func__, s->config.d60); + pr_debug("%s %d\n", __FUNCTION__, s->config.d60); if (s->config.d60 != 2) goto set_tuner; @@ -660,7 +658,7 @@ static int drx_tune(struct drx397xD_state *s, rc = ConfigureMPEGOutput(s, 0); if (rc < 0) goto set_tuner; -set_tuner: + set_tuner: rc = PLL_Set(s, fep, &df_tuner); if (rc < 0) { @@ -837,16 +835,16 @@ static int drx_tune(struct drx397xD_state *s, rc = WR16(s, 0x2010012, 0); if (rc < 0) goto exit_rc; - /* QPSK QAM16 QAM64 */ - ebx = 0x19f; /* 62 */ - ebp = 0x1fb; /* 15 */ - v20 = 0x16a; /* 62 */ - v1E = 0x195; /* 62 */ - v16 = 0x1bb; /* 15 */ - v14 = 0x1ef; /* 15 */ - v12 = 5; /* 16 */ - v10 = 5; /* 16 */ - v0E = 5; /* 16 */ + // QPSK QAM16 QAM64 + ebx = 0x19f; // 62 + ebp = 0x1fb; // 15 + v20 = 0x16a; // 62 + v1E = 0x195; // 62 + v16 = 0x1bb; // 15 + v14 = 0x1ef; // 15 + v12 = 5; // 16 + v10 = 5; // 16 + v0E = 5; // 16 } switch (fep->u.ofdm.constellation) { @@ -999,17 +997,17 @@ static int drx_tune(struct drx397xD_state *s, case BANDWIDTH_8_MHZ: /* 0 */ case BANDWIDTH_AUTO: rc = WR16(s, 0x0c2003f, 0x32); - s->bandwidth_parm = ebx = 0x8b8249; + s->bandwidth_parm = ebx = 0x8b8249; // 9142857 edx = 0; break; case BANDWIDTH_7_MHZ: rc = WR16(s, 0x0c2003f, 0x3b); - s->bandwidth_parm = ebx = 0x7a1200; + s->bandwidth_parm = ebx = 0x7a1200; // 8000000 edx = 0x4807; break; case BANDWIDTH_6_MHZ: rc = WR16(s, 0x0c2003f, 0x47); - s->bandwidth_parm = ebx = 0x68a1b6; + s->bandwidth_parm = ebx = 0x68a1b6; // 6857142 edx = 0x0f07; break; }; @@ -1062,6 +1060,8 @@ static int drx_tune(struct drx397xD_state *s, WR16(s, 0x0820040, 1); SC_SendCommand(s, 1); +// rc = WR16(s, 0x2150000, 1); +// if (rc < 0) goto exit_rc; rc = WR16(s, 0x2150000, 2); rc = WR16(s, 0x2150016, a); @@ -1069,8 +1069,7 @@ static int drx_tune(struct drx397xD_state *s, rc = WR16(s, 0x2150036, 0); rc = WR16(s, 0x2150000, 1); s->config.d60 = 2; - -exit_rc: + exit_rc: return rc; } @@ -1083,7 +1082,7 @@ static int drx397x_init(struct dvb_frontend *fe) struct drx397xD_state *s = fe->demodulator_priv; int rc; - pr_debug("%s\n", __func__); + pr_debug("%s\n", __FUNCTION__); s->config.rfagc.d00 = 2; /* 0x7c */ s->config.rfagc.w04 = 0; @@ -1103,18 +1102,18 @@ static int drx397x_init(struct dvb_frontend *fe) /* HI_CfgCommand */ s->config.w50 = 4; - s->config.w52 = 9; + s->config.w52 = 9; // 0xf; - s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ - s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ - s->config.w92 = 12000; + s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ + s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ + s->config.w92 = 12000; // 20000; s->config.w9C = 0x000e; s->config.w9E = 0x0000; /* ConfigureMPEGOutput params */ s->config.wA0 = 4; - s->config.w98 = 1; + s->config.w98 = 1; // 0; s->config.w9A = 1; /* get chip revision */ @@ -1249,7 +1248,7 @@ static int drx397x_init(struct dvb_frontend *fe) rc = WR16(s, 0x0c20012, 1); } -write_DRXD_InitFE_1: + write_DRXD_InitFE_1: rc = write_fw(s, DRXD_InitFE_1); if (rc < 0) @@ -1312,8 +1311,7 @@ static int drx397x_init(struct dvb_frontend *fe) s->config.d5C = 0; s->config.d60 = 1; s->config.d48 = 1; - -error: + error: return rc; } @@ -1328,8 +1326,7 @@ static int drx397x_set_frontend(struct dvb_frontend *fe, { struct drx397xD_state *s = fe->demodulator_priv; - s->config.s20d24 = 1; - + s->config.s20d24 = 1; // 0; return drx_tune(s, params); } @@ -1340,16 +1337,18 @@ static int drx397x_get_tune_settings(struct dvb_frontend *fe, fe_tune_settings->min_delay_ms = 10000; fe_tune_settings->step_size = 0; fe_tune_settings->max_drift = 0; - return 0; } -static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status) +static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) { struct drx397xD_state *s = fe->demodulator_priv; int lockstat; GetLockStatus(s, &lockstat); + /* TODO */ +// if (lockstat & 1) +// CorrectSysClockDeviation(s); *status = 0; if (lockstat & 2) { @@ -1357,8 +1356,9 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status) ConfigureMPEGOutput(s, 1); *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; } - if (lockstat & 4) + if (lockstat & 4) { *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + } return 0; } @@ -1366,18 +1366,16 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status) static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) { *ber = 0; - return 0; } -static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr) +static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr) { *snr = 0; - return 0; } -static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength) { struct drx397xD_state *s = fe->demodulator_priv; int rc; @@ -1403,7 +1401,6 @@ static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) * The following does the same but with less rounding errors: */ *strength = ~(7720 + (rc * 30744 >> 10)); - return 0; } @@ -1411,7 +1408,6 @@ static int drx397x_read_ucblocks(struct dvb_frontend *fe, unsigned int *ucblocks) { *ucblocks = 0; - return 0; } @@ -1440,22 +1436,22 @@ static struct dvb_frontend_ops drx397x_ops = { .frequency_max = 855250000, .frequency_stepsize = 166667, .frequency_tolerance = 0, - .caps = /* 0x0C01B2EAE */ - FE_CAN_FEC_1_2 | /* = 0x2, */ - FE_CAN_FEC_2_3 | /* = 0x4, */ - FE_CAN_FEC_3_4 | /* = 0x8, */ - FE_CAN_FEC_5_6 | /* = 0x20, */ - FE_CAN_FEC_7_8 | /* = 0x80, */ - FE_CAN_FEC_AUTO | /* = 0x200, */ - FE_CAN_QPSK | /* = 0x400, */ - FE_CAN_QAM_16 | /* = 0x800, */ - FE_CAN_QAM_64 | /* = 0x2000, */ - FE_CAN_QAM_AUTO | /* = 0x10000, */ - FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */ - FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */ - FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */ - FE_CAN_RECOVER | /* = 0x40000000, */ - FE_CAN_MUTE_TS /* = 0x80000000 */ + .caps = /* 0x0C01B2EAE */ + FE_CAN_FEC_1_2 | // = 0x2, + FE_CAN_FEC_2_3 | // = 0x4, + FE_CAN_FEC_3_4 | // = 0x8, + FE_CAN_FEC_5_6 | // = 0x20, + FE_CAN_FEC_7_8 | // = 0x80, + FE_CAN_FEC_AUTO | // = 0x200, + FE_CAN_QPSK | // = 0x400, + FE_CAN_QAM_16 | // = 0x800, + FE_CAN_QAM_64 | // = 0x2000, + FE_CAN_QAM_AUTO | // = 0x10000, + FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000, + FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000, + FE_CAN_HIERARCHY_AUTO | // = 0x100000, + FE_CAN_RECOVER | // = 0x40000000, + FE_CAN_MUTE_TS // = 0x80000000 }, .release = drx397x_release, @@ -1476,35 +1472,33 @@ static struct dvb_frontend_ops drx397x_ops = { struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, struct i2c_adapter *i2c) { - struct drx397xD_state *state; + struct drx397xD_state *s = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); - if (!state) + s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); + if (s == NULL) goto error; /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct drx397xD_config)); + s->i2c = i2c; + memcpy(&s->config, config, sizeof(struct drx397xD_config)); /* check if the demod is there */ - if (RD16(state, 0x2410019) < 0) + if (RD16(s, 0x2410019) < 0) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &drx397x_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); + memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops)); + s->frontend.demodulator_priv = s; + return &s->frontend; + error: + kfree(s); return NULL; } -EXPORT_SYMBOL(drx397xD_attach); MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); MODULE_AUTHOR("Henk Vergonet"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(drx397xD_attach); diff --git a/trunk/drivers/media/dvb/frontends/drx397xD.h b/trunk/drivers/media/dvb/frontends/drx397xD.h index ba05d17290c6..ddc7a07971b7 100644 --- a/trunk/drivers/media/dvb/frontends/drx397xD.h +++ b/trunk/drivers/media/dvb/frontends/drx397xD.h @@ -28,7 +28,7 @@ #define DRX_F_OFFSET 36000000 #define I2C_ADR_C0(x) \ -( cpu_to_le32( \ +( (u32)cpu_to_le32( \ (u32)( \ (((u32)(x) & (u32)0x000000ffUL) ) | \ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ @@ -38,7 +38,7 @@ ) #define I2C_ADR_E0(x) \ -( cpu_to_le32( \ +( (u32)cpu_to_le32( \ (u32)( \ (((u32)(x) & (u32)0x000000ffUL) ) | \ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ @@ -122,7 +122,7 @@ extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return NULL; } #endif /* CONFIG_DVB_DRX397XD */ diff --git a/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c b/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c index db8a937cc630..fed09dfb2b7c 100644 --- a/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c @@ -75,10 +75,9 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops->tuner_ops->set_params) { + fe->ops->tuner_ops->set_params(fe, p); + if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); } return 0; @@ -132,7 +131,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; -struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) +struct dvb_frontend* dvb_dummy_fe_qpsk_attach() { struct dvb_dummy_fe_state* state = NULL; @@ -152,7 +151,7 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) static struct dvb_frontend_ops dvb_dummy_fe_qam_ops; -struct dvb_frontend *dvb_dummy_fe_qam_attach(void) +struct dvb_frontend* dvb_dummy_fe_qam_attach() { struct dvb_dummy_fe_state* state = NULL; diff --git a/trunk/drivers/media/dvb/frontends/eds1547.h b/trunk/drivers/media/dvb/frontends/eds1547.h deleted file mode 100644 index fa79b7c83dd2..000000000000 --- a/trunk/drivers/media/dvb/frontends/eds1547.h +++ /dev/null @@ -1,133 +0,0 @@ -/* eds1547.h Earda EDS-1547 tuner support -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ - -#ifndef EDS1547 -#define EDS1547 - -static u8 stv0288_earda_inittab[] = { - 0x01, 0x57, - 0x02, 0x20, - 0x03, 0x8e, - 0x04, 0x8e, - 0x05, 0x12, - 0x06, 0x00, - 0x07, 0x00, - 0x09, 0x00, - 0x0a, 0x04, - 0x0b, 0x00, - 0x0c, 0x00, - 0x0d, 0x00, - 0x0e, 0xd4, - 0x0f, 0x30, - 0x11, 0x44, - 0x12, 0x03, - 0x13, 0x48, - 0x14, 0x84, - 0x15, 0x45, - 0x16, 0xb7, - 0x17, 0x9c, - 0x18, 0x00, - 0x19, 0xa6, - 0x1a, 0x88, - 0x1b, 0x8f, - 0x1c, 0xf0, - 0x20, 0x0b, - 0x21, 0x54, - 0x22, 0x00, - 0x23, 0x00, - 0x2b, 0xff, - 0x2c, 0xf7, - 0x30, 0x00, - 0x31, 0x1e, - 0x32, 0x14, - 0x33, 0x0f, - 0x34, 0x09, - 0x35, 0x0c, - 0x36, 0x05, - 0x37, 0x2f, - 0x38, 0x16, - 0x39, 0xbd, - 0x3a, 0x00, - 0x3b, 0x13, - 0x3c, 0x11, - 0x3d, 0x30, - 0x40, 0x63, - 0x41, 0x04, - 0x42, 0x60, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x4a, 0x00, - 0x50, 0x10, - 0x51, 0x36, - 0x52, 0x09, - 0x53, 0x94, - 0x54, 0x62, - 0x55, 0x29, - 0x56, 0x64, - 0x57, 0x2b, - 0x58, 0x54, - 0x59, 0x86, - 0x5a, 0x00, - 0x5b, 0x9b, - 0x5c, 0x08, - 0x5d, 0x7f, - 0x5e, 0x00, - 0x5f, 0xff, - 0x70, 0x00, - 0x71, 0x00, - 0x72, 0x00, - 0x74, 0x00, - 0x75, 0x00, - 0x76, 0x00, - 0x81, 0x00, - 0x82, 0x3f, - 0x83, 0x3f, - 0x84, 0x00, - 0x85, 0x00, - 0x88, 0x00, - 0x89, 0x00, - 0x8a, 0x00, - 0x8b, 0x00, - 0x8c, 0x00, - 0x90, 0x00, - 0x91, 0x00, - 0x92, 0x00, - 0x93, 0x00, - 0x94, 0x1c, - 0x97, 0x00, - 0xa0, 0x48, - 0xa1, 0x00, - 0xb0, 0xb8, - 0xb1, 0x3a, - 0xb2, 0x10, - 0xb3, 0x82, - 0xb4, 0x80, - 0xb5, 0x82, - 0xb6, 0x82, - 0xb7, 0x82, - 0xb8, 0x20, - 0xb9, 0x00, - 0xf0, 0x00, - 0xf1, 0x00, - 0xf2, 0xc0, - 0xff,0xff, -}; - -static struct stv0288_config earda_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - .inittab = stv0288_earda_inittab, -}; - -#endif diff --git a/trunk/drivers/media/dvb/frontends/lgs8gl5.c b/trunk/drivers/media/dvb/frontends/lgs8gl5.c deleted file mode 100644 index 855852fddf22..000000000000 --- a/trunk/drivers/media/dvb/frontends/lgs8gl5.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver - - Copyright (C) 2008 Sirius International (Hong Kong) Limited - Timothy Lee - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include -#include -#include "dvb_frontend.h" -#include "lgs8gl5.h" - - -#define REG_RESET 0x02 -#define REG_RESET_OFF 0x01 -#define REG_03 0x03 -#define REG_04 0x04 -#define REG_07 0x07 -#define REG_09 0x09 -#define REG_0A 0x0a -#define REG_0B 0x0b -#define REG_0C 0x0c -#define REG_37 0x37 -#define REG_STRENGTH 0x4b -#define REG_STRENGTH_MASK 0x7f -#define REG_STRENGTH_CARRIER 0x80 -#define REG_INVERSION 0x7c -#define REG_INVERSION_ON 0x80 -#define REG_7D 0x7d -#define REG_7E 0x7e -#define REG_A2 0xa2 -#define REG_STATUS 0xa4 -#define REG_STATUS_SYNC 0x04 -#define REG_STATUS_LOCK 0x01 - - -struct lgs8gl5_state { - struct i2c_adapter *i2c; - const struct lgs8gl5_config *config; - struct dvb_frontend frontend; -}; - - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "lgs8gl5: " args); \ - } while (0) - - -/* Writes into demod's register */ -static int -lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = {reg, data}; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n", - __func__, reg, data, ret); - return (ret != 1) ? -1 : 0; -} - - -/* Reads from demod's register */ -static int -lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg) -{ - int ret; - u8 b0[] = {reg}; - u8 b1[] = {0}; - struct i2c_msg msg[2] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, - { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - return -EIO; - - return b1[0]; -} - - -static int -lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - lgs8gl5_read_reg(state, reg); - lgs8gl5_write_reg(state, reg, data); - return 0; -} - - -/* Writes into alternate device's register */ -/* TODO: Find out what that device is for! */ -static int -lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - int ret; - u8 b0[] = {reg}; - u8 b1[] = {0}; - u8 b2[] = {reg, data}; - struct i2c_msg msg[3] = { - { - .addr = state->config->demod_address + 2, - .flags = 0, - .buf = b0, - .len = 1 - }, - { - .addr = state->config->demod_address + 2, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - }, - { - .addr = state->config->demod_address + 2, - .flags = 0, - .buf = b2, - .len = 2 - }, - }; - - ret = i2c_transfer(state->i2c, msg, 3); - return (ret != 3) ? -1 : 0; -} - - -static void -lgs8gl5_soft_reset(struct lgs8gl5_state *state) -{ - u8 val; - - dprintk("%s\n", __func__); - - val = lgs8gl5_read_reg(state, REG_RESET); - lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF); - lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF); - msleep(5); -} - - -/* Starts demodulation */ -static void -lgs8gl5_start_demod(struct lgs8gl5_state *state) -{ - u8 val; - int n; - - dprintk("%s\n", __func__); - - lgs8gl5_update_alt_reg(state, 0xc2, 0x28); - lgs8gl5_soft_reset(state); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_write_reg(state, REG_09, 0x0e); - lgs8gl5_write_reg(state, REG_0A, 0xe5); - lgs8gl5_write_reg(state, REG_0B, 0x35); - lgs8gl5_write_reg(state, REG_0C, 0x30); - - lgs8gl5_update_reg(state, REG_03, 0x00); - lgs8gl5_update_reg(state, REG_7E, 0x01); - lgs8gl5_update_alt_reg(state, 0xc5, 0x00); - lgs8gl5_update_reg(state, REG_04, 0x02); - lgs8gl5_update_reg(state, REG_37, 0x01); - lgs8gl5_soft_reset(state); - - /* Wait for carrier */ - for (n = 0; n < 10; n++) { - val = lgs8gl5_read_reg(state, REG_STRENGTH); - dprintk("Wait for carrier[%d] 0x%02X\n", n, val); - if (val & REG_STRENGTH_CARRIER) - break; - msleep(4); - } - if (!(val & REG_STRENGTH_CARRIER)) - return; - - /* Wait for lock */ - for (n = 0; n < 20; n++) { - val = lgs8gl5_read_reg(state, REG_STATUS); - dprintk("Wait for lock[%d] 0x%02X\n", n, val); - if (val & REG_STATUS_LOCK) - break; - msleep(12); - } - if (!(val & REG_STATUS_LOCK)) - return; - - lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2)); - lgs8gl5_soft_reset(state); -} - - -static int -lgs8gl5_init(struct dvb_frontend *fe) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - lgs8gl5_update_alt_reg(state, 0xc2, 0x28); - lgs8gl5_soft_reset(state); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_write_reg(state, REG_09, 0x0e); - lgs8gl5_write_reg(state, REG_0A, 0xe5); - lgs8gl5_write_reg(state, REG_0B, 0x35); - lgs8gl5_write_reg(state, REG_0C, 0x30); - - return 0; -} - - -static int -lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - u8 flags = lgs8gl5_read_reg(state, REG_STATUS); - - *status = 0; - - if ((level & REG_STRENGTH_MASK) > 0) - *status |= FE_HAS_SIGNAL; - if (level & REG_STRENGTH_CARRIER) - *status |= FE_HAS_CARRIER; - if (flags & REG_STATUS_SYNC) - *status |= FE_HAS_SYNC; - if (flags & REG_STATUS_LOCK) - *status |= FE_HAS_LOCK; - - return 0; -} - - -static int -lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - *ber = 0; - - return 0; -} - - -static int -lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - *signal_strength = (level & REG_STRENGTH_MASK) << 8; - - return 0; -} - - -static int -lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - *snr = (level & REG_STRENGTH_MASK) << 8; - - return 0; -} - - -static int -lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - - return 0; -} - - -static int -lgs8gl5_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* lgs8gl5_set_inversion(state, p->inversion); */ - - lgs8gl5_start_demod(state); - - return 0; -} - - -static int -lgs8gl5_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 inv = lgs8gl5_read_reg(state, REG_INVERSION); - struct dvb_ofdm_parameters *o = &p->u.ofdm; - - p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF; - - o->code_rate_HP = FEC_1_2; - o->code_rate_LP = FEC_7_8; - o->guard_interval = GUARD_INTERVAL_1_32; - o->transmission_mode = TRANSMISSION_MODE_2K; - o->constellation = QAM_64; - o->hierarchy_information = HIERARCHY_NONE; - o->bandwidth = BANDWIDTH_8_MHZ; - - return 0; -} - - -static int -lgs8gl5_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 240; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - - -static void -lgs8gl5_release(struct dvb_frontend *fe) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - kfree(state); -} - - -static struct dvb_frontend_ops lgs8gl5_ops; - - -struct dvb_frontend* -lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c) -{ - struct lgs8gl5_state *state = NULL; - - dprintk("%s\n", __func__); - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - - /* Check if the demod is there */ - if (lgs8gl5_read_reg(state, REG_RESET) < 0) - goto error; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &lgs8gl5_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(lgs8gl5_attach); - - -static struct dvb_frontend_ops lgs8gl5_ops = { - .info = { - .name = "Legend Silicon LGS-8GL5 DMB-TH", - .type = FE_OFDM, - .frequency_min = 474000000, - .frequency_max = 858000000, - .frequency_stepsize = 10000, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_BANDWIDTH_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER - }, - - .release = lgs8gl5_release, - - .init = lgs8gl5_init, - - .set_frontend = lgs8gl5_set_frontend, - .get_frontend = lgs8gl5_get_frontend, - .get_tune_settings = lgs8gl5_get_tune_settings, - - .read_status = lgs8gl5_read_status, - .read_ber = lgs8gl5_read_ber, - .read_signal_strength = lgs8gl5_read_signal_strength, - .read_snr = lgs8gl5_read_snr, - .read_ucblocks = lgs8gl5_read_ucblocks, -}; - - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver"); -MODULE_AUTHOR("Timothy Lee"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/lgs8gl5.h b/trunk/drivers/media/dvb/frontends/lgs8gl5.h deleted file mode 100644 index d14176787a7d..000000000000 --- a/trunk/drivers/media/dvb/frontends/lgs8gl5.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver - - Copyright (C) 2008 Sirius International (Hong Kong) Limited - Timothy Lee - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef LGS8GL5_H -#define LGS8GL5_H - -#include - -struct lgs8gl5_config { - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_LGS8GL5) || \ - (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE)) -extern struct dvb_frontend *lgs8gl5_attach( - const struct lgs8gl5_config *config, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *lgs8gl5_attach( - const struct lgs8gl5_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGS8GL5 */ - -#endif /* LGS8GL5_H */ diff --git a/trunk/drivers/media/dvb/frontends/nxt200x.c b/trunk/drivers/media/dvb/frontends/nxt200x.c index a8429ebfa8a2..af298358e822 100644 --- a/trunk/drivers/media/dvb/frontends/nxt200x.c +++ b/trunk/drivers/media/dvb/frontends/nxt200x.c @@ -80,7 +80,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len return 0; } -static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len) +static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) { int err; struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; @@ -111,7 +111,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, return 0; } -static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len) +static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len) { u8 reg2 [] = { reg }; diff --git a/trunk/drivers/media/dvb/frontends/or51211.c b/trunk/drivers/media/dvb/frontends/or51211.c index 16cf2fdd5d7d..6afe12aaca4e 100644 --- a/trunk/drivers/media/dvb/frontends/or51211.c +++ b/trunk/drivers/media/dvb/frontends/or51211.c @@ -88,7 +88,7 @@ static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, return 0; } -static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len) +static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len) { int err; struct i2c_msg msg; diff --git a/trunk/drivers/media/dvb/frontends/si21xx.c b/trunk/drivers/media/dvb/frontends/si21xx.c deleted file mode 100644 index 3ddbe69c45ce..000000000000 --- a/trunk/drivers/media/dvb/frontends/si21xx.c +++ /dev/null @@ -1,974 +0,0 @@ -/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "si21xx.h" - -#define REVISION_REG 0x00 -#define SYSTEM_MODE_REG 0x01 -#define TS_CTRL_REG_1 0x02 -#define TS_CTRL_REG_2 0x03 -#define PIN_CTRL_REG_1 0x04 -#define PIN_CTRL_REG_2 0x05 -#define LOCK_STATUS_REG_1 0x0f -#define LOCK_STATUS_REG_2 0x10 -#define ACQ_STATUS_REG 0x11 -#define ACQ_CTRL_REG_1 0x13 -#define ACQ_CTRL_REG_2 0x14 -#define PLL_DIVISOR_REG 0x15 -#define COARSE_TUNE_REG 0x16 -#define FINE_TUNE_REG_L 0x17 -#define FINE_TUNE_REG_H 0x18 - -#define ANALOG_AGC_POWER_LEVEL_REG 0x28 -#define CFO_ESTIMATOR_CTRL_REG_1 0x29 -#define CFO_ESTIMATOR_CTRL_REG_2 0x2a -#define CFO_ESTIMATOR_CTRL_REG_3 0x2b - -#define SYM_RATE_ESTIMATE_REG_L 0x31 -#define SYM_RATE_ESTIMATE_REG_M 0x32 -#define SYM_RATE_ESTIMATE_REG_H 0x33 - -#define CFO_ESTIMATOR_OFFSET_REG_L 0x36 -#define CFO_ESTIMATOR_OFFSET_REG_H 0x37 -#define CFO_ERROR_REG_L 0x38 -#define CFO_ERROR_REG_H 0x39 -#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a - -#define SYM_RATE_REG_L 0x3f -#define SYM_RATE_REG_M 0x40 -#define SYM_RATE_REG_H 0x41 -#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42 -#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43 - -#define C_N_ESTIMATOR_CTRL_REG 0x7c -#define C_N_ESTIMATOR_THRSHLD_REG 0x7d -#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e -#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f - -#define BLIND_SCAN_CTRL_REG 0x80 - -#define LSA_CTRL_REG_1 0x8D -#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f -#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90 -#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91 -#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92 -#define INBAND_POWER_THRSHLD_REG 0x93 -#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94 - -#define VIT_SRCH_CTRL_REG_1 0xa0 -#define VIT_SRCH_CTRL_REG_2 0xa1 -#define VIT_SRCH_CTRL_REG_3 0xa2 -#define VIT_SRCH_STATUS_REG 0xa3 -#define VITERBI_BER_COUNT_REG_L 0xab -#define REED_SOLOMON_CTRL_REG 0xb0 -#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1 -#define PRBS_CTRL_REG 0xb5 - -#define LNB_CTRL_REG_1 0xc0 -#define LNB_CTRL_REG_2 0xc1 -#define LNB_CTRL_REG_3 0xc2 -#define LNB_CTRL_REG_4 0xc3 -#define LNB_CTRL_STATUS_REG 0xc4 -#define LNB_FIFO_REGS_0 0xc5 -#define LNB_FIFO_REGS_1 0xc6 -#define LNB_FIFO_REGS_2 0xc7 -#define LNB_FIFO_REGS_3 0xc8 -#define LNB_FIFO_REGS_4 0xc9 -#define LNB_FIFO_REGS_5 0xca -#define LNB_SUPPLY_CTRL_REG_1 0xcb -#define LNB_SUPPLY_CTRL_REG_2 0xcc -#define LNB_SUPPLY_CTRL_REG_3 0xcd -#define LNB_SUPPLY_CTRL_REG_4 0xce -#define LNB_SUPPLY_STATUS_REG 0xcf - -#define FALSE 0 -#define TRUE 1 -#define FAIL -1 -#define PASS 0 - -#define ALLOWABLE_FS_COUNT 10 -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "si21xx: " args); \ - } while (0) - -enum { - ACTIVE_HIGH, - ACTIVE_LOW -}; -enum { - BYTE_WIDE, - BIT_WIDE -}; -enum { - CLK_GAPPED_MODE, - CLK_CONTINUOUS_MODE -}; -enum { - RISING_EDGE, - FALLING_EDGE -}; -enum { - MSB_FIRST, - LSB_FIRST -}; -enum { - SERIAL, - PARALLEL -}; - -struct si21xx_state { - struct i2c_adapter *i2c; - const struct si21xx_config *config; - struct dvb_frontend frontend; - u8 initialised:1; - int errmode; - int fs; /*Sampling rate of the ADC in MHz*/ -}; - -/* register default initialization */ -static u8 serit_sp1511lhb_inittab[] = { - 0x01, 0x28, /* set i2c_inc_disable */ - 0x20, 0x03, - 0x27, 0x20, - 0xe0, 0x45, - 0xe1, 0x08, - 0xfe, 0x01, - 0x01, 0x28, - 0x89, 0x09, - 0x04, 0x80, - 0x05, 0x01, - 0x06, 0x00, - 0x20, 0x03, - 0x24, 0x88, - 0x29, 0x09, - 0x2a, 0x0f, - 0x2c, 0x10, - 0x2d, 0x19, - 0x2e, 0x08, - 0x2f, 0x10, - 0x30, 0x19, - 0x34, 0x20, - 0x35, 0x03, - 0x45, 0x02, - 0x46, 0x45, - 0x47, 0xd0, - 0x48, 0x00, - 0x49, 0x40, - 0x4a, 0x03, - 0x4c, 0xfd, - 0x4f, 0x2e, - 0x50, 0x2e, - 0x51, 0x10, - 0x52, 0x10, - 0x56, 0x92, - 0x59, 0x00, - 0x5a, 0x2d, - 0x5b, 0x33, - 0x5c, 0x1f, - 0x5f, 0x76, - 0x62, 0xc0, - 0x63, 0xc0, - 0x64, 0xf3, - 0x65, 0xf3, - 0x79, 0x40, - 0x6a, 0x40, - 0x6b, 0x0a, - 0x6c, 0x80, - 0x6d, 0x27, - 0x71, 0x06, - 0x75, 0x60, - 0x78, 0x00, - 0x79, 0xb5, - 0x7c, 0x05, - 0x7d, 0x1a, - 0x87, 0x55, - 0x88, 0x72, - 0x8f, 0x08, - 0x90, 0xe0, - 0x94, 0x40, - 0xa0, 0x3f, - 0xa1, 0xc0, - 0xa4, 0xcc, - 0xa5, 0x66, - 0xa6, 0x66, - 0xa7, 0x7b, - 0xa8, 0x7b, - 0xa9, 0x7b, - 0xaa, 0x9a, - 0xed, 0x04, - 0xad, 0x00, - 0xae, 0x03, - 0xcc, 0xab, - 0x01, 0x08, - 0xff, 0xff -}; - -/* low level read/writes */ -static int si21_writeregs(struct si21xx_state *state, u8 reg1, - u8 *data, int len) -{ - int ret; - u8 buf[60];/* = { reg1, data };*/ - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = len + 1 - }; - - msg.buf[0] = reg1; - memcpy(msg.buf + 1, data, len); - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg1, data[0], ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int si21_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct si21xx_state *state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return si21_writereg(state, buf[0], buf[1]); -} - -static u8 si21_readreg(struct si21xx_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = ®1, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b, - .len = len - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - - return ret == 2 ? 0 : -1; -} - -static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout) -{ - unsigned long start = jiffies; - - dprintk("%s\n", __func__); - - while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) { - if (jiffies - start > timeout) { - dprintk("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate) -{ - struct si21xx_state *state = fe->demodulator_priv; - u32 sym_rate, data_rate; - int i; - u8 sym_rate_bytes[3]; - - dprintk("%s : srate = %i\n", __func__ , srate); - - if ((srate < 1000000) || (srate > 45000000)) - return -EINVAL; - - data_rate = srate; - sym_rate = 0; - - for (i = 0; i < 4; ++i) { - sym_rate /= 100; - sym_rate = sym_rate + ((data_rate % 100) * 0x800000) / - state->fs; - data_rate /= 100; - } - for (i = 0; i < 3; ++i) - sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff); - - si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03); - - return 0; -} - -static int si21xx_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *m) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 lnb_status; - u8 LNB_CTRL_1; - int status; - - dprintk("%s\n", __func__); - - status = PASS; - LNB_CTRL_1 = 0; - - status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01); - status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01); - - /*fill the FIFO*/ - status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len); - - LNB_CTRL_1 = (lnb_status & 0x70); - LNB_CTRL_1 |= m->msg_len; - - LNB_CTRL_1 |= 0x80; /* begin LNB signaling */ - - status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01); - - return status; -} - -static int si21xx_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 val; - - dprintk("%s\n", __func__); - - if (si21xx_wait_diseqc_idle(state, 100) < 0) - return -ETIMEDOUT; - - val = (0x80 | si21_readreg(state, 0xc1)); - if (si21_writereg(state, LNB_CTRL_REG_1, - burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10))) - return -EREMOTEIO; - - if (si21xx_wait_diseqc_idle(state, 100) < 0) - return -ETIMEDOUT; - - if (si21_writereg(state, LNB_CTRL_REG_1, val)) - return -EREMOTEIO; - - return 0; -} -/* 30.06.2008 */ -static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 val; - - dprintk("%s\n", __func__); - val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1)); - - switch (tone) { - case SEC_TONE_ON: - return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20); - - case SEC_TONE_OFF: - return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20)); - - default: - return -EINVAL; - } -} - -static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) -{ - struct si21xx_state *state = fe->demodulator_priv; - - u8 val; - dprintk("%s: %s\n", __func__, - volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - - val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1)); - - switch (volt) { - case SEC_VOLTAGE_18: - return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40); - break; - case SEC_VOLTAGE_13: - return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40)); - break; - default: - return -EINVAL; - }; -} - -static int si21xx_init(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - int i; - int status = 0; - u8 reg1; - u8 val; - u8 reg2[2]; - - dprintk("%s\n", __func__); - - for (i = 0; ; i += 2) { - reg1 = serit_sp1511lhb_inittab[i]; - val = serit_sp1511lhb_inittab[i+1]; - if (reg1 == 0xff && val == 0xff) - break; - si21_writeregs(state, reg1, &val, 1); - } - - /*DVB QPSK SYSTEM MODE REG*/ - reg1 = 0x08; - si21_writeregs(state, SYSTEM_MODE_REG, ®1, 0x01); - - /*transport stream config*/ - /* - mode = PARALLEL; - sdata_form = LSB_FIRST; - clk_edge = FALLING_EDGE; - clk_mode = CLK_GAPPED_MODE; - strt_len = BYTE_WIDE; - sync_pol = ACTIVE_HIGH; - val_pol = ACTIVE_HIGH; - err_pol = ACTIVE_HIGH; - sclk_rate = 0x00; - parity = 0x00 ; - data_delay = 0x00; - clk_delay = 0x00; - pclk_smooth = 0x00; - */ - reg2[0] = - PARALLEL + (LSB_FIRST << 1) - + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3) - + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5) - + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7); - - reg2[1] = 0; - /* sclk_rate + (parity << 2) - + (data_delay << 3) + (clk_delay << 4) - + (pclk_smooth << 5); - */ - status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02); - if (status != 0) - dprintk(" %s : TS Set Error\n", __func__); - - return 0; - -} - -static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 regs_read[2]; - u8 reg_read; - u8 i; - u8 lock; - u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG); - - si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02); - reg_read = 0; - - for (i = 0; i < 7; ++i) - reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i); - - lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80)); - - dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock); - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (lock & 0x2) - *status |= FE_HAS_CARRIER; - - if (lock & 0x20) - *status |= FE_HAS_VITERBI; - - if (lock & 0x40) - *status |= FE_HAS_SYNC; - - if ((lock & 0x7b) == 0x7b) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct si21xx_state *state = fe->demodulator_priv; - - /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG, - (u8*)agclevel, 0x01);*/ - - u16 signal = (3 * si21_readreg(state, 0x27) * - si21_readreg(state, 0x28)); - - dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__, - si21_readreg(state, 0x27), - si21_readreg(state, 0x28), (int) signal); - - signal <<= 4; - *strength = signal; - - return 0; -} - -static int si21_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (state->errmode != STATUS_BER) - return 0; - - *ber = (si21_readreg(state, 0x1d) << 8) | - si21_readreg(state, 0x1e); - - return 0; -} - -static int si21_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct si21xx_state *state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) | - si21_readreg(state, 0x25)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - - dprintk("%s\n", __func__); - - return 0; -} - -static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (state->errmode != STATUS_UCBLOCKS) - *ucblocks = 0; - else - *ucblocks = (si21_readreg(state, 0x1d) << 8) | - si21_readreg(state, 0x1e); - - return 0; -} - -/* initiates a channel acquisition sequence - using the specified symbol rate and code rate */ -static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate, - fe_code_rate_t crate) -{ - - struct si21xx_state *state = fe->demodulator_priv; - u8 coderates[] = { - 0x0, 0x01, 0x02, 0x04, 0x00, - 0x8, 0x10, 0x20, 0x00, 0x3f - }; - - u8 coderate_ptr; - int status; - u8 start_acq = 0x80; - u8 reg, regs[3]; - - dprintk("%s\n", __func__); - - status = PASS; - coderate_ptr = coderates[crate]; - - si21xx_set_symbolrate(fe, symbrate); - - /* write code rates to use in the Viterbi search */ - status |= si21_writeregs(state, - VIT_SRCH_CTRL_REG_1, - &coderate_ptr, 0x01); - - /* clear acq_start bit */ - status |= si21_readregs(state, ACQ_CTRL_REG_2, ®, 0x01); - reg &= ~start_acq; - status |= si21_writeregs(state, ACQ_CTRL_REG_2, ®, 0x01); - - /* use new Carrier Frequency Offset Estimator (QuickLock) */ - regs[0] = 0xCB; - regs[1] = 0x40; - regs[2] = 0xCB; - - status |= si21_writeregs(state, - TWO_DB_BNDWDTH_THRSHLD_REG, - ®s[0], 0x03); - reg = 0x56; - status |= si21_writeregs(state, - LSA_CTRL_REG_1, ®, 1); - reg = 0x05; - status |= si21_writeregs(state, - BLIND_SCAN_CTRL_REG, ®, 1); - /* start automatic acq */ - status |= si21_writeregs(state, - ACQ_CTRL_REG_2, &start_acq, 0x01); - - return status; -} - -static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) -{ - struct si21xx_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz) - datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/ - - /* in MHz */ - unsigned char coarse_tune_freq; - int fine_tune_freq; - unsigned char sample_rate = 0; - /* boolean */ - unsigned int inband_interferer_ind; - - /* INTERMEDIATE VALUES */ - int icoarse_tune_freq; /* MHz */ - int ifine_tune_freq; /* MHz */ - unsigned int band_high; - unsigned int band_low; - unsigned int x1; - unsigned int x2; - int i; - unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = { - FALSE, FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, FALSE - }; - unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = { - FALSE, FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, FALSE - }; - - int status; - - /* allowable sample rates for ADC in MHz */ - int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195, - 196, 204, 205, 206, 207 - }; - /* in MHz */ - int if_limit_high; - int if_limit_low; - int lnb_lo; - int lnb_uncertanity; - - int rf_freq; - int data_rate; - unsigned char regs[4]; - - dprintk("%s : FE_SET_FRONTEND\n", __func__); - - if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) - inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE; - - if_limit_high = -700000; - if_limit_low = -100000; - /* in MHz */ - lnb_lo = 0; - lnb_uncertanity = 0; - - rf_freq = 10 * c->frequency ; - data_rate = c->symbol_rate / 100; - - status = PASS; - - band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200) - + (data_rate * 135)) / 200; - - band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200) - + (data_rate * 135)) / 200; - - - icoarse_tune_freq = 100000 * - (((rf_freq - lnb_lo) - - (if_limit_low + if_limit_high) / 2) - / 100000); - - ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ; - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) * - (afs[i] * 2500) + afs[i] * 2500; - - x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) * - (afs[i] * 2500); - - if (((band_low < x1) && (x1 < band_high)) || - ((band_low < x2) && (x2 < band_high))) - inband_interferer_div4[i] = TRUE; - - } - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) * - (afs[i] * 5000) + afs[i] * 5000; - - x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) * - (afs[i] * 5000); - - if (((band_low < x1) && (x1 < band_high)) || - ((band_low < x2) && (x2 < band_high))) - inband_interferer_div2[i] = TRUE; - } - - inband_interferer_ind = TRUE; - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) - inband_interferer_ind &= inband_interferer_div2[i] | - inband_interferer_div4[i]; - - if (inband_interferer_ind) { - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - if (inband_interferer_div2[i] == FALSE) { - sample_rate = (u8) afs[i]; - break; - } - } - } else { - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - if ((inband_interferer_div2[i] | - inband_interferer_div4[i]) == FALSE) { - sample_rate = (u8) afs[i]; - break; - } - } - - } - - if (sample_rate > 207 || sample_rate < 192) - sample_rate = 200; - - fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) / - ((sample_rate) * 1000)); - - coarse_tune_freq = (u8)(icoarse_tune_freq / 100000); - - regs[0] = sample_rate; - regs[1] = coarse_tune_freq; - regs[2] = fine_tune_freq & 0xFF; - regs[3] = fine_tune_freq >> 8 & 0xFF; - - status |= si21_writeregs(state, PLL_DIVISOR_REG, ®s[0], 0x04); - - state->fs = sample_rate;/*ADC MHz*/ - si21xx_setacquire(fe, c->symbol_rate, c->fec_inner); - - return 0; -} - -static int si21xx_sleep(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 regdata; - - dprintk("%s\n", __func__); - - si21_readregs(state, SYSTEM_MODE_REG, ®data, 0x01); - regdata |= 1 << 6; - si21_writeregs(state, SYSTEM_MODE_REG, ®data, 0x01); - state->initialised = 0; - - return 0; -} - -static void si21xx_release(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - kfree(state); -} - -static struct dvb_frontend_ops si21xx_ops = { - - .info = { - .name = "SL SI21XX DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO - }, - - .release = si21xx_release, - .init = si21xx_init, - .sleep = si21xx_sleep, - .write = si21_write, - .read_status = si21_read_status, - .read_ber = si21_read_ber, - .read_signal_strength = si21_read_signal_strength, - .read_snr = si21_read_snr, - .read_ucblocks = si21_read_ucblocks, - .diseqc_send_master_cmd = si21xx_send_diseqc_msg, - .diseqc_send_burst = si21xx_send_diseqc_burst, - .set_tone = si21xx_set_tone, - .set_voltage = si21xx_set_voltage, - - .set_property = si21xx_set_property, - .get_property = si21xx_get_property, - .set_frontend = si21xx_set_frontend, -}; - -struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, - struct i2c_adapter *i2c) -{ - struct si21xx_state *state = NULL; - int id; - - dprintk("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->errmode = STATUS_BER; - - /* check if the demod is there */ - id = si21_readreg(state, SYSTEM_MODE_REG); - si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */ - msleep(200); - id = si21_readreg(state, 0x00); - - /* register 0x00 contains: - 0x34 for SI2107 - 0x24 for SI2108 - 0x14 for SI2109 - 0x04 for SI2110 - */ - if (id != 0x04 && id != 0x14) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &si21xx_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(si21xx_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver"); -MODULE_AUTHOR("Igor M. Liplianin"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/si21xx.h b/trunk/drivers/media/dvb/frontends/si21xx.h deleted file mode 100644 index 141b5b8a5f63..000000000000 --- a/trunk/drivers/media/dvb/frontends/si21xx.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SI21XX_H -#define SI21XX_H - -#include -#include "dvb_frontend.h" - -struct si21xx_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* minimum delay before retuning */ - int min_delay_ms; -}; - -#if defined(CONFIG_DVB_SI21XX) || \ - (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE)) -extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *si21xx_attach( - const struct si21xx_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val) -{ - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif diff --git a/trunk/drivers/media/dvb/frontends/sp887x.c b/trunk/drivers/media/dvb/frontends/sp887x.c index 559509ab4dab..4543609e1816 100644 --- a/trunk/drivers/media/dvb/frontends/sp887x.c +++ b/trunk/drivers/media/dvb/frontends/sp887x.c @@ -337,8 +337,7 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct sp887x_state* state = fe->demodulator_priv; - unsigned actual_freq; - int err; + int actual_freq, err; u16 val, reg0xc05; if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ && diff --git a/trunk/drivers/media/dvb/frontends/stb6000.c b/trunk/drivers/media/dvb/frontends/stb6000.c deleted file mode 100644 index 0e2cb0df1441..000000000000 --- a/trunk/drivers/media/dvb/frontends/stb6000.c +++ /dev/null @@ -1,255 +0,0 @@ - /* - Driver for ST STB6000 DVBS Silicon tuner - - Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#include -#include -#include - -#include "stb6000.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "stb6000: " args); \ - } while (0) - -struct stb6000_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u32 frequency; -}; - -static int stb6000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int stb6000_sleep(struct dvb_frontend *fe) -{ - struct stb6000_priv *priv = fe->tuner_priv; - int ret; - u8 buf[] = { 10, 0 }; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int stb6000_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct stb6000_priv *priv = fe->tuner_priv; - unsigned int n, m; - int ret; - u32 freq_mhz; - int bandwidth; - u8 buf[12]; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 12 - }; - - dprintk("%s:\n", __func__); - - freq_mhz = params->frequency / 1000; - bandwidth = params->u.qpsk.symbol_rate / 1000000; - - if (bandwidth > 31) - bandwidth = 31; - - if ((freq_mhz > 949) && (freq_mhz < 2151)) { - buf[0] = 0x01; - buf[1] = 0xac; - if (freq_mhz < 1950) - buf[1] = 0xaa; - if (freq_mhz < 1800) - buf[1] = 0xa8; - if (freq_mhz < 1650) - buf[1] = 0xa6; - if (freq_mhz < 1530) - buf[1] = 0xa5; - if (freq_mhz < 1470) - buf[1] = 0xa4; - if (freq_mhz < 1370) - buf[1] = 0xa2; - if (freq_mhz < 1300) - buf[1] = 0xa1; - if (freq_mhz < 1200) - buf[1] = 0xa0; - if (freq_mhz < 1075) - buf[1] = 0xbc; - if (freq_mhz < 1000) - buf[1] = 0xba; - if (freq_mhz < 1075) { - n = freq_mhz / 8; /* vco=lo*4 */ - m = 2; - } else { - n = freq_mhz / 16; /* vco=lo*2 */ - m = 1; - } - buf[2] = n >> 1; - buf[3] = (unsigned char)(((n & 1) << 7) | - (m * freq_mhz - n * 16) | 0x60); - buf[4] = 0x04; - buf[5] = 0x0e; - - buf[6] = (unsigned char)(bandwidth); - - buf[7] = 0xd8; - buf[8] = 0xd0; - buf[9] = 0x50; - buf[10] = 0xeb; - buf[11] = 0x4f; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - udelay(10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - buf[0] = 0x07; - buf[1] = 0xdf; - buf[2] = 0xd0; - buf[3] = 0x50; - buf[4] = 0xfb; - msg.len = 5; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - udelay(10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - priv->frequency = freq_mhz * 1000; - - return (ret == 1) ? 0 : ret; - } - return -1; -} - -static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct stb6000_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops stb6000_tuner_ops = { - .info = { - .name = "ST STB6000", - .frequency_min = 950000, - .frequency_max = 2150000 - }, - .release = stb6000_release, - .sleep = stb6000_sleep, - .set_params = stb6000_set_params, - .get_frequency = stb6000_get_frequency, -}; - -struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c) -{ - struct stb6000_priv *priv = NULL; - u8 b0[] = { 0 }; - u8 b1[] = { 0, 0 }; - struct i2c_msg msg[2] = { - { - .addr = addr, - .flags = 0, - .buf = b0, - .len = 0 - }, { - .addr = addr, - .flags = I2C_M_RD, - .buf = b1, - .len = 2 - } - }; - int ret; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - /* is some i2c device here ? */ - ret = i2c_transfer(i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - - priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - - memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - - return fe; -} -EXPORT_SYMBOL(stb6000_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("DVB STB6000 driver"); -MODULE_AUTHOR("Igor M. Liplianin "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/stb6000.h b/trunk/drivers/media/dvb/frontends/stb6000.h deleted file mode 100644 index 7be479c22d5b..000000000000 --- a/trunk/drivers/media/dvb/frontends/stb6000.h +++ /dev/null @@ -1,51 +0,0 @@ - /* - Driver for ST stb6000 DVBS Silicon tuner - - Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#ifndef __DVB_STB6000_H__ -#define __DVB_STB6000_H__ - -#include -#include "dvb_frontend.h" - -/** - * Attach a stb6000 tuner to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param addr i2c address of the tuner. - * @param i2c i2c adapter to use. - * @return FE pointer on success, NULL on failure. - */ -#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, - int addr, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_STB6000 */ - -#endif /* __DVB_STB6000_H__ */ diff --git a/trunk/drivers/media/dvb/frontends/stv0288.c b/trunk/drivers/media/dvb/frontends/stv0288.c deleted file mode 100644 index ff1194de34c0..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0288.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - Driver for ST STV0288 demodulator - Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de - for Reel Multimedia - Copyright (C) 2008 TurboSight.com, Bob Liu - Copyright (C) 2008 Igor M. Liplianin - Removed stb6000 specific tuner code and revised some - procedures. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "stv0288.h" - -struct stv0288_state { - struct i2c_adapter *i2c; - const struct stv0288_config *config; - struct dvb_frontend frontend; - - u8 initialised:1; - u32 tuner_frequency; - u32 symbol_rate; - fe_code_rate_t fec_inner; - int errmode; -}; - -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -static int debug_legacy_dish_switch; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "stv0288: " args); \ - } while (0) - - -static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return stv0288_writeregI(state, buf[0], buf[1]); -} - -static u8 stv0288_readreg(struct stv0288_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate) -{ - struct stv0288_state *state = fe->demodulator_priv; - unsigned int temp; - unsigned char b[3]; - - if ((srate < 1000000) || (srate > 45000000)) - return -EINVAL; - - temp = (unsigned int)srate / 1000; - - temp = temp * 32768; - temp = temp / 25; - temp = temp / 125; - b[0] = (unsigned char)((temp >> 12) & 0xff); - b[1] = (unsigned char)((temp >> 4) & 0xff); - b[2] = (unsigned char)((temp << 4) & 0xf0); - stv0288_writeregI(state, 0x28, 0x80); /* SFRH */ - stv0288_writeregI(state, 0x29, 0); /* SFRM */ - stv0288_writeregI(state, 0x2a, 0); /* SFRL */ - - stv0288_writeregI(state, 0x28, b[0]); - stv0288_writeregI(state, 0x29, b[1]); - stv0288_writeregI(state, 0x2a, b[2]); - dprintk("stv0288: stv0288_set_symbolrate\n"); - - return 0; -} - -static int stv0288_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *m) -{ - struct stv0288_state *state = fe->demodulator_priv; - - int i; - - dprintk("%s\n", __func__); - - stv0288_writeregI(state, 0x09, 0); - msleep(30); - stv0288_writeregI(state, 0x05, 0x16); - - for (i = 0; i < m->msg_len; i++) { - if (stv0288_writeregI(state, 0x06, m->msg[i])) - return -EREMOTEIO; - msleep(12); - } - - return 0; -} - -static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct stv0288_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */ - return -EREMOTEIO; - - if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff)) - return -EREMOTEIO; - - if (stv0288_writeregI(state, 0x06, 0x12)) - return -EREMOTEIO; - - return 0; -} - -static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct stv0288_state *state = fe->demodulator_priv; - - switch (tone) { - case SEC_TONE_ON: - if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */ - return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0xff); - - case SEC_TONE_OFF: - if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */ - return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0x00); - - default: - return -EINVAL; - } -} - -static u8 stv0288_inittab[] = { - 0x01, 0x15, - 0x02, 0x20, - 0x09, 0x0, - 0x0a, 0x4, - 0x0b, 0x0, - 0x0c, 0x0, - 0x0d, 0x0, - 0x0e, 0xd4, - 0x0f, 0x30, - 0x11, 0x80, - 0x12, 0x03, - 0x13, 0x48, - 0x14, 0x84, - 0x15, 0x45, - 0x16, 0xb7, - 0x17, 0x9c, - 0x18, 0x0, - 0x19, 0xa6, - 0x1a, 0x88, - 0x1b, 0x8f, - 0x1c, 0xf0, - 0x20, 0x0b, - 0x21, 0x54, - 0x22, 0x0, - 0x23, 0x0, - 0x2b, 0xff, - 0x2c, 0xf7, - 0x30, 0x0, - 0x31, 0x1e, - 0x32, 0x14, - 0x33, 0x0f, - 0x34, 0x09, - 0x35, 0x0c, - 0x36, 0x05, - 0x37, 0x2f, - 0x38, 0x16, - 0x39, 0xbe, - 0x3a, 0x0, - 0x3b, 0x13, - 0x3c, 0x11, - 0x3d, 0x30, - 0x40, 0x63, - 0x41, 0x04, - 0x42, 0x60, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x4a, 0x00, - 0x50, 0x10, - 0x51, 0x38, - 0x52, 0x21, - 0x58, 0x54, - 0x59, 0x86, - 0x5a, 0x0, - 0x5b, 0x9b, - 0x5c, 0x08, - 0x5d, 0x7f, - 0x5e, 0x0, - 0x5f, 0xff, - 0x70, 0x0, - 0x71, 0x0, - 0x72, 0x0, - 0x74, 0x0, - 0x75, 0x0, - 0x76, 0x0, - 0x81, 0x0, - 0x82, 0x3f, - 0x83, 0x3f, - 0x84, 0x0, - 0x85, 0x0, - 0x88, 0x0, - 0x89, 0x0, - 0x8a, 0x0, - 0x8b, 0x0, - 0x8c, 0x0, - 0x90, 0x0, - 0x91, 0x0, - 0x92, 0x0, - 0x93, 0x0, - 0x94, 0x1c, - 0x97, 0x0, - 0xa0, 0x48, - 0xa1, 0x0, - 0xb0, 0xb8, - 0xb1, 0x3a, - 0xb2, 0x10, - 0xb3, 0x82, - 0xb4, 0x80, - 0xb5, 0x82, - 0xb6, 0x82, - 0xb7, 0x82, - 0xb8, 0x20, - 0xb9, 0x0, - 0xf0, 0x0, - 0xf1, 0x0, - 0xf2, 0xc0, - 0x51, 0x36, - 0x52, 0x09, - 0x53, 0x94, - 0x54, 0x62, - 0x55, 0x29, - 0x56, 0x64, - 0x57, 0x2b, - 0xff, 0xff, -}; - -static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) -{ - dprintk("%s: %s\n", __func__, - volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - return 0; -} - -static int stv0288_init(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - int i; - u8 reg; - u8 val; - - dprintk("stv0288: init chip\n"); - stv0288_writeregI(state, 0x41, 0x04); - msleep(50); - - /* we have default inittab */ - if (state->config->inittab == NULL) { - for (i = 0; !(stv0288_inittab[i] == 0xff && - stv0288_inittab[i + 1] == 0xff); i += 2) - stv0288_writeregI(state, stv0288_inittab[i], - stv0288_inittab[i + 1]); - } else { - for (i = 0; ; i += 2) { - reg = state->config->inittab[i]; - val = state->config->inittab[i+1]; - if (reg == 0xff && val == 0xff) - break; - stv0288_writeregI(state, reg, val); - } - } - return 0; -} - -static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct stv0288_state *state = fe->demodulator_priv; - - u8 sync = stv0288_readreg(state, 0x24); - if (sync == 255) - sync = 0; - - dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); - - *status = 0; - - if ((sync & 0x08) == 0x08) { - *status |= FE_HAS_LOCK; - dprintk("stv0288 has locked\n"); - } - - return 0; -} - -static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return 0; - *ber = (stv0288_readreg(state, 0x26) << 8) | - stv0288_readreg(state, 0x27); - dprintk("stv0288_read_ber %d\n", *ber); - - return 0; -} - - -static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct stv0288_state *state = fe->demodulator_priv; - - s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8)); - - - signal = signal * 5 / 4; - *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal; - dprintk("stv0288_read_signal_strength %d\n", *strength); - - return 0; -} -static int stv0288_sleep(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - - stv0288_writeregI(state, 0x41, 0x84); - state->initialised = 0; - - return 0; -} -static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct stv0288_state *state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8) - | stv0288_readreg(state, 0x2e)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - dprintk("stv0288_read_snr %d\n", *snr); - - return 0; -} - -static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return 0; - *ucblocks = (stv0288_readreg(state, 0x26) << 8) | - stv0288_readreg(state, 0x27); - dprintk("stv0288_read_ber %d\n", *ucblocks); - - return 0; -} - -static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) -{ - struct stv0288_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - char tm; - unsigned char tda[3]; - - dprintk("%s : FE_SET_FRONTEND\n", __func__); - - if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery " - "system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* only frequency & symbol_rate are used for tuner*/ - dfp->frequency = c->frequency; - dfp->u.qpsk.symbol_rate = c->symbol_rate; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, dfp); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - udelay(10); - stv0288_set_symbolrate(fe, c->symbol_rate); - /* Carrier lock control register */ - stv0288_writeregI(state, 0x15, 0xc5); - - tda[0] = 0x2b; /* CFRM */ - tda[2] = 0x0; /* CFRL */ - for (tm = -6; tm < 7;) { - /* Viterbi status */ - if (stv0288_readreg(state, 0x24) & 0x80) - break; - - tda[2] += 40; - if (tda[2] < 40) - tm++; - tda[1] = (unsigned char)tm; - stv0288_writeregI(state, 0x2b, tda[1]); - stv0288_writeregI(state, 0x2c, tda[2]); - udelay(30); - } - - state->tuner_frequency = c->frequency; - state->fec_inner = FEC_AUTO; - state->symbol_rate = c->symbol_rate; - - return 0; -} - -static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (enable) - stv0288_writeregI(state, 0x01, 0xb5); - else - stv0288_writeregI(state, 0x01, 0x35); - - udelay(1); - - return 0; -} - -static void stv0288_release(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0288_ops = { - - .info = { - .name = "ST STV0288 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1000, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO - }, - - .release = stv0288_release, - .init = stv0288_init, - .sleep = stv0288_sleep, - .write = stv0288_write, - .i2c_gate_ctrl = stv0288_i2c_gate_ctrl, - .read_status = stv0288_read_status, - .read_ber = stv0288_read_ber, - .read_signal_strength = stv0288_read_signal_strength, - .read_snr = stv0288_read_snr, - .read_ucblocks = stv0288_read_ucblocks, - .diseqc_send_master_cmd = stv0288_send_diseqc_msg, - .diseqc_send_burst = stv0288_send_diseqc_burst, - .set_tone = stv0288_set_tone, - .set_voltage = stv0288_set_voltage, - - .set_property = stv0288_set_property, - .get_property = stv0288_get_property, - .set_frontend = stv0288_set_frontend, -}; - -struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c) -{ - struct stv0288_state *state = NULL; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->tuner_frequency = 0; - state->symbol_rate = 0; - state->fec_inner = 0; - state->errmode = STATUS_BER; - - stv0288_writeregI(state, 0x41, 0x04); - msleep(200); - id = stv0288_readreg(state, 0x00); - dprintk("stv0288 id %x\n", id); - - /* register 0x00 contains 0x11 for STV0288 */ - if (id != 0x11) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0288_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(stv0288_attach); - -module_param(debug_legacy_dish_switch, int, 0444); -MODULE_PARM_DESC(debug_legacy_dish_switch, - "Enable timing analysis for Dish Network legacy switches"); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver"); -MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/media/dvb/frontends/stv0288.h b/trunk/drivers/media/dvb/frontends/stv0288.h deleted file mode 100644 index f2b53db0606d..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0288.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Driver for ST STV0288 demodulator - - Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de - for Reel Multimedia - Copyright (C) 2008 TurboSight.com, - Copyright (C) 2008 Igor M. Liplianin - Removed stb6000 specific tuner code and revised some - procedures. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef STV0288_H -#define STV0288_H - -#include -#include "dvb_frontend.h" - -struct stv0288_config { - /* the demodulator's i2c address */ - u8 demod_address; - - u8* inittab; - - /* minimum delay before retuning */ - int min_delay_ms; - - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \ - defined(MODULE)) -extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_STV0288 */ - -static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val) -{ - int r = 0; - u8 buf[] = { reg, val }; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif /* STV0288_H */ diff --git a/trunk/drivers/media/dvb/frontends/stv0299.c b/trunk/drivers/media/dvb/frontends/stv0299.c index 6c1cb1973c6e..35435bef8e79 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.c +++ b/trunk/drivers/media/dvb/frontends/stv0299.c @@ -559,8 +559,6 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par int invval = 0; dprintk ("%s : FE_SET_FRONTEND\n", __func__); - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); // set the inversion if (p->inversion == INVERSION_OFF) invval = 0; diff --git a/trunk/drivers/media/dvb/frontends/stv0299.h b/trunk/drivers/media/dvb/frontends/stv0299.h index 0fd96e22b650..3282f43022f5 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.h +++ b/trunk/drivers/media/dvb/frontends/stv0299.h @@ -89,18 +89,15 @@ struct stv0299_config int min_delay_ms; /* Set the symbol rate */ - int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio); - - /* Set device param to start dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); + int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); }; #if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) -extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, - struct i2c_adapter *i2c); +extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, + struct i2c_adapter* i2c); #else -static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, - struct i2c_adapter *i2c) +static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, + struct i2c_adapter* i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; diff --git a/trunk/drivers/media/dvb/frontends/tdhd1.h b/trunk/drivers/media/dvb/frontends/tdhd1.h deleted file mode 100644 index 51f170678650..000000000000 --- a/trunk/drivers/media/dvb/frontends/tdhd1.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * tdhd1.h - ALPS TDHD1-204A tuner support - * - * Copyright (C) 2008 Oliver Endriss - * - * - * 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. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * The project's page is at http://www.linuxtv.org - */ - -#ifndef TDHD1_H -#define TDHD1_H - -#include "tda1004x.h" - -static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name); - -static struct tda1004x_config alps_tdhd1_204a_config = { - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = alps_tdhd1_204_request_firmware -}; - -static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct i2c_adapter *i2c = fe->tuner_priv; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - u32 div; - - div = (params->frequency + 36166666) / 166666; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85; - - if (params->frequency >= 174000000 && params->frequency <= 230000000) - data[3] = 0x02; - else if (params->frequency >= 470000000 && params->frequency <= 823000000) - data[3] = 0x0C; - else if (params->frequency > 823000000 && params->frequency <= 862000000) - data[3] = 0x8C; - else - return -EINVAL; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - - return 0; -} - -#endif /* TDHD1_H */ diff --git a/trunk/drivers/media/dvb/ttpci/Kconfig b/trunk/drivers/media/dvb/ttpci/Kconfig index 867027ceab3e..41b5a988b619 100644 --- a/trunk/drivers/media/dvb/ttpci/Kconfig +++ b/trunk/drivers/media/dvb/ttpci/Kconfig @@ -86,7 +86,6 @@ config DVB_BUDGET select DVB_TDA10086 if !DVB_FE_CUSTOMISE select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_TDA1004X if !DVB_FE_CUSTOMISE help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard MPEG2 decoder, and without diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index c7c770c28988..0777e8f9544b 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -88,7 +88,6 @@ static int budgetpatch; static int wss_cfg_4_3 = 0x4008; static int wss_cfg_16_9 = 0x0007; static int tv_standard; -static int full_ts; module_param_named(debug, av7110_debug, int, 0644); MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); @@ -107,8 +106,6 @@ module_param(volume, int, 0444); MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); module_param(budgetpatch, int, 0444); MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); -module_param(full_ts, int, 0444); -MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 disable (default), 1 enable"); module_param(wss_cfg_4_3, int, 0444); MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data"); module_param(wss_cfg_16_9, int, 0444); @@ -119,8 +116,6 @@ MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static void restart_feeds(struct av7110 *av7110); -static int budget_start_feed(struct dvb_demux_feed *feed); -static int budget_stop_feed(struct dvb_demux_feed *feed); static int av7110_num; @@ -381,9 +376,9 @@ static inline void start_debi_dma(struct av7110 *av7110, int dir, irdebi(av7110, DEBISWAB, addr, 0, len); } -static void debiirq(unsigned long cookie) +static void debiirq(unsigned long data) { - struct av7110 *av7110 = (struct av7110 *)cookie; + struct av7110 *av7110 = (struct av7110 *) data; int type = av7110->debitype; int handle = (type >> 8) & 0x1f; unsigned int xfer = 0; @@ -492,9 +487,9 @@ static void debiirq(unsigned long cookie) } /* irq from av7110 firmware writing the mailbox register in the DPRAM */ -static void gpioirq(unsigned long cookie) +static void gpioirq(unsigned long data) { - struct av7110 *av7110 = (struct av7110 *)cookie; + struct av7110 *av7110 = (struct av7110 *) data; u32 rxbuf, txbuf; int len; @@ -811,9 +806,6 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) dprintk(4, "%p\n", av7110); - if (av7110->full_ts) - return 0; - if (dvbdmxfilter->type == DMX_TYPE_SEC) { if (hw_sections) { buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) | @@ -862,9 +854,6 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) dprintk(4, "%p\n", av7110); - if (av7110->full_ts) - return 0; - handle = dvbdmxfilter->hw_handle; if (handle >= 32) { printk("%s tried to stop invalid filter %04x, filter type = %x\n", @@ -924,7 +913,7 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) return ret; } - if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) { + if ((dvbdmxfeed->ts_type & TS_PACKET)) { if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) @@ -985,7 +974,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) if (!demux->dmx.frontend) return -EINVAL; - if (!av7110->full_ts && feed->pid > 0x1fff) + if (feed->pid > 0x1fff) return -EINVAL; if (feed->type == DMX_TYPE_TS) { @@ -1014,12 +1003,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) } } - if (av7110->full_ts) { - budget_start_feed(feed); - return ret; - } - - if (feed->type == DMX_TYPE_SEC) { + else if (feed->type == DMX_TYPE_SEC) { int i; for (i = 0; i < demux->filternum; i++) { @@ -1066,12 +1050,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed) ret = StopHWFilter(feed->filter); } - if (av7110->full_ts) { - budget_stop_feed(feed); - return ret; - } - - if (feed->type == DMX_TYPE_SEC) { + if (!ret && feed->type == DMX_TYPE_SEC) { for (i = 0; ifilternum; i++) { if (demux->filter[i].state == DMX_STATE_GO && demux->filter[i].filter.parent == &feed->feed.sec) { @@ -1095,7 +1074,6 @@ static void restart_feeds(struct av7110 *av7110) struct dvb_demux *dvbdmx = &av7110->demux; struct dvb_demux_feed *feed; int mode; - int feeding; int i, j; dprintk(4, "%p\n", av7110); @@ -1104,8 +1082,6 @@ static void restart_feeds(struct av7110 *av7110) av7110->playing = 0; av7110->rec_mode = 0; - feeding = av7110->feeding1; /* full_ts mod */ - for (i = 0; i < dvbdmx->feednum; i++) { feed = &dvbdmx->feed[i]; if (feed->state == DMX_STATE_GO) { @@ -1123,8 +1099,6 @@ static void restart_feeds(struct av7110 *av7110) } } - av7110->feeding1 = feeding; /* full_ts mod */ - if (mode) av7110_av_start_play(av7110, mode); } @@ -1223,9 +1197,8 @@ static int start_ts_capture(struct av7110 *budget) if (budget->feeding1) return ++budget->feeding1; - memset(budget->grabbing, 0x00, TS_BUFLEN); + memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); budget->ttbp = 0; - SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */ SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ return ++budget->feeding1; @@ -1260,14 +1233,18 @@ static int budget_stop_feed(struct dvb_demux_feed *feed) return status; } -static void vpeirq(unsigned long cookie) +static void vpeirq(unsigned long data) { - struct av7110 *budget = (struct av7110 *)cookie; + struct av7110 *budget = (struct av7110 *) data; u8 *mem = (u8 *) (budget->grabbing); u32 olddma = budget->ttbp; u32 newdma = saa7146_read(budget->dev, PCI_VDP3); - struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1; + if (!budgetpatch) { + printk("av7110.c: vpeirq() called while budgetpatch disabled!" + " check saa7146 IER register\n"); + BUG(); + } /* nearest lower position divisible by 188 */ newdma -= newdma % 188; @@ -1291,11 +1268,11 @@ static void vpeirq(unsigned long cookie) if (newdma > olddma) /* no wraparound, dump olddma..newdma */ - dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188); + dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188); else { /* wraparound, dump olddma..buflen and 0..newdma */ - dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188); - dvb_dmx_swfilter_packets(demux, mem, newdma / 188); + dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188); + dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188); } } @@ -1317,8 +1294,8 @@ static int av7110_register(struct av7110 *av7110) for (i = 0; i < 32; i++) av7110->handle2filter[i] = NULL; - dvbdemux->filternum = (av7110->full_ts) ? 256 : 32; - dvbdemux->feednum = (av7110->full_ts) ? 256 : 32; + dvbdemux->filternum = 32; + dvbdemux->feednum = 32; dvbdemux->start_feed = av7110_start_feed; dvbdemux->stop_feed = av7110_stop_feed; dvbdemux->write_to_decoder = av7110_write_to_decoder; @@ -1328,7 +1305,7 @@ static int av7110_register(struct av7110 *av7110) dvb_dmx_init(&av7110->demux); av7110->demux.dmx.get_stc = dvb_get_stc; - av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32; + av7110->dmxdev.filternum = 32; av7110->dmxdev.demux = &dvbdemux->dmx; av7110->dmxdev.capabilities = 0; @@ -1445,6 +1422,7 @@ int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) return i2c_transfer(&av7110->i2c_adap, &msgs, 1); } +#if 0 u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) { u8 mm1[] = {0x00}; @@ -1461,6 +1439,7 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) return mm2[0]; } +#endif /**************************************************************************** * INITIALIZATION @@ -2277,7 +2256,7 @@ static int frontend_init(struct av7110 *av7110) if (!av7110->fe) { /* FIXME: propagate the failure code from the lower layers */ ret = -ENOMEM; - printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", av7110->dev->pci->vendor, av7110->dev->pci->device, av7110->dev->pci->subsystem_vendor, @@ -2505,47 +2484,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, av7110->dvb_adapter.proposed_mac); ret = -ENOMEM; - /* full-ts mod? */ - if (full_ts) - av7110->full_ts = true; - - /* check for full-ts flag in eeprom */ - if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) { - u8 flags = i2c_readreg(av7110, 0xaa, 2); - if (flags != 0xff && (flags & 0x01)) - av7110->full_ts = true; - } - - if (av7110->full_ts) { - printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n"); - spin_lock_init(&av7110->feedlock1); - av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, - &av7110->pt); - if (!av7110->grabbing) - goto err_i2c_del_3; - - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, MC2, (MASK_10 | MASK_26)); - - saa7146_write(dev, DD1_INIT, 0x00000600); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - saa7146_write(dev, BRS_CTRL, 0x60000000); - saa7146_write(dev, MC2, MASK_08 | MASK_24); - - /* dma3 */ - saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); - saa7146_write(dev, BASE_ODD3, 0); - saa7146_write(dev, BASE_EVEN3, 0); - saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); - saa7146_write(dev, PITCH3, TS_WIDTH); - saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90); - saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); - saa7146_write(dev, MC2, MASK_04 | MASK_20); - - tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); - - } else if (budgetpatch) { + if (budgetpatch) { spin_lock_init(&av7110->feedlock1); av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, &av7110->pt); @@ -2771,13 +2710,11 @@ static int __devexit av7110_detach(struct saa7146_dev* saa) #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) av7110_ir_exit(av7110); #endif - if (budgetpatch || av7110->full_ts) { - if (budgetpatch) { - /* Disable RPS1 */ - saa7146_write(saa, MC1, MASK_29); - /* VSYNC LOW (inactive) */ - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - } + if (budgetpatch) { + /* Disable RPS1 */ + saa7146_write(saa, MC1, MASK_29); + /* VSYNC LOW (inactive) */ + saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); saa7146_write(saa, MC1, MASK_20); /* DMA3 off */ SAA7146_IER_DISABLE(saa, MASK_10); SAA7146_ISR_CLEAR(saa, MASK_10); @@ -2857,7 +2794,7 @@ static void av7110_irq(struct saa7146_dev* dev, u32 *isr) tasklet_schedule(&av7110->gpio_tasklet); } - if (*isr & MASK_10) + if ((*isr & MASK_10) && budgetpatch) tasklet_schedule(&av7110->vpe_tasklet); } diff --git a/trunk/drivers/media/dvb/ttpci/av7110.h b/trunk/drivers/media/dvb/ttpci/av7110.h index d85b8512ac30..55f23ddcb994 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.h +++ b/trunk/drivers/media/dvb/ttpci/av7110.h @@ -192,7 +192,6 @@ struct av7110 { unsigned char *grabbing; struct saa7146_pgtable pt; struct tasklet_struct vpe_tasklet; - bool full_ts; int fe_synced; struct mutex pid_mutex; diff --git a/trunk/drivers/media/dvb/ttpci/av7110_av.c b/trunk/drivers/media/dvb/ttpci/av7110_av.c index bdc62acf2099..184647ad1c7c 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_av.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_av.c @@ -788,9 +788,6 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l dprintk(2, "av7110:%p, \n", av7110); - if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE) - return 0; - switch (feed->pes_type) { case 0: if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) diff --git a/trunk/drivers/media/dvb/ttpci/budget-av.c b/trunk/drivers/media/dvb/ttpci/budget-av.c index 1032ea77837e..b7d1f2f18d3a 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-av.c +++ b/trunk/drivers/media/dvb/ttpci/budget-av.c @@ -57,8 +57,6 @@ #define SLOTSTATUS_READY 8 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - struct budget_av { struct budget budget; struct video_device *vd; @@ -1051,7 +1049,7 @@ static void frontend_init(struct budget_av *budget_av) if (fe == NULL) { printk(KERN_ERR "budget-av: A frontend driver was not found " - "for device [%04x:%04x] subsystem [%04x:%04x]\n", + "for device %04x/%04x subsystem %04x/%04x\n", saa->pci->vendor, saa->pci->device, saa->pci->subsystem_vendor, @@ -1129,9 +1127,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio dev->ext_priv = budget_av; - err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE, - adapter_nr); - if (err) { + if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) { kfree(budget_av); return err; } diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c index 0a5aad45435d..060e7c785326 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-ci.c +++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c @@ -92,8 +92,6 @@ static int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - struct budget_ci_ir { struct input_dev *dev; struct tasklet_struct msp430_irq_tasklet; @@ -1155,7 +1153,7 @@ static void frontend_init(struct budget_ci *budget_ci) } if (budget_ci->budget.dvb_frontend == NULL) { - printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", budget_ci->budget.dev->pci->vendor, budget_ci->budget.dev->pci->device, budget_ci->budget.dev->pci->subsystem_vendor, @@ -1185,8 +1183,7 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio dev->ext_priv = budget_ci; - err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE, - adapter_nr); + err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE); if (err) goto out2; diff --git a/trunk/drivers/media/dvb/ttpci/budget-core.c b/trunk/drivers/media/dvb/ttpci/budget-core.c index ba18e56d5f11..6f4ddb643fee 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-core.c +++ b/trunk/drivers/media/dvb/ttpci/budget-core.c @@ -57,6 +57,8 @@ module_param_named(bufsize, dma_buffer_size, int, 0444); MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /**************************************************************************** * TT budget / WinTV Nova ****************************************************************************/ @@ -409,7 +411,7 @@ static void budget_unregister(struct budget *budget) int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, struct saa7146_pci_extension_data *info, - struct module *owner, short *adapter_nums) + struct module *owner) { int ret = 0; struct budget_info *bi = info->ext_priv; @@ -472,7 +474,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, - owner, &budget->dev->pci->dev, adapter_nums); + owner, &budget->dev->pci->dev, adapter_nr); if (ret < 0) return ret; diff --git a/trunk/drivers/media/dvb/ttpci/budget-patch.c b/trunk/drivers/media/dvb/ttpci/budget-patch.c index 60136688a9a4..aa5ed4ef19f2 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-patch.c +++ b/trunk/drivers/media/dvb/ttpci/budget-patch.c @@ -39,8 +39,6 @@ #include "bsru6.h" -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - #define budget_patch budget static struct saa7146_extension budget_extension; @@ -362,7 +360,7 @@ static void frontend_init(struct budget_patch* budget) } if (budget->dvb_frontend == NULL) { - printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", budget->dev->pci->vendor, budget->dev->pci->device, budget->dev->pci->subsystem_vendor, @@ -594,9 +592,8 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte dprintk(2, "budget: %p\n", budget); - err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); - if (err) { - kfree(budget); + if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { + kfree (budget); return err; } diff --git a/trunk/drivers/media/dvb/ttpci/budget.c b/trunk/drivers/media/dvb/ttpci/budget.c index 1638e1d9f538..f0068996ac07 100644 --- a/trunk/drivers/media/dvb/ttpci/budget.c +++ b/trunk/drivers/media/dvb/ttpci/budget.c @@ -46,14 +46,11 @@ #include "lnbp21.h" #include "bsru6.h" #include "bsbe1.h" -#include "tdhd1.h" static int diseqc_method; module_param(diseqc_method, int, 0444); MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - static void Set22K (struct budget *budget, int state) { struct saa7146_dev *dev=budget->dev; @@ -393,13 +390,6 @@ static struct stv0299_config alps_bsbe1_config_activy = { .set_symbol_rate = alps_bsbe1_set_symbol_rate, }; -static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) -{ - struct budget *budget = (struct budget *)fe->dvb->priv; - - return request_firmware(fw, name, &budget->dev->pci->dev); -} - static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) { @@ -521,14 +511,6 @@ static void frontend_init(struct budget *budget) } break; - case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */ - budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - } - break; - case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); if (budget->dvb_frontend) { @@ -568,7 +550,7 @@ static void frontend_init(struct budget *budget) } if (budget->dvb_frontend == NULL) { - printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", budget->dev->pci->vendor, budget->dev->pci->device, budget->dev->pci->subsystem_vendor, @@ -600,8 +582,7 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ dev->ext_priv = budget; - err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); - if (err) { + if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { printk("==> failed\n"); kfree (budget); return err; @@ -643,7 +624,6 @@ MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY); static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), @@ -654,7 +634,6 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), - MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), { .vendor = 0, diff --git a/trunk/drivers/media/dvb/ttpci/budget.h b/trunk/drivers/media/dvb/ttpci/budget.h index 86435bf16260..dd450b739bff 100644 --- a/trunk/drivers/media/dvb/ttpci/budget.h +++ b/trunk/drivers/media/dvb/ttpci/budget.h @@ -109,7 +109,7 @@ static struct saa7146_pci_extension_data x_var = { \ extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, struct saa7146_pci_extension_data *info, - struct module *owner, short *adapter_nums); + struct module *owner); extern void ttpci_budget_init_hooks(struct budget *budget); extern int ttpci_budget_deinit(struct budget *budget); extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); diff --git a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 66ab0c6e9783..e6c9cd2e3b94 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1614,7 +1614,7 @@ static void frontend_init(struct ttusb* ttusb) } if (ttusb->fe == NULL) { - printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n", + printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n", le16_to_cpu(ttusb->dev->descriptor.idVendor), le16_to_cpu(ttusb->dev->descriptor.idProduct)); } else { diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index ab33fec8a19f..de5829b863fd 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1665,7 +1665,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, } if (dec->fe == NULL) { - printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n", + printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n", le16_to_cpu(dec->udev->descriptor.idVendor), le16_to_cpu(dec->udev->descriptor.idProduct)); } else { diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 21260aad1e54..443af24097f3 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -38,17 +38,7 @@ struct ttusbdecfe_state { }; -static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe, - fe_status_t *status) -{ - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - return 0; -} - - -static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe, - fe_status_t *status) +static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) { struct ttusbdecfe_state* state = fe->demodulator_priv; u8 b[] = { 0x00, 0x00, 0x00, 0x00, @@ -261,7 +251,7 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, - .read_status = ttusbdecfe_dvbt_read_status, + .read_status = ttusbdecfe_read_status, }; static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { @@ -283,7 +273,7 @@ static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { .set_frontend = ttusbdecfe_dvbs_set_frontend, - .read_status = ttusbdecfe_dvbs_read_status, + .read_status = ttusbdecfe_read_status, .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd, .set_voltage = ttusbdecfe_dvbs_set_voltage, diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index e51d707e58d3..1b41b3f77cf9 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -361,16 +361,4 @@ config USB_SI470X To compile this driver as a module, choose M here: the module will be called radio-silabs. -config USB_MR800 - tristate "AverMedia MR 800 USB FM radio support" - depends on USB && VIDEO_V4L2 - ---help--- - Say Y here if you want to connect this type of radio to your - computer's USB port. Note that the audio is not digital, and - you must connect the line out connector to a sound card or a - set of speakers. - - To compile this driver as a module, choose M here: the - module will be called radio-mr800. - endif # RADIO_ADAPTERS diff --git a/trunk/drivers/media/radio/Makefile b/trunk/drivers/media/radio/Makefile index 240ec63cdafc..7ca71ab96b43 100644 --- a/trunk/drivers/media/radio/Makefile +++ b/trunk/drivers/media/radio/Makefile @@ -18,6 +18,5 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_USB_SI470X) += radio-si470x.o -obj-$(CONFIG_USB_MR800) += radio-mr800.o EXTRA_CFLAGS += -Isound diff --git a/trunk/drivers/media/radio/dsbr100.c b/trunk/drivers/media/radio/dsbr100.c index 66783fffe4c1..70c65a745923 100644 --- a/trunk/drivers/media/radio/dsbr100.c +++ b/trunk/drivers/media/radio/dsbr100.c @@ -274,7 +274,7 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); if (v->index > 0) return -EINVAL; @@ -306,7 +306,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); radio->curfreq = f->frequency; if (dsbr100_setfreq(radio, radio->curfreq)==-1) @@ -317,7 +317,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; @@ -342,7 +342,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -355,20 +355,16 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { - if (dsbr100_stop(radio) == -1) { + if (dsbr100_stop(radio)==-1) warn("Radio did not respond properly"); - return -EBUSY; - } } else { - if (dsbr100_start(radio) == -1) { + if (dsbr100_start(radio)==-1) warn("Radio did not respond properly"); - return -EBUSY; - } } return 0; } @@ -409,26 +405,23 @@ static int vidioc_s_audio(struct file *file, void *priv, static int usb_dsbr100_open(struct inode *inode, struct file *file) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); - lock_kernel(); radio->users = 1; radio->muted = 1; if (dsbr100_start(radio)<0) { warn("Radio did not start up properly"); radio->users = 0; - unlock_kernel(); return -EIO; } dsbr100_setfreq(radio, radio->curfreq); - unlock_kernel(); return 0; } static int usb_dsbr100_close(struct inode *inode, struct file *file) { - struct dsbr100_device *radio = video_drvdata(file); + struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); if (!radio) return -ENODEV; @@ -514,8 +507,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, static int __init dsbr100_init(void) { int retval = usb_register(&usb_dsbr100_driver); - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_VERSION ":" DRIVER_DESC); return retval; } diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c index 9305e958fc66..1f064f4b32df 100644 --- a/trunk/drivers/media/radio/radio-aimslab.c +++ b/trunk/drivers/media/radio/radio-aimslab.c @@ -51,7 +51,6 @@ static struct mutex lock; struct rt_device { - unsigned long in_use; int port; int curvol; unsigned long curfreq; @@ -246,7 +245,8 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; if (v->index > 0) return -EINVAL; @@ -273,7 +273,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; rt->curfreq = f->frequency; rt_setfreq(rt, rt->curfreq); @@ -283,7 +284,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = rt->curfreq; @@ -308,7 +310,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -324,7 +327,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -374,21 +378,10 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct rt_device rtrack_unit; -static int rtrack_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0; -} - -static int rtrack_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &rtrack_unit.in_use); - return 0; -} - static const struct file_operations rtrack_fops = { .owner = THIS_MODULE, - .open = rtrack_exclusive_open, - .release = rtrack_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -415,7 +408,6 @@ static struct video_device rtrack_radio = { .name = "RadioTrack radio", .fops = &rtrack_fops, .ioctl_ops = &rtrack_ioctl_ops, - .release = video_device_release_empty, }; static int __init rtrack_init(void) @@ -432,7 +424,7 @@ static int __init rtrack_init(void) return -EBUSY; } - video_set_drvdata(&rtrack_radio, &rtrack_unit); + rtrack_radio.priv=&rtrack_unit; if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) { release_region(io, 2); diff --git a/trunk/drivers/media/radio/radio-aztech.c b/trunk/drivers/media/radio/radio-aztech.c index d78489573230..628c689e3ffe 100644 --- a/trunk/drivers/media/radio/radio-aztech.c +++ b/trunk/drivers/media/radio/radio-aztech.c @@ -70,7 +70,6 @@ static struct mutex lock; struct az_device { - unsigned long in_use; int curvol; unsigned long curfreq; int stereo; @@ -196,7 +195,8 @@ static int vidioc_querycap (struct file *file, void *priv, static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *v) { - struct az_device *az = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; if (v->index > 0) return -EINVAL; @@ -264,7 +264,8 @@ static int vidioc_s_audio (struct file *file, void *priv, static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct az_device *az = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; az->curfreq = f->frequency; az_setfreq(az, az->curfreq); @@ -274,7 +275,8 @@ static int vidioc_s_frequency (struct file *file, void *priv, static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct az_device *az = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = az->curfreq; @@ -300,7 +302,8 @@ static int vidioc_queryctrl (struct file *file, void *priv, static int vidioc_g_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct az_device *az = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -319,7 +322,8 @@ static int vidioc_g_ctrl (struct file *file, void *priv, static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct az_device *az = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -338,21 +342,10 @@ static int vidioc_s_ctrl (struct file *file, void *priv, static struct az_device aztech_unit; -static int aztech_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0; -} - -static int aztech_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &aztech_unit.in_use); - return 0; -} - static const struct file_operations aztech_fops = { .owner = THIS_MODULE, - .open = aztech_exclusive_open, - .release = aztech_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -376,10 +369,9 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = { }; static struct video_device aztech_radio = { - .name = "Aztech radio", - .fops = &aztech_fops, - .ioctl_ops = &aztech_ioctl_ops, - .release = video_device_release_empty, + .name = "Aztech radio", + .fops = &aztech_fops, + .ioctl_ops = &aztech_ioctl_ops, }; module_param_named(debug,aztech_radio.debug, int, 0644); @@ -400,7 +392,7 @@ static int __init aztech_init(void) } mutex_init(&lock); - video_set_drvdata(&aztech_radio, &aztech_unit); + aztech_radio.priv=&aztech_unit; if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) { release_region(io,2); diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index 0490a1fa999d..04c3698d32e4 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -589,7 +589,6 @@ static struct video_device cadet_radio = { .name = "Cadet radio", .fops = &cadet_fops, .ioctl_ops = &cadet_ioctl_ops, - .release = video_device_release_empty, }; #ifdef CONFIG_PNP diff --git a/trunk/drivers/media/radio/radio-gemtek-pci.c b/trunk/drivers/media/radio/radio-gemtek-pci.c index e15bee6d7cfc..5cd7f032298d 100644 --- a/trunk/drivers/media/radio/radio-gemtek-pci.c +++ b/trunk/drivers/media/radio/radio-gemtek-pci.c @@ -100,8 +100,9 @@ struct gemtek_pci_card { u8 mute; }; +static const char rcsid[] = "$Id: radio-gemtek-pci.c,v 1.1 2001/07/23 08:08:16 ted Exp ted $"; + static int nr_radio = -1; -static unsigned long in_use; static inline u8 gemtek_pci_out( u16 value, u32 port ) { @@ -204,7 +205,8 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct gemtek_pci_card *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_pci_card *card = dev->priv; if (v->index > 0) return -EINVAL; @@ -231,7 +233,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek_pci_card *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_pci_card *card = dev->priv; if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || (f->frequency > GEMTEK_PCI_RANGE_HIGH) ) @@ -245,7 +248,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek_pci_card *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_pci_card *card = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = card->current_frequency; @@ -269,7 +273,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek_pci_card *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_pci_card *card = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -288,7 +293,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek_pci_card *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_pci_card *card = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -358,21 +364,10 @@ MODULE_DEVICE_TABLE( pci, gemtek_pci_id ); static int mx = 1; -static int gemtek_pci_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &in_use) ? -EBUSY : 0; -} - -static int gemtek_pci_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &in_use); - return 0; -} - static const struct file_operations gemtek_pci_fops = { .owner = THIS_MODULE, - .open = gemtek_pci_exclusive_open, - .release = gemtek_pci_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -396,10 +391,9 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { }; static struct video_device vdev_template = { - .name = "Gemtek PCI Radio", - .fops = &gemtek_pci_fops, - .ioctl_ops = &gemtek_pci_ioctl_ops, - .release = video_device_release_empty, + .name = "Gemtek PCI Radio", + .fops = &gemtek_pci_fops, + .ioctl_ops = &gemtek_pci_ioctl_ops, }; static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) @@ -437,7 +431,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci } card->videodev = devradio; - video_set_drvdata(devradio, card); + devradio->priv = card; gemtek_pci_mute( card ); printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", diff --git a/trunk/drivers/media/radio/radio-gemtek.c b/trunk/drivers/media/radio/radio-gemtek.c index d131a5d38128..0a0f956bb308 100644 --- a/trunk/drivers/media/radio/radio-gemtek.c +++ b/trunk/drivers/media/radio/radio-gemtek.c @@ -57,7 +57,6 @@ static int shutdown = 1; static int keepmuted = 1; static int initmute = 1; static int radio_nr = -1; -static unsigned long in_use; module_param(io, int, 0444); MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " @@ -394,21 +393,10 @@ static struct v4l2_queryctrl radio_qctrl[] = { } }; -static int gemtek_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &in_use) ? -EBUSY : 0; -} - -static int gemtek_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &in_use); - return 0; -} - static const struct file_operations gemtek_fops = { .owner = THIS_MODULE, - .open = gemtek_exclusive_open, - .release = gemtek_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -459,7 +447,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_device *rt = dev->priv; gemtek_setfreq(rt, f->frequency); @@ -469,7 +458,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_device *rt = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = rt->lastfreq; @@ -493,7 +483,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_device *rt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -512,7 +503,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct gemtek_device *rt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -577,10 +569,9 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { }; static struct video_device gemtek_radio = { - .name = "GemTek Radio card", - .fops = &gemtek_fops, - .ioctl_ops = &gemtek_ioctl_ops, - .release = video_device_release_empty, + .name = "GemTek Radio card", + .fops = &gemtek_fops, + .ioctl_ops = &gemtek_ioctl_ops, }; /* @@ -619,7 +610,7 @@ static int __init gemtek_init(void) return -EINVAL; } - video_set_drvdata(&gemtek_radio, &gemtek_unit); + gemtek_radio.priv = &gemtek_unit; if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) { release_region(io, 1); diff --git a/trunk/drivers/media/radio/radio-maestro.c b/trunk/drivers/media/radio/radio-maestro.c index 4bf4d007bcfa..9ef0a763eeb7 100644 --- a/trunk/drivers/media/radio/radio-maestro.c +++ b/trunk/drivers/media/radio/radio-maestro.c @@ -75,21 +75,7 @@ static struct v4l2_queryctrl radio_qctrl[] = { static int radio_nr = -1; module_param(radio_nr, int, 0); -static unsigned long in_use; - static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); - -static int maestro_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &in_use) ? -EBUSY : 0; -} - -static int maestro_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &in_use); - return 0; -} - static void maestro_remove(struct pci_dev *pdev); static struct pci_device_id maestro_r_pci_tbl[] = { @@ -112,8 +98,8 @@ static struct pci_driver maestro_r_driver = { static const struct file_operations maestro_fops = { .owner = THIS_MODULE, - .open = maestro_exclusive_open, - .release = maestro_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -210,7 +196,8 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card = video_get_drvdata(dev); if (v->index > 0) return -EINVAL; @@ -242,7 +229,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card = video_get_drvdata(dev); if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) return -EINVAL; @@ -253,7 +241,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card = video_get_drvdata(dev); f->type = V4L2_TUNER_RADIO; f->frequency = BITS2FREQ(radio_bits_get(card)); @@ -278,7 +267,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card = video_get_drvdata(dev); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -291,7 +281,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card = video_get_drvdata(dev); register u16 io = card->io; register u16 omask = inw(io + IO_MASK); @@ -383,7 +374,6 @@ static struct video_device maestro_radio = { .name = "Maestro radio", .fops = &maestro_fops, .ioctl_ops = &maestro_ioctl_ops, - .release = video_device_release, }; static int __devinit maestro_probe(struct pci_dev *pdev, diff --git a/trunk/drivers/media/radio/radio-maxiradio.c b/trunk/drivers/media/radio/radio-maxiradio.c index c777a17b00bc..0cc6fcb041fd 100644 --- a/trunk/drivers/media/radio/radio-maxiradio.c +++ b/trunk/drivers/media/radio/radio-maxiradio.c @@ -85,7 +85,6 @@ static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ; static int radio_nr = -1; module_param(radio_nr, int, 0); -static unsigned long in_use; #define FREQ_LO 50*16000 #define FREQ_HI 150*16000 @@ -100,21 +99,10 @@ static unsigned long in_use; #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) -static int maxiradio_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &in_use) ? -EBUSY : 0; -} - -static int maxiradio_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &in_use); - return 0; -} - static const struct file_operations maxiradio_fops = { .owner = THIS_MODULE, - .open = maxiradio_exclusive_open, - .release = maxiradio_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -231,7 +219,8 @@ static int vidioc_querycap (struct file *file, void *priv, static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *v) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; if (v->index > 0) return -EINVAL; @@ -301,7 +290,8 @@ static int vidioc_s_audio (struct file *file, void *priv, static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", @@ -322,7 +312,8 @@ static int vidioc_s_frequency (struct file *file, void *priv, static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = card->freq; @@ -352,7 +343,8 @@ static int vidioc_queryctrl (struct file *file, void *priv, static int vidioc_g_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -366,7 +358,8 @@ static int vidioc_g_ctrl (struct file *file, void *priv, static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct radio_device *card = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -397,10 +390,9 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { }; static struct video_device maxiradio_radio = { - .name = "Maxi Radio FM2000 radio", - .fops = &maxiradio_fops, - .ioctl_ops = &maxiradio_ioctl_ops, - .release = video_device_release_empty, + .name = "Maxi Radio FM2000 radio", + .fops = &maxiradio_fops, + .ioctl_ops = &maxiradio_ioctl_ops, }; static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -416,7 +408,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d radio_unit.io = pci_resource_start(pdev, 0); mutex_init(&radio_unit.lock); - video_set_drvdata(&maxiradio_radio, &radio_unit); + maxiradio_radio.priv = &radio_unit; if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) { printk("radio-maxiradio: can't register device!"); diff --git a/trunk/drivers/media/radio/radio-mr800.c b/trunk/drivers/media/radio/radio-mr800.c deleted file mode 100644 index a33717c48003..000000000000 --- a/trunk/drivers/media/radio/radio-mr800.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - * A driver for the AverMedia MR 800 USB FM radio. This device plugs - * into both the USB and an analog audio input, so this thing - * only deals with initialization and frequency setting, the - * audio data has to be handled by a sound driver. - * - * Copyright (c) 2008 Alexey Klimov - * - * 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 - */ - -/* - * Big thanks to authors of dsbr100.c and radio-si470x.c - * - * When work was looked pretty good, i discover this: - * http://av-usbradio.sourceforge.net/index.php - * http://sourceforge.net/projects/av-usbradio/ - * Latest release of theirs project was in 2005. - * Probably, this driver could be improved trough using their - * achievements (specifications given). - * So, we have smth to begin with. - * - * History: - * Version 0.01: First working version. - * It's required to blacklist AverMedia USB Radio - * in usbhid/hid-quirks.c - * - * Many things to do: - * - Correct power managment of device (suspend & resume) - * - Make x86 independance (little-endian and big-endian stuff) - * - Add code for scanning and smooth tuning - * - Checked and add stereo&mono stuff - * - Add code for sensitivity value - * - Correct mistakes - * - In Japan another FREQ_MIN and FREQ_MAX - */ - -/* kernel includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for KERNEL_VERSION MACRO */ - -/* driver and module definitions */ -#define DRIVER_AUTHOR "Alexey Klimov " -#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver" -#define DRIVER_VERSION "0.01" -#define RADIO_VERSION KERNEL_VERSION(0, 0, 1) - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -#define USB_AMRADIO_VENDOR 0x07ca -#define USB_AMRADIO_PRODUCT 0xb800 - -/* Probably USB_TIMEOUT should be modified in module parameter */ -#define BUFFER_LENGTH 8 -#define USB_TIMEOUT 500 - -/* Frequency limits in MHz -- these are European values. For Japanese -devices, that would be 76 and 91. */ -#define FREQ_MIN 87.5 -#define FREQ_MAX 108.0 -#define FREQ_MUL 16000 - -/* module parameter */ -static int radio_nr = -1; -module_param(radio_nr, int, 0); -MODULE_PARM_DESC(radio_nr, "Radio Nr"); - -static struct v4l2_queryctrl radio_qctrl[] = { - { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, -/* HINT: the disabled controls are only here to satify kradio and such apps */ - { .id = V4L2_CID_AUDIO_VOLUME, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_BALANCE, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_BASS, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_TREBLE, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, - { - .id = V4L2_CID_AUDIO_LOUDNESS, - .flags = V4L2_CTRL_FLAG_DISABLED, - }, -}; - -static int usb_amradio_probe(struct usb_interface *intf, - const struct usb_device_id *id); -static void usb_amradio_disconnect(struct usb_interface *intf); -static int usb_amradio_open(struct inode *inode, struct file *file); -static int usb_amradio_close(struct inode *inode, struct file *file); -static int usb_amradio_suspend(struct usb_interface *intf, - pm_message_t message); -static int usb_amradio_resume(struct usb_interface *intf); - -/* Data for one (physical) device */ -struct amradio_device { - /* reference to USB and video device */ - struct usb_device *usbdev; - struct video_device *videodev; - - unsigned char *buffer; - struct mutex lock; /* buffer locking */ - int curfreq; - int stereo; - int users; - int removed; - int muted; -}; - -/* USB Device ID List */ -static struct usb_device_id usb_amradio_device_table[] = { - {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT, - USB_CLASS_HID, 0, 0) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, usb_amradio_device_table); - -/* USB subsystem interface */ -static struct usb_driver usb_amradio_driver = { - .name = "radio-mr800", - .probe = usb_amradio_probe, - .disconnect = usb_amradio_disconnect, - .suspend = usb_amradio_suspend, - .resume = usb_amradio_resume, - .reset_resume = usb_amradio_resume, - .id_table = usb_amradio_device_table, - .supports_autosuspend = 1, -}; - -/* switch on radio. Send 8 bytes to device. */ -static int amradio_start(struct amradio_device *radio) -{ - int retval; - int size; - - mutex_lock(&radio->lock); - - radio->buffer[0] = 0x00; - radio->buffer[1] = 0x55; - radio->buffer[2] = 0xaa; - radio->buffer[3] = 0x00; - radio->buffer[4] = 0xab; - radio->buffer[5] = 0x00; - radio->buffer[6] = 0x00; - radio->buffer[7] = 0x00; - - retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), - (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - - if (retval) { - mutex_unlock(&radio->lock); - return retval; - } - - mutex_unlock(&radio->lock); - - radio->muted = 0; - - return retval; -} - -/* switch off radio */ -static int amradio_stop(struct amradio_device *radio) -{ - int retval; - int size; - - mutex_lock(&radio->lock); - - radio->buffer[0] = 0x00; - radio->buffer[1] = 0x55; - radio->buffer[2] = 0xaa; - radio->buffer[3] = 0x00; - radio->buffer[4] = 0xab; - radio->buffer[5] = 0x01; - radio->buffer[6] = 0x00; - radio->buffer[7] = 0x00; - - retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), - (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - - if (retval) { - mutex_unlock(&radio->lock); - return retval; - } - - mutex_unlock(&radio->lock); - - radio->muted = 1; - - return retval; -} - -/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ -static int amradio_setfreq(struct amradio_device *radio, int freq) -{ - int retval; - int size; - unsigned short freq_send = 0x13 + (freq >> 3) / 25; - - mutex_lock(&radio->lock); - - radio->buffer[0] = 0x00; - radio->buffer[1] = 0x55; - radio->buffer[2] = 0xaa; - radio->buffer[3] = 0x03; - radio->buffer[4] = 0xa4; - radio->buffer[5] = 0x00; - radio->buffer[6] = 0x00; - radio->buffer[7] = 0x08; - - retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), - (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - - if (retval) { - mutex_unlock(&radio->lock); - return retval; - } - - /* frequency is calculated from freq_send and placed in first 2 bytes */ - radio->buffer[0] = (freq_send >> 8) & 0xff; - radio->buffer[1] = freq_send & 0xff; - radio->buffer[2] = 0x01; - radio->buffer[3] = 0x00; - radio->buffer[4] = 0x00; - /* 5 and 6 bytes of buffer already = 0x00 */ - radio->buffer[7] = 0x00; - - retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), - (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - - if (retval) { - mutex_unlock(&radio->lock); - return retval; - } - - mutex_unlock(&radio->lock); - - radio->stereo = 0; - - return retval; -} - -/* USB subsystem interface begins here */ - -/* handle unplugging of the device, release data structures -if nothing keeps us from doing it. If something is still -keeping us busy, the release callback of v4l will take care -of releasing it. */ -static void usb_amradio_disconnect(struct usb_interface *intf) -{ - struct amradio_device *radio = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - if (radio) { - video_unregister_device(radio->videodev); - radio->videodev = NULL; - if (radio->users) { - kfree(radio->buffer); - kfree(radio); - } else { - radio->removed = 1; - } - } -} - -/* vidioc_querycap - query device capabilities */ -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *v) -{ - strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); - strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); - sprintf(v->bus_info, "USB"); - v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER; - return 0; -} - -/* vidioc_g_tuner - get tuner attributes */ -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - if (v->index > 0) - return -EINVAL; - -/* TODO: Add function which look is signal stereo or not - * amradio_getstat(radio); - */ - radio->stereo = -1; - strcpy(v->name, "FM"); - v->type = V4L2_TUNER_RADIO; - v->rangelow = FREQ_MIN * FREQ_MUL; - v->rangehigh = FREQ_MAX * FREQ_MUL; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - v->capability = V4L2_TUNER_CAP_LOW; - if (radio->stereo) - v->audmode = V4L2_TUNER_MODE_STEREO; - else - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xffff; /* Can't get the signal strength, sad.. */ - v->afc = 0; /* Don't know what is this */ - return 0; -} - -/* vidioc_s_tuner - set tuner attributes */ -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - if (v->index > 0) - return -EINVAL; - return 0; -} - -/* vidioc_s_frequency - set tuner radio frequency */ -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - radio->curfreq = f->frequency; - if (amradio_setfreq(radio, radio->curfreq) < 0) - warn("Set frequency failed"); - return 0; -} - -/* vidioc_g_frequency - get tuner radio frequency */ -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - f->type = V4L2_TUNER_RADIO; - f->frequency = radio->curfreq; - return 0; -} - -/* vidioc_queryctrl - enumerate control items */ -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { - if (qc->id && qc->id == radio_qctrl[i].id) { - memcpy(qc, &(radio_qctrl[i]), - sizeof(*qc)); - return 0; - } - } - return -EINVAL; -} - -/* vidioc_g_ctrl - get the value of a control */ -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = radio->muted; - return 0; - } - return -EINVAL; -} - -/* vidioc_s_ctrl - set the value of a control */ -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) { - if (amradio_stop(radio) < 0) { - warn("amradio_stop() failed"); - return -1; - } - } else { - if (amradio_start(radio) < 0) { - warn("amradio_start() failed"); - return -1; - } - } - return 0; - } - return -EINVAL; -} - -/* vidioc_g_audio - get audio attributes */ -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - if (a->index > 1) - return -EINVAL; - - strcpy(a->name, "Radio"); - a->capability = V4L2_AUDCAP_STEREO; - return 0; -} - -/* vidioc_s_audio - set audio attributes */ -static int vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - if (a->index != 0) - return -EINVAL; - return 0; -} - -/* vidioc_g_input - get input */ -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -/* vidioc_s_input - set input */ -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) -{ - if (i != 0) - return -EINVAL; - return 0; -} - -/* open device - amradio_start() and amradio_setfreq() */ -static int usb_amradio_open(struct inode *inode, struct file *file) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - radio->users = 1; - radio->muted = 1; - - if (amradio_start(radio) < 0) { - warn("Radio did not start up properly"); - radio->users = 0; - return -EIO; - } - if (amradio_setfreq(radio, radio->curfreq) < 0) - warn("Set frequency failed"); - return 0; -} - -/*close device - free driver structures */ -static int usb_amradio_close(struct inode *inode, struct file *file) -{ - struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - - if (!radio) - return -ENODEV; - radio->users = 0; - if (radio->removed) { - kfree(radio->buffer); - kfree(radio); - } - return 0; -} - -/* Suspend device - stop device. Need to be checked and fixed */ -static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct amradio_device *radio = usb_get_intfdata(intf); - - if (amradio_stop(radio) < 0) - warn("amradio_stop() failed"); - - info("radio-mr800: Going into suspend.."); - - return 0; -} - -/* Resume device - start device. Need to be checked and fixed */ -static int usb_amradio_resume(struct usb_interface *intf) -{ - struct amradio_device *radio = usb_get_intfdata(intf); - - if (amradio_start(radio) < 0) - warn("amradio_start() failed"); - - info("radio-mr800: Coming out of suspend.."); - - return 0; -} - -/* File system interface */ -static const struct file_operations usb_amradio_fops = { - .owner = THIS_MODULE, - .open = usb_amradio_open, - .release = usb_amradio_close, - .ioctl = video_ioctl2, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l_compat_ioctl32, -#endif - .llseek = no_llseek, -}; - -static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, -}; - -/* V4L2 interface */ -static struct video_device amradio_videodev_template = { - .name = "AverMedia MR 800 USB FM Radio", - .fops = &usb_amradio_fops, - .ioctl_ops = &usb_amradio_ioctl_ops, - .release = video_device_release, -}; - -/* check if the device is present and register with v4l and -usb if it is */ -static int usb_amradio_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct amradio_device *radio; - - radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL); - - if (!(radio)) - return -ENOMEM; - - radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); - - if (!(radio->buffer)) { - kfree(radio); - return -ENOMEM; - } - - radio->videodev = video_device_alloc(); - - if (!(radio->videodev)) { - kfree(radio->buffer); - kfree(radio); - return -ENOMEM; - } - - memcpy(radio->videodev, &amradio_videodev_template, - sizeof(amradio_videodev_template)); - - radio->removed = 0; - radio->users = 0; - radio->usbdev = interface_to_usbdev(intf); - radio->curfreq = 95.16 * FREQ_MUL; - - mutex_init(&radio->lock); - - video_set_drvdata(radio->videodev, radio); - if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { - warn("Could not register video device"); - video_device_release(radio->videodev); - kfree(radio->buffer); - kfree(radio); - return -EIO; - } - - usb_set_intfdata(intf, radio); - return 0; -} - -static int __init amradio_init(void) -{ - int retval = usb_register(&usb_amradio_driver); - - info(DRIVER_VERSION " " DRIVER_DESC); - if (retval) - err("usb_register failed. Error number %d", retval); - return retval; -} - -static void __exit amradio_exit(void) -{ - usb_deregister(&usb_amradio_driver); -} - -module_init(amradio_init); -module_exit(amradio_exit); - diff --git a/trunk/drivers/media/radio/radio-rtrack2.c b/trunk/drivers/media/radio/radio-rtrack2.c index a67079777419..6d820e2481e7 100644 --- a/trunk/drivers/media/radio/radio-rtrack2.c +++ b/trunk/drivers/media/radio/radio-rtrack2.c @@ -52,7 +52,6 @@ static spinlock_t lock; struct rt_device { - unsigned long in_use; int port; unsigned long curfreq; int muted; @@ -154,7 +153,8 @@ static int rt_getsigstr(struct rt_device *dev) static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; if (v->index > 0) return -EINVAL; @@ -173,7 +173,8 @@ static int vidioc_g_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; rt->curfreq = f->frequency; rt_setfreq(rt, rt->curfreq); @@ -183,7 +184,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = rt->curfreq; @@ -208,7 +210,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -227,7 +230,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rt_device *rt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct rt_device *rt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -280,21 +284,10 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct rt_device rtrack2_unit; -static int rtrack2_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0; -} - -static int rtrack2_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &rtrack2_unit.in_use); - return 0; -} - static const struct file_operations rtrack2_fops = { .owner = THIS_MODULE, - .open = rtrack2_exclusive_open, - .release = rtrack2_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -321,7 +314,6 @@ static struct video_device rtrack2_radio = { .name = "RadioTrack II radio", .fops = &rtrack2_fops, .ioctl_ops = &rtrack2_ioctl_ops, - .release = video_device_release_empty, }; static int __init rtrack2_init(void) @@ -337,7 +329,7 @@ static int __init rtrack2_init(void) return -EBUSY; } - video_set_drvdata(&rtrack2_radio, &rtrack2_unit); + rtrack2_radio.priv=&rtrack2_unit; spin_lock_init(&lock); if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) { diff --git a/trunk/drivers/media/radio/radio-sf16fmi.c b/trunk/drivers/media/radio/radio-sf16fmi.c index 329c90bddadd..0d478f54a907 100644 --- a/trunk/drivers/media/radio/radio-sf16fmi.c +++ b/trunk/drivers/media/radio/radio-sf16fmi.c @@ -45,7 +45,6 @@ static struct v4l2_queryctrl radio_qctrl[] = { struct fmi_device { - unsigned long in_use; int port; int curvol; /* 1 or 0 */ unsigned long curfreq; /* freq in kHz */ @@ -147,7 +146,8 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { int mult; - struct fmi_device *fmi = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmi_device *fmi = dev->priv; if (v->index > 0) return -EINVAL; @@ -175,7 +175,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmi_device *fmi = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmi_device *fmi = dev->priv; if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) f->frequency *= 1000; @@ -192,7 +193,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmi_device *fmi = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmi_device *fmi = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = fmi->curfreq; @@ -219,7 +221,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmi_device *fmi = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmi_device *fmi = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -232,7 +235,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmi_device *fmi = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmi_device *fmi = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -280,21 +284,10 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct fmi_device fmi_unit; -static int fmi_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0; -} - -static int fmi_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &fmi_unit.in_use); - return 0; -} - static const struct file_operations fmi_fops = { .owner = THIS_MODULE, - .open = fmi_exclusive_open, - .release = fmi_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -321,7 +314,6 @@ static struct video_device fmi_radio = { .name = "SF16FMx radio", .fops = &fmi_fops, .ioctl_ops = &fmi_ioctl_ops, - .release = video_device_release_empty, }; /* ladis: this is my card. does any other types exist? */ @@ -381,7 +373,7 @@ static int __init fmi_init(void) fmi_unit.curvol = 0; fmi_unit.curfreq = 0; fmi_unit.flags = V4L2_TUNER_CAP_LOW; - video_set_drvdata(&fmi_radio, &fmi_unit); + fmi_radio.priv = &fmi_unit; mutex_init(&lock); diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c index b1f47c322e02..6290553d24be 100644 --- a/trunk/drivers/media/radio/radio-sf16fmr2.c +++ b/trunk/drivers/media/radio/radio-sf16fmr2.c @@ -64,7 +64,6 @@ static struct v4l2_queryctrl radio_qctrl[] = { /* this should be static vars for module size */ struct fmr2_device { - unsigned long in_use; int port; int curvol; /* 0-15 */ int mute; @@ -230,7 +229,8 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { int mult; - struct fmr2_device *fmr2 = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmr2_device *fmr2 = dev->priv; if (v->index > 0) return -EINVAL; @@ -262,7 +262,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmr2_device *fmr2 = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmr2_device *fmr2 = dev->priv; if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) f->frequency *= 1000; @@ -285,7 +286,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmr2_device *fmr2 = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmr2_device *fmr2 = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = fmr2->curfreq; @@ -311,7 +313,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmr2_device *fmr2 = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmr2_device *fmr2 = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -327,7 +330,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmr2_device *fmr2 = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct fmr2_device *fmr2 = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -396,21 +400,10 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct fmr2_device fmr2_unit; -static int fmr2_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0; -} - -static int fmr2_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &fmr2_unit.in_use); - return 0; -} - static const struct file_operations fmr2_fops = { .owner = THIS_MODULE, - .open = fmr2_exclusive_open, - .release = fmr2_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -437,7 +430,6 @@ static struct video_device fmr2_radio = { .name = "SF16FMR2 radio", .fops = &fmr2_fops, .ioctl_ops = &fmr2_ioctl_ops, - .release = video_device_release_empty, }; static int __init fmr2_init(void) @@ -449,7 +441,7 @@ static int __init fmr2_init(void) fmr2_unit.stereo = 1; fmr2_unit.flags = V4L2_TUNER_CAP_LOW; fmr2_unit.card_type = 0; - video_set_drvdata(&fmr2_radio, &fmr2_unit); + fmr2_radio.priv = &fmr2_unit; mutex_init(&lock); diff --git a/trunk/drivers/media/radio/radio-si470x.c b/trunk/drivers/media/radio/radio-si470x.c index f6cedcd3ab97..16c7ef20265c 100644 --- a/trunk/drivers/media/radio/radio-si470x.c +++ b/trunk/drivers/media/radio/radio-si470x.c @@ -986,7 +986,7 @@ static void si470x_work(struct work_struct *work) static ssize_t si470x_fops_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; unsigned int block_count = 0; @@ -1047,7 +1047,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, static unsigned int si470x_fops_poll(struct file *file, struct poll_table_struct *pts) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* switch on rds reception */ @@ -1071,10 +1071,9 @@ static unsigned int si470x_fops_poll(struct file *file, */ static int si470x_fops_open(struct inode *inode, struct file *file) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; - lock_kernel(); radio->users++; retval = usb_autopm_get_interface(radio->intf); @@ -1091,7 +1090,6 @@ static int si470x_fops_open(struct inode *inode, struct file *file) } done: - unlock_kernel(); return retval; } @@ -1101,7 +1099,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file) */ static int si470x_fops_release(struct inode *inode, struct file *file) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety check */ @@ -1284,7 +1282,7 @@ static int si470x_vidioc_queryctrl(struct file *file, void *priv, static int si470x_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ @@ -1320,7 +1318,7 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ @@ -1407,7 +1405,7 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv, static int si470x_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ @@ -1473,7 +1471,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ @@ -1507,7 +1505,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, static int si470x_vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *freq) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ @@ -1536,7 +1534,7 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, static int si470x_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *freq) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ @@ -1565,7 +1563,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, struct v4l2_hw_freq_seek *seek) { - struct si470x_device *radio = video_drvdata(file); + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; /* safety checks */ diff --git a/trunk/drivers/media/radio/radio-terratec.c b/trunk/drivers/media/radio/radio-terratec.c index 0abb186a9473..0876fecc5f27 100644 --- a/trunk/drivers/media/radio/radio-terratec.c +++ b/trunk/drivers/media/radio/radio-terratec.c @@ -79,7 +79,6 @@ static spinlock_t lock; struct tt_device { - unsigned long in_use; int port; int curvol; unsigned long curfreq; @@ -221,7 +220,8 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct tt_device *tt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct tt_device *tt = dev->priv; if (v->index > 0) return -EINVAL; @@ -248,7 +248,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct tt_device *tt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct tt_device *tt = dev->priv; tt->curfreq = f->frequency; tt_setfreq(tt, tt->curfreq); @@ -258,7 +259,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct tt_device *tt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct tt_device *tt = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = tt->curfreq; @@ -283,7 +285,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct tt_device *tt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct tt_device *tt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -302,7 +305,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct tt_device *tt = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct tt_device *tt = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -352,21 +356,10 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct tt_device terratec_unit; -static int terratec_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0; -} - -static int terratec_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &terratec_unit.in_use); - return 0; -} - static const struct file_operations terratec_fops = { .owner = THIS_MODULE, - .open = terratec_exclusive_open, - .release = terratec_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -393,7 +386,6 @@ static struct video_device terratec_radio = { .name = "TerraTec ActiveRadio", .fops = &terratec_fops, .ioctl_ops = &terratec_ioctl_ops, - .release = video_device_release_empty, }; static int __init terratec_init(void) @@ -409,7 +401,7 @@ static int __init terratec_init(void) return -EBUSY; } - video_set_drvdata(&terratec_radio, &terratec_unit); + terratec_radio.priv=&terratec_unit; spin_lock_init(&lock); diff --git a/trunk/drivers/media/radio/radio-trust.c b/trunk/drivers/media/radio/radio-trust.c index e7b111fcd105..193161956253 100644 --- a/trunk/drivers/media/radio/radio-trust.c +++ b/trunk/drivers/media/radio/radio-trust.c @@ -78,7 +78,6 @@ static __u16 curtreble; static unsigned long curfreq; static int curstereo; static int curmute; -static unsigned long in_use; /* i2c addresses */ #define TDA7318_ADDR 0x88 @@ -337,21 +336,10 @@ static int vidioc_s_audio(struct file *file, void *priv, return 0; } -static int trust_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &in_use) ? -EBUSY : 0; -} - -static int trust_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &in_use); - return 0; -} - static const struct file_operations trust_fops = { .owner = THIS_MODULE, - .open = trust_exclusive_open, - .release = trust_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -378,7 +366,6 @@ static struct video_device trust_radio = { .name = "Trust FM Radio", .fops = &trust_fops, .ioctl_ops = &trust_ioctl_ops, - .release = video_device_release_empty, }; static int __init trust_init(void) diff --git a/trunk/drivers/media/radio/radio-typhoon.c b/trunk/drivers/media/radio/radio-typhoon.c index 952ec35a8415..f8d62cfea774 100644 --- a/trunk/drivers/media/radio/radio-typhoon.c +++ b/trunk/drivers/media/radio/radio-typhoon.c @@ -79,7 +79,7 @@ static struct v4l2_queryctrl radio_qctrl[] = { #endif struct typhoon_device { - unsigned long in_use; + int users; int iobase; int curvol; int muted; @@ -223,7 +223,8 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct typhoon_device *typhoon = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct typhoon_device *typhoon = dev->priv; typhoon->curfreq = f->frequency; typhoon_setfreq(typhoon, typhoon->curfreq); @@ -233,7 +234,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct typhoon_device *typhoon = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct typhoon_device *typhoon = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = typhoon->curfreq; @@ -259,7 +261,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct typhoon_device *typhoon = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct typhoon_device *typhoon = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -275,7 +278,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct typhoon_device *typhoon = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct typhoon_device *typhoon = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -330,21 +334,10 @@ static struct typhoon_device typhoon_unit = .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, }; -static int typhoon_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0; -} - -static int typhoon_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &typhoon_unit.in_use); - return 0; -} - static const struct file_operations typhoon_fops = { .owner = THIS_MODULE, - .open = typhoon_exclusive_open, - .release = typhoon_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -371,7 +364,6 @@ static struct video_device typhoon_radio = { .name = "Typhoon Radio", .fops = &typhoon_fops, .ioctl_ops = &typhoon_ioctl_ops, - .release = video_device_release_empty, }; #ifdef CONFIG_RADIO_TYPHOON_PROC_FS @@ -454,8 +446,9 @@ static int __init typhoon_init(void) return -EBUSY; } - video_set_drvdata(&typhoon_radio, &typhoon_unit); - if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + typhoon_radio.priv = &typhoon_unit; + if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) == -1) + { release_region(io, 8); return -EINVAL; } diff --git a/trunk/drivers/media/radio/radio-zoltrix.c b/trunk/drivers/media/radio/radio-zoltrix.c index 15b10bad6796..51d57ed3b3e1 100644 --- a/trunk/drivers/media/radio/radio-zoltrix.c +++ b/trunk/drivers/media/radio/radio-zoltrix.c @@ -69,7 +69,6 @@ static int io = CONFIG_RADIO_ZOLTRIX_PORT; static int radio_nr = -1; struct zol_device { - unsigned long in_use; int port; int curvol; unsigned long curfreq; @@ -123,11 +122,8 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) unsigned int stereo = dev->stereo; int i; - if (freq == 0) { - printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n"); - return -EINVAL; - } - + if (freq == 0) + return 1; m = (freq / 160 - 8800) * 2; f = (unsigned long long) m + 0x4d1c; @@ -249,7 +245,8 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct zol_device *zol = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct zol_device *zol = dev->priv; if (v->index > 0) return -EINVAL; @@ -279,20 +276,19 @@ static int vidioc_s_tuner(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct zol_device *zol = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct zol_device *zol = dev->priv; zol->curfreq = f->frequency; - if (zol_setfreq(zol, zol->curfreq) != 0) { - printk(KERN_WARNING "zoltrix: Set frequency failed.\n"); - return -EINVAL; - } + zol_setfreq(zol, zol->curfreq); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct zol_device *zol = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct zol_device *zol = dev->priv; f->type = V4L2_TUNER_RADIO; f->frequency = zol->curfreq; @@ -317,7 +313,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct zol_device *zol = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct zol_device *zol = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -333,7 +330,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct zol_device *zol = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct zol_device *zol = dev->priv; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -349,10 +347,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return 0; } zol->stereo = 1; - if (zol_setfreq(zol, zol->curfreq) != 0) { - printk(KERN_WARNING "zoltrix: Set frequency failed.\n"); - return -EINVAL; - } + zol_setfreq(zol, zol->curfreq); #if 0 /* FIXME: Implement stereo/mono switch on V4L2 */ if (v->mode & VIDEO_SOUND_STEREO) { @@ -401,22 +396,11 @@ static int vidioc_s_audio(struct file *file, void *priv, static struct zol_device zoltrix_unit; -static int zoltrix_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0; -} - -static int zoltrix_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &zoltrix_unit.in_use); - return 0; -} - static const struct file_operations zoltrix_fops = { .owner = THIS_MODULE, - .open = zoltrix_exclusive_open, - .release = zoltrix_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -443,7 +427,6 @@ static struct video_device zoltrix_radio = { .name = "Zoltrix Radio Plus", .fops = &zoltrix_fops, .ioctl_ops = &zoltrix_ioctl_ops, - .release = video_device_release_empty, }; static int __init zoltrix_init(void) @@ -457,7 +440,7 @@ static int __init zoltrix_init(void) return -ENXIO; } - video_set_drvdata(&zoltrix_radio, &zoltrix_unit); + zoltrix_radio.priv = &zoltrix_unit; if (!request_region(io, 2, "zoltrix")) { printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); return -EBUSY; diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 47102c2c8250..3e9e0dcd217e 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -34,7 +34,6 @@ config VIDEOBUF_DVB select VIDEOBUF_GEN config VIDEO_BTCX - depends on PCI tristate config VIDEO_IR @@ -72,15 +71,6 @@ config VIDEO_ADV_DEBUG V4L devices. In doubt, say N. -config VIDEO_FIXED_MINOR_RANGES - bool "Enable old-style fixed minor ranges for video devices" - default n - ---help--- - Say Y here to enable the old-style fixed-range minor assignments. - Only useful if you rely on the old behavior and use mknod instead of udev. - - When in doubt, say N. - config VIDEO_HELPER_CHIPS_AUTO bool "Autoselect pertinent encoders/decoders and other helper chips" default y @@ -588,6 +578,13 @@ config VIDEO_SAA5249 To compile this driver as a module, choose M here: the module will be called saa5249. +config TUNER_3036 + tristate "SAB3036 tuner" + depends on I2C && VIDEO_V4L1 + help + Say Y here to include support for Philips SAB3036 compatible tuners. + If in doubt, say N. + config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 @@ -605,7 +602,79 @@ config VIDEO_STRADIS driver for PCI. There is a product page at . -source "drivers/media/video/zoran/Kconfig" +config VIDEO_ZORAN + tristate "Zoran ZR36057/36067 Video For Linux" + depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS + help + Say Y for support for MJPEG capture cards based on the Zoran + 36057/36067 PCI controller chipset. This includes the Iomega + Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is + a driver homepage at . For + more information, check . + + To compile this driver as a module, choose M here: the + module will be called zr36067. + +config VIDEO_ZORAN_DC30 + tristate "Pinnacle/Miro DC30(+) support" + depends on VIDEO_ZORAN + select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback + card. This also supports really old DC10 cards based on the + zr36050 MJPEG codec and zr36016 VFE. + +config VIDEO_ZORAN_ZR36060 + tristate "Zoran ZR36060" + depends on VIDEO_ZORAN + help + Say Y to support Zoran boards based on 36060 chips. + This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 + and 33 R10 and AverMedia 6 boards. + +config VIDEO_ZORAN_BUZ + tristate "Iomega Buz support" + depends on VIDEO_ZORAN_ZR36060 + select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the Iomega Buz MJPEG capture/playback card. + +config VIDEO_ZORAN_DC10 + tristate "Pinnacle/Miro DC10(+) support" + depends on VIDEO_ZORAN_ZR36060 + select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback + card. + +config VIDEO_ZORAN_LML33 + tristate "Linux Media Labs LML33 support" + depends on VIDEO_ZORAN_ZR36060 + select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the Linux Media Labs LML33 MJPEG capture/playback + card. + +config VIDEO_ZORAN_LML33R10 + tristate "Linux Media Labs LML33R10 support" + depends on VIDEO_ZORAN_ZR36060 + select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO + help + support for the Linux Media Labs LML33R10 MJPEG capture/playback + card. + +config VIDEO_ZORAN_AVS6EYES + tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 + select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the AverMedia 6 Eyes video surveillance card. config VIDEO_MEYE tristate "Sony Vaio Picturebook Motion Eye Video For Linux" @@ -628,7 +697,7 @@ config VIDEO_MXB depends on PCI && VIDEO_V4L1 && I2C select VIDEO_SAA7146_VV select VIDEO_TUNER - select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO @@ -639,6 +708,21 @@ config VIDEO_MXB To compile this driver as a module, choose M here: the module will be called mxb. +config VIDEO_DPC + tristate "Philips-Semiconductors 'dpc7146 demonstration board'" + depends on PCI && VIDEO_V4L1 && I2C + select VIDEO_SAA7146_VV + select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO + ---help--- + This is a video4linux driver for the 'dpc7146 demonstration + board' by Philips-Semiconductors. It's the reference design + for SAA7146 bases boards, so if you have some unsupported + saa7146 based, analog video card, chances are good that it + will work with this skeleton driver. + + To compile this driver as a module, choose M here: the + module will be called dpc7146. + config VIDEO_HEXIUM_ORION tristate "Hexium HV-PCI6 and Orion frame grabber" depends on PCI && VIDEO_V4L2 && I2C @@ -700,70 +784,6 @@ config VIDEO_CAFE_CCIC CMOS camera controller. This is the controller found on first- generation OLPC systems. -config SOC_CAMERA - tristate "SoC camera support" - depends on VIDEO_V4L2 && HAS_DMA - select VIDEOBUF_GEN - help - SoC Camera is a common API to several cameras, not connecting - over a bus like PCI or USB. For example some i2c camera connected - directly to the data bus of an SoC. - -config SOC_CAMERA_MT9M001 - tristate "mt9m001 support" - depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9M001_PCA9536_SWITCH - help - This driver supports MT9M001 cameras from Micron, monochrome - and colour models. - -config MT9M001_PCA9536_SWITCH - bool "pca9536 datawidth switch for mt9m001" - depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO - help - Select this if your MT9M001 camera uses a PCA9536 I2C GPIO - extender to switch between 8 and 10 bit datawidth modes - -config SOC_CAMERA_MT9M111 - tristate "mt9m111 support" - depends on SOC_CAMERA && I2C - help - This driver supports MT9M111 cameras from Micron - -config SOC_CAMERA_MT9V022 - tristate "mt9v022 support" - depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9V022_PCA9536_SWITCH - help - This driver supports MT9V022 cameras from Micron - -config MT9V022_PCA9536_SWITCH - bool "pca9536 datawidth switch for mt9v022" - depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO - help - Select this if your MT9V022 camera uses a PCA9536 I2C GPIO - extender to switch between 8 and 10 bit datawidth modes - -config SOC_CAMERA_PLATFORM - tristate "platform camera support" - depends on SOC_CAMERA - help - This is a generic SoC camera platform driver, useful for testing - -config VIDEO_PXA27x - tristate "PXA27x Quick Capture Interface driver" - depends on VIDEO_DEV && PXA27x && SOC_CAMERA - select VIDEOBUF_DMA_SG - ---help--- - This is a v4l2 driver for the PXA27x Quick Capture Interface - -config VIDEO_SH_MOBILE_CEU - tristate "SuperH Mobile CEU Interface driver" - depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA - select VIDEOBUF_DMA_CONTIG - ---help--- - This is a v4l2 driver for the SuperH Mobile CEU Interface - # # USB Multimedia device configuration # @@ -802,7 +822,8 @@ config VIDEO_OVCAMCHIP config USB_W9968CF tristate "USB W996[87]CF JPEG Dual Mode Camera support" - depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP + depends on VIDEO_V4L1 && I2C + select VIDEO_OVCAMCHIP ---help--- Say Y here if you want support for cameras based on OV681 or Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. @@ -893,4 +914,64 @@ config USB_S2255 endif # V4L_USB_DRIVERS +config SOC_CAMERA + tristate "SoC camera support" + depends on VIDEO_V4L2 && HAS_DMA + select VIDEOBUF_GEN + help + SoC Camera is a common API to several cameras, not connecting + over a bus like PCI or USB. For example some i2c camera connected + directly to the data bus of an SoC. + +config SOC_CAMERA_MT9M001 + tristate "mt9m001 support" + depends on SOC_CAMERA && I2C + select GPIO_PCA953X if MT9M001_PCA9536_SWITCH + help + This driver supports MT9M001 cameras from Micron, monochrome + and colour models. + +config MT9M001_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9m001" + depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO + help + Select this if your MT9M001 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + +config SOC_CAMERA_MT9V022 + tristate "mt9v022 support" + depends on SOC_CAMERA && I2C + select GPIO_PCA953X if MT9V022_PCA9536_SWITCH + help + This driver supports MT9V022 cameras from Micron + +config MT9V022_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9v022" + depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO + help + Select this if your MT9V022 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + +config SOC_CAMERA_PLATFORM + tristate "platform camera support" + depends on SOC_CAMERA + help + This is a generic SoC camera platform driver, useful for testing + +config VIDEO_PXA27x + tristate "PXA27x Quick Capture Interface driver" + depends on VIDEO_DEV && PXA27x + select SOC_CAMERA + select VIDEOBUF_DMA_SG + ---help--- + This is a v4l2 driver for the PXA27x Quick Capture Interface + +config VIDEO_SH_MOBILE_CEU + tristate "SuperH Mobile CEU Interface driver" + depends on VIDEO_DEV && HAS_DMA + select SOC_CAMERA + select VIDEOBUF_DMA_CONTIG + ---help--- + This is a v4l2 driver for the SuperH Mobile CEU Interface + endif # VIDEO_CAPTURE_DRIVERS diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index 16962f3aa157..ef7c8d3ffb18 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -2,6 +2,8 @@ # Makefile for the video capture/playback device drivers. # +zr36067-objs := zoran_procfs.o zoran_device.o \ + zoran_driver.o zoran_card.o tuner-objs := tuner-core.o msp3400-objs := msp3400-driver.o msp3400-kthreads.o @@ -52,7 +54,9 @@ obj-$(CONFIG_VIDEO_BT856) += bt856.o obj-$(CONFIG_VIDEO_BT866) += bt866.o obj-$(CONFIG_VIDEO_KS0127) += ks0127.o -obj-$(CONFIG_VIDEO_ZORAN) += zoran/ +obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o +obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o +obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o @@ -80,6 +84,8 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o +obj-$(CONFIG_VIDEO_DPC) += dpc7146.o +obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o @@ -131,7 +137,6 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o -obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o diff --git a/trunk/drivers/media/video/arv.c b/trunk/drivers/media/video/arv.c index 218754b4906a..9e436ad3d34b 100644 --- a/trunk/drivers/media/video/arv.c +++ b/trunk/drivers/media/video/arv.c @@ -116,7 +116,6 @@ struct ar_device { int width, height; int frame_bytes, line_bytes; wait_queue_head_t wait; - unsigned long in_use; struct mutex lock; }; @@ -270,7 +269,7 @@ static inline void wait_for_vertical_sync(int exp_line) static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct video_device *v = video_devdata(file); - struct ar_device *ar = video_get_drvdata(v); + struct ar_device *ar = v->priv; long ret = ar->frame_bytes; /* return read bytes */ unsigned long arvcr1 = 0; unsigned long flags; @@ -400,7 +399,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); - struct ar_device *ar = video_get_drvdata(dev); + struct ar_device *ar = dev->priv; DEBUG(1, "ar_ioctl()\n"); switch(cmd) { @@ -626,7 +625,7 @@ static void ar_interrupt(int irq, void *dev) */ static int ar_initialize(struct video_device *dev) { - struct ar_device *ar = video_get_drvdata(dev); + struct ar_device *ar = dev->priv; unsigned long cr = 0; int i,found=0; @@ -733,7 +732,7 @@ static int ar_initialize(struct video_device *dev) void ar_release(struct video_device *vfd) { - struct ar_device *ar = video_get_drvdata(vfd); + struct ar_device *ar = vfd->priv; mutex_lock(&ar->lock); video_device_release(vfd); } @@ -743,23 +742,10 @@ void ar_release(struct video_device *vfd) * Video4Linux Module functions * ****************************************************************************/ -static struct ar_device ardev; - -static int ar_exclusive_open(struct inode *inode, struct file *file) -{ - return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0; -} - -static int ar_exclusive_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &ardev.in_use); - return 0; -} - static const struct file_operations ar_fops = { .owner = THIS_MODULE, - .open = ar_exclusive_open, - .release = ar_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .read = ar_read, .ioctl = ar_ioctl, #ifdef CONFIG_COMPAT @@ -776,6 +762,7 @@ static struct video_device ar_template = { }; #define ALIGN4(x) ((((int)(x)) & 0x3) == 0) +static struct ar_device ardev; static int __init ar_init(void) { @@ -815,7 +802,7 @@ static int __init ar_init(void) return -ENOMEM; } memcpy(ar->vdev, &ar_template, sizeof(ar_template)); - video_set_drvdata(ar->vdev, ar); + ar->vdev->priv = ar; if (vga) { ar->width = AR_WIDTH_VGA; diff --git a/trunk/drivers/media/video/au0828/au0828-cards.c b/trunk/drivers/media/video/au0828/au0828-cards.c index 5f07a8a072b6..ed48908a9034 100644 --- a/trunk/drivers/media/video/au0828/au0828-cards.c +++ b/trunk/drivers/media/video/au0828/au0828-cards.c @@ -46,7 +46,7 @@ struct au0828_board au0828_boards[] = { /* Tuner callback function for au0828 boards. Currently only needed * for HVR1500Q, which has an xc5000 tuner. */ -int au0828_tuner_callback(void *priv, int component, int command, int arg) +int au0828_tuner_callback(void *priv, int command, int arg) { struct au0828_dev *dev = priv; diff --git a/trunk/drivers/media/video/au0828/au0828-dvb.c b/trunk/drivers/media/video/au0828/au0828-dvb.c index f0fcdb4769d7..ba94be7e0ac1 100644 --- a/trunk/drivers/media/video/au0828/au0828-dvb.c +++ b/trunk/drivers/media/video/au0828/au0828-dvb.c @@ -36,39 +36,11 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define _AU0828_BULKPIPE 0x83 #define _BULKPIPESIZE 0xe522 -static u8 hauppauge_hvr950q_led_states[] = { - 0x00, /* off */ - 0x02, /* yellow */ - 0x04, /* green */ -}; - -static struct au8522_led_config hauppauge_hvr950q_led_cfg = { - .gpio_output = 0x00e0, - .gpio_output_enable = 0x6006, - .gpio_output_disable = 0x0660, - - .gpio_leds = 0x00e2, - .led_states = hauppauge_hvr950q_led_states, - .num_led_states = sizeof(hauppauge_hvr950q_led_states), - - .vsb8_strong = 20 /* dB */ * 10, - .qam64_strong = 25 /* dB */ * 10, - .qam256_strong = 32 /* dB */ * 10, -}; - static struct au8522_config hauppauge_hvr950q_config = { .demod_address = 0x8e >> 1, .status_mode = AU8522_DEMODLOCKING, .qam_if = AU8522_IF_6MHZ, .vsb_if = AU8522_IF_6MHZ, - .led_cfg = &hauppauge_hvr950q_led_cfg, -}; - -static struct au8522_config fusionhdtv7usb_config = { - .demod_address = 0x8e >> 1, - .status_mode = AU8522_DEMODLOCKING, - .qam_if = AU8522_IF_6MHZ, - .vsb_if = AU8522_IF_6MHZ, }; static struct au8522_config hauppauge_woodbury_config = { @@ -81,6 +53,7 @@ static struct au8522_config hauppauge_woodbury_config = { static struct xc5000_config hauppauge_hvr950q_tunerconfig = { .i2c_address = 0x61, .if_khz = 6000, + .tuner_callback = au0828_tuner_callback }; static struct mxl5007t_config mxl5007t_hvr950q_config = { @@ -380,12 +353,14 @@ int au0828_dvb_register(struct au0828_dev *dev) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_DVICO_FUSIONHDTV7: dvb->frontend = dvb_attach(au8522_attach, &hauppauge_hvr950q_config, &dev->i2c_adap); if (dvb->frontend != NULL) - dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, - &hauppauge_hvr950q_tunerconfig); + dvb_attach(xc5000_attach, dvb->frontend, + &dev->i2c_adap, + &hauppauge_hvr950q_tunerconfig, dev); break; case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: dvb->frontend = dvb_attach(au8522_attach, @@ -405,16 +380,6 @@ int au0828_dvb_register(struct au0828_dev *dev) 0x60, &dev->i2c_adap, &hauppauge_woodbury_tunerconfig); break; - case AU0828_BOARD_DVICO_FUSIONHDTV7: - dvb->frontend = dvb_attach(au8522_attach, - &fusionhdtv7usb_config, - &dev->i2c_adap); - if (dvb->frontend != NULL) { - dvb_attach(xc5000_attach, dvb->frontend, - &dev->i2c_adap, - &hauppauge_hvr950q_tunerconfig); - } - break; default: printk(KERN_WARNING "The frontend of your DVB/ATSC card " "isn't supported yet\n"); @@ -425,8 +390,6 @@ int au0828_dvb_register(struct au0828_dev *dev) __func__); return -1; } - /* define general-purpose callback pointer */ - dvb->frontend->callback = au0828_tuner_callback; /* register everything */ ret = dvb_register(dev); diff --git a/trunk/drivers/media/video/au0828/au0828.h b/trunk/drivers/media/video/au0828/au0828.h index 9d6a1161dc98..4f10ff300135 100644 --- a/trunk/drivers/media/video/au0828/au0828.h +++ b/trunk/drivers/media/video/au0828/au0828.h @@ -103,8 +103,7 @@ extern int au0828_debug; extern struct au0828_board au0828_boards[]; extern struct usb_device_id au0828_usb_id_table[]; extern void au0828_gpio_setup(struct au0828_dev *dev); -extern int au0828_tuner_callback(void *priv, int component, - int command, int arg); +extern int au0828_tuner_callback(void *priv, int command, int arg); extern void au0828_card_setup(struct au0828_dev *dev); /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/bt856.c b/trunk/drivers/media/video/bt856.c index ab2ce4d7b5de..98ee2d8feb34 100644 --- a/trunk/drivers/media/video/bt856.c +++ b/trunk/drivers/media/video/bt856.c @@ -68,8 +68,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ -#define BT856_REG_OFFSET 0xDA -#define BT856_NR_REG 6 +#define REG_OFFSET 0xDA +#define BT856_NR_REG 6 struct bt856 { unsigned char reg[BT856_NR_REG]; @@ -89,7 +89,7 @@ bt856_write (struct i2c_client *client, { struct bt856 *encoder = i2c_get_clientdata(client); - encoder->reg[reg - BT856_REG_OFFSET] = value; + encoder->reg[reg - REG_OFFSET] = value; return i2c_smbus_write_byte_data(client, reg, value); } @@ -103,7 +103,7 @@ bt856_setbit (struct i2c_client *client, return bt856_write(client, reg, (encoder-> - reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | + reg[reg - REG_OFFSET] & ~(1 << bit)) | (value ? (1 << bit) : 0)); } diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 13742b0bbe3e..6081edc362df 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -305,7 +305,7 @@ static struct CARD { { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, - { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" }, + { 0, -1, NULL } }; @@ -3037,31 +3037,6 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .has_remote = 1, }, - [BTTV_BOARD_ENLTV_FM_2] = { - /* Encore TV Tuner Pro ENL TV-FM-2 - Mauro Carvalho Chehab IR disabled - bit 18/17 = 00 -> mute - 01 -> enable external audio input - 10 -> internal audio input (mono?) - 11 -> internal audio input - */ - .gpiomask = 0x060040, - .muxsel = { 2, 3, 3 }, - .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 }, - .gpiomute = 0, - .tuner_type = TUNER_TCL_MF02GIP_5N, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .pll = PLL_28, - .has_radio = 1, - .has_remote = 1, - } }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index 5858bf5ff41c..933eaef41ead 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -76,9 +76,9 @@ static unsigned int gbuffers = 8; static unsigned int gbufsize = 0x208000; static unsigned int reset_crop = 1; -static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; -static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; -static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; +static int video_nr = -1; +static int radio_nr = -1; +static int vbi_nr = -1; static int debug_latency; static unsigned int fdsr; @@ -108,6 +108,9 @@ module_param(irq_debug, int, 0644); module_param(debug_latency, int, 0644); module_param(fdsr, int, 0444); +module_param(video_nr, int, 0444); +module_param(radio_nr, int, 0444); +module_param(vbi_nr, int, 0444); module_param(gbuffers, int, 0444); module_param(gbufsize, int, 0444); module_param(reset_crop, int, 0444); @@ -127,10 +130,7 @@ module_param(uv_ratio, int, 0444); module_param(full_luma_range, int, 0444); module_param(coring, int, 0444); -module_param_array(radio, int, NULL, 0444); -module_param_array(video_nr, int, NULL, 0444); -module_param_array(radio_nr, int, NULL, 0444); -module_param_array(vbi_nr, int, NULL, 0444); +module_param_array(radio, int, NULL, 0444); MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)"); MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian"); @@ -152,9 +152,6 @@ MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); -MODULE_PARM_DESC(video_nr, "video device numbers"); -MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); -MODULE_PARM_DESC(radio_nr, "radio device numbers"); MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); @@ -1370,7 +1367,7 @@ static void init_irqreg(struct bttv *btv) (btv->gpioirq ? BT848_INT_GPINT : 0) | BT848_INT_SCERR | (fdsr ? BT848_INT_FDSR : 0) | - BT848_INT_RISCI | BT848_INT_OCERR | + BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES| BT848_INT_FMTCHG|BT848_INT_HLOCK| BT848_INT_I2CDONE, BT848_INT_MASK); @@ -2664,6 +2661,18 @@ static int bttv_querycap(struct file *file, void *priv, return 0; } +static int bttv_enum_fmt_vbi_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (0 != f->index) + return -EINVAL; + + f->pixelformat = V4L2_PIX_FMT_GREY; + strcpy(f->description, "vbi data"); + + return 0; +} + static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) { int index = -1, i; @@ -3218,7 +3227,6 @@ static int bttv_open(struct inode *inode, struct file *file) dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); - lock_kernel(); for (i = 0; i < bttv_num; i++) { if (bttvs[i].video_dev && bttvs[i].video_dev->minor == minor) { @@ -3233,20 +3241,16 @@ static int bttv_open(struct inode *inode, struct file *file) break; } } - if (NULL == btv) { - unlock_kernel(); + if (NULL == btv) return -ENODEV; - } dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", btv->c.nr,v4l2_type_names[type]); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } file->private_data = fh; *fh = btv->init; fh->type = type; @@ -3266,7 +3270,6 @@ static int bttv_open(struct inode *inode, struct file *file) sizeof(struct bttv_buffer), fh); set_tvnorm(btv,btv->tvnorm); - set_input(btv, btv->input, btv->tvnorm); btv->users++; @@ -3287,7 +3290,6 @@ static int bttv_open(struct inode *inode, struct file *file) bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); bttv_field_count(btv); - unlock_kernel(); return 0; } @@ -3328,10 +3330,6 @@ static int bttv_release(struct inode *inode, struct file *file) btv->users--; bttv_field_count(btv); - - if (!btv->users) - audio_mute(btv, 1); - return 0; } @@ -3369,6 +3367,7 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay, .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay, .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay, + .vidioc_enum_fmt_vbi_cap = bttv_enum_fmt_vbi_cap, .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap, @@ -3431,26 +3430,21 @@ static int radio_open(struct inode *inode, struct file *file) dprintk("bttv: open minor=%d\n",minor); - lock_kernel(); for (i = 0; i < bttv_num; i++) { if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) { btv = &bttvs[i]; break; } } - if (NULL == btv) { - unlock_kernel(); + if (NULL == btv) return -ENODEV; - } dprintk("bttv%d: open called (radio)\n",btv->c.nr); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } file->private_data = fh; *fh = btv->init; v4l2_prio_open(&btv->prio, &fh->prio); @@ -3463,7 +3457,6 @@ static int radio_open(struct inode *inode, struct file *file) audio_input(btv,TVAUDIO_INPUT_RADIO); mutex_unlock(&btv->lock); - unlock_kernel(); return 0; } @@ -4242,8 +4235,7 @@ static int __devinit bttv_register_video(struct bttv *btv) if (NULL == btv->video_dev) goto err; - if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, - video_nr[btv->c.nr]) < 0) + if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) goto err; printk(KERN_INFO "bttv%d: registered device video%d\n", btv->c.nr,btv->video_dev->minor & 0x1f); @@ -4259,8 +4251,7 @@ static int __devinit bttv_register_video(struct bttv *btv) if (NULL == btv->vbi_dev) goto err; - if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, - vbi_nr[btv->c.nr]) < 0) + if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) goto err; printk(KERN_INFO "bttv%d: registered device vbi%d\n", btv->c.nr,btv->vbi_dev->minor & 0x1f); @@ -4271,8 +4262,7 @@ static int __devinit bttv_register_video(struct bttv *btv) btv->radio_dev = vdev_init(btv, &radio_template, "radio"); if (NULL == btv->radio_dev) goto err; - if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, - radio_nr[btv->c.nr]) < 0) + if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) goto err; printk(KERN_INFO "bttv%d: registered device radio%d\n", btv->c.nr,btv->radio_dev->minor & 0x1f); diff --git a/trunk/drivers/media/video/bt8xx/bttv-input.c b/trunk/drivers/media/video/bt8xx/bttv-input.c index 2f289d981fe6..a38af98f4cae 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-input.c +++ b/trunk/drivers/media/video/bt8xx/bttv-input.c @@ -28,8 +28,8 @@ #include "bttvp.h" -static int ir_debug; -module_param(ir_debug, int, 0644); +static int debug; +module_param(debug, int, 0644); /* debug level (0,1,2) */ static int repeat_delay = 500; module_param(repeat_delay, int, 0644); static int repeat_period = 33; @@ -40,12 +40,6 @@ module_param(ir_rc5_remote_gap, int, 0644); static int ir_rc5_key_timeout = 200; module_param(ir_rc5_key_timeout, int, 0644); -#undef dprintk -#define dprintk(arg...) do { \ - if (ir_debug >= 1) \ - printk(arg); \ -} while (0) - #define DEVNAME "bttv-input" /* ---------------------------------------------------------------------- */ @@ -85,45 +79,6 @@ static void ir_handle_key(struct bttv *btv) } -static void ir_enltv_handle_key(struct bttv *btv) -{ - struct card_ir *ir = btv->remote; - u32 gpio, data, keyup; - - /* read gpio value */ - gpio = bttv_gpio_read(&btv->c); - - /* extract data */ - data = ir_extract_bits(gpio, ir->mask_keycode); - - /* Check if it is keyup */ - keyup = (gpio & ir->mask_keyup) ? 1 << 31 : 0; - - if ((ir->last_gpio & 0x7f) != data) { - dprintk(KERN_INFO DEVNAME ": gpio=0x%x code=%d | %s\n", - gpio, data, - (gpio & ir->mask_keyup) ? " up" : "up/down"); - - ir_input_keydown(ir->dev, &ir->ir, data, data); - if (keyup) - ir_input_nokey(ir->dev, &ir->ir); - } else { - if ((ir->last_gpio & 1 << 31) == keyup) - return; - - dprintk(KERN_INFO DEVNAME ":(cnt) gpio=0x%x code=%d | %s\n", - gpio, data, - (gpio & ir->mask_keyup) ? " up" : "down"); - - if (keyup) - ir_input_nokey(ir->dev, &ir->ir); - else - ir_input_keydown(ir->dev, &ir->ir, data, data); - } - - ir->last_gpio = data | keyup; -} - void bttv_input_irq(struct bttv *btv) { struct card_ir *ir = btv->remote; @@ -137,10 +92,7 @@ static void bttv_input_timer(unsigned long data) struct bttv *btv = (struct bttv*)data; struct card_ir *ir = btv->remote; - if (btv->c.type == BTTV_BOARD_ENLTV_FM_2) - ir_enltv_handle_key(btv); - else - ir_handle_key(btv); + ir_handle_key(btv); mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } @@ -332,14 +284,6 @@ int bttv_input_init(struct bttv *btv) ir->mask_keyup = 0x006000; ir->polling = 50; /* ms */ break; - case BTTV_BOARD_ENLTV_FM_2: - ir_codes = ir_codes_encore_enltv2; - ir->mask_keycode = 0x00fd00; - ir->mask_keyup = 0x000080; - ir->polling = 1; /* ms */ - ir->last_gpio = ir_extract_bits(bttv_gpio_read(&btv->c), - ir->mask_keycode); - break; } if (NULL == ir_codes) { dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type); diff --git a/trunk/drivers/media/video/bt8xx/bttv.h b/trunk/drivers/media/video/bt8xx/bttv.h index 46cb90e0985b..6d93d16c96e4 100644 --- a/trunk/drivers/media/video/bt8xx/bttv.h +++ b/trunk/drivers/media/video/bt8xx/bttv.h @@ -176,7 +176,7 @@ #define BTTV_BOARD_TYPHOON_TVTUNERPCI 0x95 #define BTTV_BOARD_GEOVISION_GV600 0x96 #define BTTV_BOARD_KOZUMI_KTV_01C 0x97 -#define BTTV_BOARD_ENLTV_FM_2 0x98 + /* more card-specific defines */ #define PT2254_L_CHANNEL 0x10 diff --git a/trunk/drivers/media/video/btcx-risc.c b/trunk/drivers/media/video/btcx-risc.c index ac1b2687a20d..3324ab38f58c 100644 --- a/trunk/drivers/media/video/btcx-risc.c +++ b/trunk/drivers/media/video/btcx-risc.c @@ -64,7 +64,7 @@ int btcx_riscmem_alloc(struct pci_dev *pci, unsigned int size) { __le32 *cpu; - dma_addr_t dma = 0; + dma_addr_t dma; if (NULL != risc->cpu && risc->size < size) btcx_riscmem_free(pci,risc); diff --git a/trunk/drivers/media/video/bw-qcam.c b/trunk/drivers/media/video/bw-qcam.c index ace4ff9ea023..6e39e253ce53 100644 --- a/trunk/drivers/media/video/bw-qcam.c +++ b/trunk/drivers/media/video/bw-qcam.c @@ -495,7 +495,7 @@ static void qc_set(struct qcam_device *q) val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * q->transfer_scale; } - val = DIV_ROUND_UP(val, val2); + val = (val + val2 - 1) / val2; qc_command(q, 0x13); qc_command(q, val); @@ -651,7 +651,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l transperline = q->width * q->bpp; divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * q->transfer_scale; - transperline = DIV_ROUND_UP(transperline, divisor); + transperline = (transperline + divisor - 1) / divisor; for (i = 0, yield = yieldlines; i < linestotrans; i++) { @@ -894,27 +894,10 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static int qcam_exclusive_open(struct inode *inode, struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; -} - -static int qcam_exclusive_release(struct inode *inode, struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - clear_bit(0, &qcam->in_use); - return 0; -} - static const struct file_operations qcam_fops = { .owner = THIS_MODULE, - .open = qcam_exclusive_open, - .release = qcam_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = qcam_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -926,7 +909,6 @@ static struct video_device qcam_template= { .name = "Connectix Quickcam", .fops = &qcam_fops, - .release = video_device_release_empty, }; #define MAX_CAMS 4 diff --git a/trunk/drivers/media/video/bw-qcam.h b/trunk/drivers/media/video/bw-qcam.h index 8a60c5de0935..6701dafbc0da 100644 --- a/trunk/drivers/media/video/bw-qcam.h +++ b/trunk/drivers/media/video/bw-qcam.h @@ -65,5 +65,4 @@ struct qcam_device { int top, left; int status; unsigned int saved_bits; - unsigned long in_use; }; diff --git a/trunk/drivers/media/video/c-qcam.c b/trunk/drivers/media/video/c-qcam.c index 17aa0adb3467..7f6c6b4bec10 100644 --- a/trunk/drivers/media/video/c-qcam.c +++ b/trunk/drivers/media/video/c-qcam.c @@ -51,7 +51,6 @@ struct qcam_device { int contrast, brightness, whitebal; int top, left; unsigned int bidirectional; - unsigned long in_use; struct mutex lock; }; @@ -688,28 +687,11 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static int qcam_exclusive_open(struct inode *inode, struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; -} - -static int qcam_exclusive_release(struct inode *inode, struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - clear_bit(0, &qcam->in_use); - return 0; -} - /* video device template */ static const struct file_operations qcam_fops = { .owner = THIS_MODULE, - .open = qcam_exclusive_open, - .release = qcam_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = qcam_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -722,7 +704,6 @@ static struct video_device qcam_template= { .name = "Colour QuickCam", .fops = &qcam_fops, - .release = video_device_release_empty, }; /* Initialize the QuickCam driver control structure. */ diff --git a/trunk/drivers/media/video/cafe_ccic.c b/trunk/drivers/media/video/cafe_ccic.c index fc9497bdd322..5405c30dbb04 100644 --- a/trunk/drivers/media/video/cafe_ccic.c +++ b/trunk/drivers/media/video/cafe_ccic.c @@ -1476,12 +1476,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) { struct cafe_camera *cam; - lock_kernel(); cam = cafe_find_dev(iminor(inode)); - if (cam == NULL) { - unlock_kernel(); + if (cam == NULL) return -ENODEV; - } filp->private_data = cam; mutex_lock(&cam->s_mutex); @@ -1493,7 +1490,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) } (cam->users)++; mutex_unlock(&cam->s_mutex); - unlock_kernel(); return 0; } @@ -2096,8 +2092,15 @@ static int cafe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int ret; + u16 classword; struct cafe_camera *cam; - + /* + * Make sure we have a camera here - we'll get calls for + * the other cafe devices as well. + */ + pci_read_config_word(pdev, PCI_CLASS_DEVICE, &classword); + if (classword != PCI_CLASS_MULTIMEDIA_VIDEO) + return -ENODEV; /* * Start putting together one of our big camera structures. */ @@ -2285,8 +2288,8 @@ static int cafe_pci_resume(struct pci_dev *pdev) static struct pci_device_id cafe_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, - PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) }, + { PCI_DEVICE(0x11ab, 0x4100) }, /* Eventual real ID */ + { PCI_DEVICE(0x11ab, 0x4102) }, /* Really eventual real ID */ { 0, } }; diff --git a/trunk/drivers/media/video/cpia.c b/trunk/drivers/media/video/cpia.c index 1798b779a25a..a661800b0e69 100644 --- a/trunk/drivers/media/video/cpia.c +++ b/trunk/drivers/media/video/cpia.c @@ -39,6 +39,10 @@ #include #include +#ifdef CONFIG_KMOD +#include +#endif + #include "cpia.h" static int video_nr = -1; @@ -3151,7 +3155,7 @@ static void put_cam(struct cpia_camera_ops* ops) static int cpia_open(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); - struct cam_data *cam = video_get_drvdata(dev); + struct cam_data *cam = dev->priv; int err; if (!cam) { @@ -3198,7 +3202,7 @@ static int cpia_open(struct inode *inode, struct file *file) /* Set ownership of /proc/cpia/videoX to current user */ if(cam->proc_entry) - cam->proc_entry->uid = current_uid(); + cam->proc_entry->uid = current->uid; /* set mark for loading first frame uncompressed */ cam->first_frame = 1; @@ -3228,7 +3232,7 @@ static int cpia_open(struct inode *inode, struct file *file) static int cpia_close(struct inode *inode, struct file *file) { struct video_device *dev = file->private_data; - struct cam_data *cam = video_get_drvdata(dev); + struct cam_data *cam = dev->priv; if (cam->ops) { /* Return ownership of /proc/cpia/videoX to root */ @@ -3280,7 +3284,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct video_device *dev = file->private_data; - struct cam_data *cam = video_get_drvdata(dev); + struct cam_data *cam = dev->priv; int err; /* make this _really_ smp and multithread-safe */ @@ -3337,7 +3341,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, void *arg) { struct video_device *dev = file->private_data; - struct cam_data *cam = video_get_drvdata(dev); + struct cam_data *cam = dev->priv; int retval = 0; if (!cam || !cam->ops) @@ -3735,7 +3739,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) unsigned long start = vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start; unsigned long page, pos; - struct cam_data *cam = video_get_drvdata(dev); + struct cam_data *cam = dev->priv; int retval; if (!cam || !cam->ops) @@ -3797,7 +3801,6 @@ static const struct file_operations cpia_fops = { static struct video_device cpia_template = { .name = "CPiA Camera", .fops = &cpia_fops, - .release = video_device_release_empty, }; /* initialise cam_data structure */ @@ -3925,7 +3928,7 @@ static void init_camera_struct(struct cam_data *cam, cam->proc_entry = NULL; memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template)); - video_set_drvdata(&cam->vdev, cam); + cam->vdev.priv = cam; cam->curframe = 0; for (i = 0; i < FRAME_NUM; i++) { diff --git a/trunk/drivers/media/video/cpia2/cpia2_core.c b/trunk/drivers/media/video/cpia2/cpia2_core.c index 7e791b6923f9..af8b9ec8e358 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_core.c +++ b/trunk/drivers/media/video/cpia2/cpia2_core.c @@ -1537,7 +1537,7 @@ static int config_sensor_500(struct camera_data *cam, * * This sets all user changeable properties to the values in cam->params. *****************************************************************************/ -static int set_all_properties(struct camera_data *cam) +int set_all_properties(struct camera_data *cam) { /** * Don't set target_kb here, it will be set later. @@ -1588,7 +1588,7 @@ void cpia2_save_camera_state(struct camera_data *cam) * get_color_params * *****************************************************************************/ -static void get_color_params(struct camera_data *cam) +void get_color_params(struct camera_data *cam) { cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0); cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0); @@ -1881,7 +1881,7 @@ void cpia2_set_saturation(struct camera_data *cam, unsigned char value) * wake_system * *****************************************************************************/ -static void wake_system(struct camera_data *cam) +void wake_system(struct camera_data *cam) { cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0); } @@ -1892,7 +1892,7 @@ static void wake_system(struct camera_data *cam) * * Valid for STV500 sensor only *****************************************************************************/ -static void set_lowlight_boost(struct camera_data *cam) +void set_lowlight_boost(struct camera_data *cam) { struct cpia2_command cmd; @@ -2169,7 +2169,7 @@ void cpia2_dbg_dump_registers(struct camera_data *cam) * * Sets all values to the defaults *****************************************************************************/ -static void reset_camera_struct(struct camera_data *cam) +void reset_camera_struct(struct camera_data *cam) { /*** * The following parameter values are the defaults from the register map. diff --git a/trunk/drivers/media/video/cpia2/cpia2_usb.c b/trunk/drivers/media/video/cpia2/cpia2_usb.c index 73511a542077..a8a199047cbd 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_usb.c +++ b/trunk/drivers/media/video/cpia2/cpia2_usb.c @@ -478,7 +478,7 @@ int cpia2_usb_change_streaming_alternate(struct camera_data *cam, * set_alternate * *****************************************************************************/ -static int set_alternate(struct camera_data *cam, unsigned int alt) +int set_alternate(struct camera_data *cam, unsigned int alt) { int ret = 0; diff --git a/trunk/drivers/media/video/cpia2/cpia2_v4l.c b/trunk/drivers/media/video/cpia2/cpia2_v4l.c index 897e8d1a5c3c..eb9f15cd4c45 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_v4l.c +++ b/trunk/drivers/media/video/cpia2/cpia2_v4l.c @@ -241,7 +241,8 @@ static struct v4l2_queryctrl controls[] = { *****************************************************************************/ static int cpia2_open(struct inode *inode, struct file *file) { - struct camera_data *cam = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct camera_data *cam = video_get_drvdata(dev); int retval = 0; if (!cam) { @@ -356,7 +357,8 @@ static int cpia2_close(struct inode *inode, struct file *file) static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *off) { - struct camera_data *cam = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct camera_data *cam = video_get_drvdata(dev); int noblock = file->f_flags&O_NONBLOCK; struct cpia2_fh *fh = file->private_data; @@ -380,7 +382,9 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, *****************************************************************************/ static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait) { - struct camera_data *cam = video_drvdata(filp); + struct video_device *dev = video_devdata(filp); + struct camera_data *cam = video_get_drvdata(dev); + struct cpia2_fh *fh = filp->private_data; if(!cam) @@ -1575,7 +1579,8 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) static int cpia2_do_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_nr, void *arg) { - struct camera_data *cam = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct camera_data *cam = video_get_drvdata(dev); int retval = 0; if (!cam) @@ -1855,8 +1860,9 @@ static int cpia2_ioctl(struct inode *inode, struct file *file, *****************************************************************************/ static int cpia2_mmap(struct file *file, struct vm_area_struct *area) { - struct camera_data *cam = video_drvdata(file); int retval; + struct video_device *dev = video_devdata(file); + struct camera_data *cam = video_get_drvdata(dev); /* Priority check */ struct cpia2_fh *fh = file->private_data; diff --git a/trunk/drivers/media/video/cx18/Makefile b/trunk/drivers/media/video/cx18/Makefile index f7bf0edf93f9..b23d2e26120f 100644 --- a/trunk/drivers/media/video/cx18/Makefile +++ b/trunk/drivers/media/video/cx18/Makefile @@ -2,7 +2,7 @@ cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio. cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \ cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \ cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \ - cx18-dvb.o cx18-io.o + cx18-dvb.o obj-$(CONFIG_VIDEO_CX18) += cx18.o diff --git a/trunk/drivers/media/video/cx18/cx18-audio.c b/trunk/drivers/media/video/cx18/cx18-audio.c index 57beddf0af4d..6d5b94fc7087 100644 --- a/trunk/drivers/media/video/cx18/cx18-audio.c +++ b/trunk/drivers/media/video/cx18/cx18-audio.c @@ -22,7 +22,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-i2c.h" #include "cx18-cards.h" #include "cx18-audio.h" @@ -61,10 +60,10 @@ int cx18_audio_set_io(struct cx18 *cx) if (err) return err; - val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; + val = read_reg(CX18_AUDIO_ENABLE) & ~0x30; val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : (audio_input << 4); - cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE); + write_reg(val | 0xb00, CX18_AUDIO_ENABLE); cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.c b/trunk/drivers/media/video/cx18/cx18-av-core.c index 73f5141a42d1..3b0a2c450605 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.c +++ b/trunk/drivers/media/video/cx18/cx18-av-core.c @@ -22,35 +22,27 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" int cx18_av_write(struct cx18 *cx, u16 addr, u8 value) { - u32 reg = 0xc40000 + (addr & ~3); + u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3)); u32 mask = 0xff; int shift = (addr & 3) * 8; - u32 x = cx18_read_reg(cx, reg); x = (x & ~(mask << shift)) | ((u32)value << shift); - cx18_write_reg(cx, x, reg); + writel(x, cx->reg_mem + 0xc40000 + (addr & ~3)); return 0; } int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value) { - cx18_write_reg(cx, value, 0xc40000 + addr); - return 0; -} - -int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value) -{ - cx18_write_reg_noretry(cx, value, 0xc40000 + addr); + writel(value, cx->reg_mem + 0xc40000 + addr); return 0; } u8 cx18_av_read(struct cx18 *cx, u16 addr) { - u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3)); + u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3)); int shift = (addr & 3) * 8; return (x >> shift) & 0xff; @@ -58,12 +50,7 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr) u32 cx18_av_read4(struct cx18 *cx, u16 addr) { - return cx18_read_reg(cx, 0xc40000 + addr); -} - -u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr) -{ - return cx18_read_reg_noretry(cx, 0xc40000 + addr); + return readl(cx->reg_mem + 0xc40000 + addr); } int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask, diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.h b/trunk/drivers/media/video/cx18/cx18-av-core.h index b67d8df20cc6..eb61fa1e0965 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.h +++ b/trunk/drivers/media/video/cx18/cx18-av-core.h @@ -301,10 +301,8 @@ struct cx18_av_state { /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); -int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value); u8 cx18_av_read(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr); -u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); diff --git a/trunk/drivers/media/video/cx18/cx18-av-firmware.c b/trunk/drivers/media/video/cx18/cx18-av-firmware.c index 522a035b2e8f..e996a4e3123a 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-firmware.c +++ b/trunk/drivers/media/video/cx18/cx18-av-firmware.c @@ -20,7 +20,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include #define CX18_AUDIO_ENABLE 0xc72014 @@ -50,7 +49,7 @@ int cx18_av_loadfw(struct cx18 *cx) cx18_av_write4(cx, 0x8100, 0x00010000); /* Put the 8051 in reset and enable firmware upload */ - cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000); + cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000); ptr = fw->data; size = fw->size; @@ -59,28 +58,22 @@ int cx18_av_loadfw(struct cx18 *cx) u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); u32 value = 0; int retries2; - int unrec_err = 0; - for (retries2 = 0; retries2 < CX18_MAX_MMIO_RETRIES; - retries2++) { - cx18_av_write4_noretry(cx, CXADEC_DL_CTL, - dl_control); + for (retries2 = 0; retries2 < 5; retries2++) { + cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); udelay(10); - value = cx18_av_read4_noretry(cx, - CXADEC_DL_CTL); + value = cx18_av_read4(cx, CXADEC_DL_CTL); if (value == dl_control) break; /* Check if we can correct the byte by changing the address. We can only write the lower address byte of the address. */ if ((value & 0x3F00) != (dl_control & 0x3F00)) { - unrec_err = 1; + retries2 = 5; break; } } - cx18_log_write_retries(cx, retries2, - cx->reg_mem + 0xc40000 + CXADEC_DL_CTL); - if (unrec_err || retries2 >= CX18_MAX_MMIO_RETRIES) + if (retries2 >= 5) break; } if (i == size) @@ -126,10 +119,10 @@ int cx18_av_loadfw(struct cx18 *cx) have a name in the spec. */ cx18_av_write4(cx, 0x09CC, 1); - v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); - /* If bit 11 is 1, clear bit 10 */ + v = read_reg(CX18_AUDIO_ENABLE); + /* If bit 11 is 1 */ if (v & 0x800) - cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); + write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */ /* Enable WW auto audio standard detection */ v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); diff --git a/trunk/drivers/media/video/cx18/cx18-cards.c b/trunk/drivers/media/video/cx18/cx18-cards.c index 5efe01ebe9db..3cb9734ec07b 100644 --- a/trunk/drivers/media/video/cx18/cx18-cards.c +++ b/trunk/drivers/media/video/cx18/cx18-cards.c @@ -292,111 +292,12 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { /* ------------------------------------------------------------------------- */ -/* Toshiba Qosmio laptop internal DVB-T/Analog Hybrid Tuner */ - -static const struct cx18_card_pci_info cx18_pci_toshiba_qosmio_dvbt[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_TOSHIBA, 0x0110 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { - .type = CX18_CARD_TOSHIBA_QOSMIO_DVBT, - .name = "Toshiba Qosmio DVB-T/Analog", - .comment = "Experimenters and photos needed for device to work well.\n" - "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_all = CX18_HW_TUNER, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, - }, - .tuners = { - { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, - }, - .ddr = { - .chip_config = 0x202, - .refresh = 0x3bb, - .timing1 = 0x33320a63, - .timing2 = 0x0a, - .tune_lane = 0, - .initial_emrs = 0x42, - }, - .xceive_pin = 15, - .pci_list = cx18_pci_toshiba_qosmio_dvbt, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -/* Leadtek WinFast PVR2100 */ - -static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_leadtek_pvr2100 = { - .type = CX18_CARD_LEADTEK_PVR2100, - .name = "Leadtek WinFast PVR2100", - .comment = "Experimenters and photos needed for device to work well.\n" - "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_muxer = CX18_HW_GPIO, - .hw_all = CX18_HW_TUNER | CX18_HW_GPIO, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, - }, - .tuners = { - /* XC3028 tuner */ - { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, - .ddr = { - /* - * Pointer to proper DDR config values provided by - * Terry Wu - */ - .chip_config = 0x303, - .refresh = 0x3bb, - .timing1 = 0x24220e83, - .timing2 = 0x1f, - .tune_lane = 0, - .initial_emrs = 0x2, - }, - .gpio_init.initial_value = 0x6, - .gpio_init.direction = 0x7, - .gpio_audio_input = { .mask = 0x7, - .tuner = 0x6, .linein = 0x2, .radio = 0x2 }, - .xceive_pin = 15, - .pci_list = cx18_pci_leadtek_pvr2100, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - static const struct cx18_card *cx18_card_list[] = { &cx18_card_hvr1600_esmt, &cx18_card_hvr1600_samsung, &cx18_card_h900, &cx18_card_mpc718, &cx18_card_cnxt_raptor_pal, - &cx18_card_toshiba_qosmio_dvbt, - &cx18_card_leadtek_pvr2100, }; const struct cx18_card *cx18_get_card(u16 index) diff --git a/trunk/drivers/media/video/cx18/cx18-driver.c b/trunk/drivers/media/video/cx18/cx18-driver.c index 085121c2b47f..bd18afebbf86 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.c +++ b/trunk/drivers/media/video/cx18/cx18-driver.c @@ -4,7 +4,6 @@ * Derived from ivtv-driver.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls * * 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 @@ -23,7 +22,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-version.h" #include "cx18-cards.h" #include "cx18-i2c.h" @@ -75,14 +73,10 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -static int mmio_ndelay[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 }; + static unsigned cardtype_c = 1; static unsigned tuner_c = 1; static unsigned radio_c = 1; -static unsigned mmio_ndelay_c = 1; static char pal[] = "--"; static char secam[] = "--"; static char ntsc[] = "-"; @@ -96,18 +90,15 @@ static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS; static int cx18_pci_latency = 1; -int cx18_retry_mmio = 1; int cx18_debug; module_param_array(tuner, int, &tuner_c, 0644); module_param_array(radio, bool, &radio_c, 0644); module_param_array(cardtype, int, &cardtype_c, 0644); -module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644); module_param_string(pal, pal, sizeof(pal), 0644); module_param_string(secam, secam, sizeof(secam), 0644); module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); module_param_named(debug, cx18_debug, int, 0644); -module_param_named(retry_mmio, cx18_retry_mmio, int, 0644); module_param(cx18_pci_latency, int, 0644); module_param(cx18_first_minor, int, 0644); @@ -130,8 +121,6 @@ MODULE_PARM_DESC(cardtype, "\t\t\t 3 = Compro VideoMate H900\n" "\t\t\t 4 = Yuan MPC718\n" "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" - "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" - "\t\t\t 7 = Leadtek WinFast PVR2100\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); @@ -151,14 +140,6 @@ MODULE_PARM_DESC(debug, MODULE_PARM_DESC(cx18_pci_latency, "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" "\t\t\tDefault: Yes"); -MODULE_PARM_DESC(retry_mmio, - "Check and retry memory mapped IO accesses\n" - "\t\t\tDefault: 1 [Yes]"); -MODULE_PARM_DESC(mmio_ndelay, - "Delay (ns) for each CX23418 memory mapped IO access.\n" - "\t\t\tTry larger values that are close to a multiple of the\n" - "\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY)); MODULE_PARM_DESC(enc_mpg_buffers, "Encoder MPG Buffers (in MB)\n" "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS)); @@ -175,7 +156,7 @@ MODULE_PARM_DESC(enc_pcm_buffers, "Encoder PCM buffers (in MB)\n" "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); -MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); +MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card"); MODULE_AUTHOR("Hans Verkuil"); MODULE_DESCRIPTION("CX23418 driver"); @@ -375,11 +356,6 @@ static void cx18_process_options(struct cx18 *cx) cx->options.tuner = tuner[cx->num]; cx->options.radio = radio[cx->num]; - if (mmio_ndelay[cx->num] < 0) - cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY; - else - cx->options.mmio_ndelay = mmio_ndelay[cx->num]; - cx->std = cx18_parse_std(cx); if (cx->options.cardtype == -1) { CX18_INFO("Ignore card\n"); @@ -419,9 +395,9 @@ static void cx18_process_options(struct cx18 *cx) if (cx->card == NULL) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); - CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", + CX18_ERR("Unknown card: vendor/device: %04x/%04x\n", cx->dev->vendor, cx->dev->device); - CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", + CX18_ERR(" subsystem vendor/device: %04x/%04x\n", cx->dev->subsystem_vendor, cx->dev->subsystem_device); CX18_ERR("Defaulting to %s card\n", cx->card->name); CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); @@ -535,9 +511,9 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, return -EIO; } - /* Enable bus mastering and memory mapped IO for the CX23418 */ + /* Check for bus mastering */ pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(dev, PCI_COMMAND, cmd); pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev); @@ -549,6 +525,11 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); } + /* This config space value relates to DMA latencies. The + default value 0x8080 is too low however and will lead + to DMA errors. 0xffff is the max value which solves + these problems. */ + pci_write_config_dword(dev, 0x40, 0xffff); CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " "irq: %d, latency: %d, memory: 0x%lx\n", @@ -675,7 +656,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, goto free_mem; } cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET; - devtype = cx18_read_reg(cx, 0xC72028); + devtype = read_reg(0xC72028); switch (devtype & 0xff000000) { case 0xff000000: CX18_INFO("cx23418 revision %08x (A)\n", devtype); @@ -834,7 +815,6 @@ static int __devinit cx18_probe(struct pci_dev *dev, if (retval == 0) retval = -ENODEV; CX18_ERR("Error %d on initialization\n", retval); - cx18_log_statistics(cx); kfree(cx18_cards[cx18_cards_active]); cx18_cards[cx18_cards_active] = NULL; @@ -922,8 +902,8 @@ static void cx18_remove(struct pci_dev *pci_dev) cx18_stop_all_captures(cx); /* Interrupts */ - cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); - cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); + sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); + sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); cx18_halt_firmware(cx); @@ -939,7 +919,6 @@ static void cx18_remove(struct pci_dev *pci_dev) pci_disable_device(cx->dev); - cx18_log_statistics(cx); CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); } @@ -959,7 +938,7 @@ static int module_start(void) /* Validate parameters */ if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", + printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n", CX18_MAX_CARDS - 1); return -1; } diff --git a/trunk/drivers/media/video/cx18/cx18-driver.h b/trunk/drivers/media/video/cx18/cx18-driver.h index fa8be0731a3f..4801bc7fb5b2 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.h +++ b/trunk/drivers/media/video/cx18/cx18-driver.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -63,9 +64,6 @@ # error "This driver requires kernel PCI support." #endif -/* Default delay to throttle mmio access to the CX23418 */ -#define CX18_DEFAULT_MMIO_NDELAY 0 /* 0 ns = 0 PCI clock(s) / 33 MHz */ - #define CX18_MEM_OFFSET 0x00000000 #define CX18_MEM_SIZE 0x04000000 #define CX18_REG_OFFSET 0x02000000 @@ -79,9 +77,7 @@ #define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */ #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ -#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ -#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ -#define CX18_CARD_LAST 6 +#define CX18_CARD_LAST 4 #define CX18_ENC_STREAM_TYPE_MPG 0 #define CX18_ENC_STREAM_TYPE_TS 1 @@ -101,8 +97,6 @@ #define CX18_PCI_ID_COMPRO 0x185b #define CX18_PCI_ID_YUAN 0x12ab #define CX18_PCI_ID_CONEXANT 0x14f1 -#define CX18_PCI_ID_TOSHIBA 0x1179 -#define CX18_PCI_ID_LEADTEK 0x107D /* ======================================================================== */ /* ========================== START USER SETTABLE DMA VARIABLES =========== */ @@ -175,7 +169,6 @@ #define CX18_MAX_PGM_INDEX (400) -extern int cx18_retry_mmio; /* enable check & retry of mmio accesses */ extern int cx18_debug; @@ -184,7 +177,6 @@ struct cx18_options { int cardtype; /* force card type on load */ int tuner; /* set tuner on load */ int radio; /* enable/disable radio */ - unsigned long mmio_ndelay; /* delay in ns after every PCI mmio access */ }; /* per-buffer bit flags */ @@ -224,7 +216,8 @@ struct cx18_buffer { struct cx18_queue { struct list_head list; - atomic_t buffers; + u32 buffers; + u32 length; u32 bytesused; }; @@ -244,8 +237,6 @@ struct cx18_dvb { struct cx18; /* forward reference */ struct cx18_scb; /* forward reference */ -#define CX18_INVALID_TASK_HANDLE 0xffffffff - struct cx18_stream { /* These first four fields are always set, even if the stream is not actually created. */ @@ -268,6 +259,7 @@ struct cx18_stream { /* Buffer Stats */ u32 buffers; u32 buf_size; + u32 buffers_stolen; /* Buffer Queues */ struct cx18_queue q_free; /* free buffers */ @@ -349,13 +341,6 @@ struct cx18_i2c_algo_callback_data { int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */ }; -#define CX18_MAX_MMIO_RETRIES 10 - -struct cx18_mmio_stats { - atomic_t retried_write[CX18_MAX_MMIO_RETRIES+1]; - atomic_t retried_read[CX18_MAX_MMIO_RETRIES+1]; -}; - /* Struct to hold info about cx18 cards */ struct cx18 { int num; /* board number, -1 during init! */ @@ -445,9 +430,6 @@ struct cx18 { u32 gpio_val; struct mutex gpio_lock; - /* Statistics */ - struct cx18_mmio_stats mmio_stats; - /* v4l2 and User settings */ /* codec settings */ @@ -476,4 +458,47 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv); /* First-open initialization: load firmware, etc. */ int cx18_init_on_first_open(struct cx18 *cx); +/* This is a PCI post thing, where if the pci register is not read, then + the write doesn't always take effect right away. By reading back the + register any pending PCI writes will be performed (in order), and so + you can be sure that the writes are guaranteed to be done. + + Rarely needed, only in some timing sensitive cases. + Apparently if this is not done some motherboards seem + to kill the firmware and get into the broken state until computer is + rebooted. */ +#define write_sync(val, reg) \ + do { writel(val, reg); readl(reg); } while (0) + +#define read_reg(reg) readl(cx->reg_mem + (reg)) +#define write_reg(val, reg) writel(val, cx->reg_mem + (reg)) +#define write_reg_sync(val, reg) \ + do { write_reg(val, reg); read_reg(reg); } while (0) + +#define read_enc(addr) readl(cx->enc_mem + (u32)(addr)) +#define write_enc(val, addr) writel(val, cx->enc_mem + (u32)(addr)) +#define write_enc_sync(val, addr) \ + do { write_enc(val, addr); read_enc(addr); } while (0) + +#define sw1_irq_enable(val) do { \ + write_reg(val, SW1_INT_STATUS); \ + write_reg(read_reg(SW1_INT_ENABLE_PCI) | (val), SW1_INT_ENABLE_PCI); \ +} while (0) + +#define sw1_irq_disable(val) \ + write_reg(read_reg(SW1_INT_ENABLE_PCI) & ~(val), SW1_INT_ENABLE_PCI); + +#define sw2_irq_enable(val) do { \ + write_reg(val, SW2_INT_STATUS); \ + write_reg(read_reg(SW2_INT_ENABLE_PCI) | (val), SW2_INT_ENABLE_PCI); \ +} while (0) + +#define sw2_irq_disable(val) \ + write_reg(read_reg(SW2_INT_ENABLE_PCI) & ~(val), SW2_INT_ENABLE_PCI); + +#define setup_page(addr) do { \ + u32 val = read_reg(0xD000F8) & ~0x1f00; \ + write_reg(val | (((addr) >> 17) & 0x1f00), 0xD000F8); \ +} while (0) + #endif /* CX18_DRIVER_H */ diff --git a/trunk/drivers/media/video/cx18/cx18-dvb.c b/trunk/drivers/media/video/cx18/cx18-dvb.c index afc694e7bdb2..1e420a804fc9 100644 --- a/trunk/drivers/media/video/cx18/cx18-dvb.c +++ b/trunk/drivers/media/video/cx18/cx18-dvb.c @@ -21,7 +21,6 @@ #include "cx18-version.h" #include "cx18-dvb.h" -#include "cx18-io.h" #include "cx18-streams.h" #include "cx18-cards.h" #include "s5h1409.h" @@ -88,13 +87,13 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: - v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL); + v = read_reg(CX18_REG_DMUX_NUM_PORT_0_CONTROL); v |= 0x00400000; /* Serial Mode */ v |= 0x00002000; /* Data Length - Byte */ v |= 0x00010000; /* Error - Polarity */ v |= 0x00020000; /* Error - Passthru */ v |= 0x000c0000; /* Error - Ignore */ - cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); + write_reg(v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); break; default: diff --git a/trunk/drivers/media/video/cx18/cx18-fileops.c b/trunk/drivers/media/video/cx18/cx18-fileops.c index 5f9089907544..1e537fe04a23 100644 --- a/trunk/drivers/media/video/cx18/cx18-fileops.c +++ b/trunk/drivers/media/video/cx18/cx18-fileops.c @@ -132,7 +132,6 @@ static void cx18_dualwatch(struct cx18 *cx) u16 new_stereo_mode; const u16 stereo_mask = 0x0300; const u16 dual = 0x0200; - u32 h; new_stereo_mode = cx->params.audio_properties & stereo_mask; memset(&vt, 0, sizeof(vt)); @@ -144,21 +143,13 @@ static void cx18_dualwatch(struct cx18 *cx) if (new_stereo_mode == cx->dualwatch_stereo_mode) return; - new_bitmap = new_stereo_mode - | (cx->params.audio_properties & ~stereo_mask); + new_bitmap = new_stereo_mode | (cx->params.audio_properties & ~stereo_mask); - CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. " - "new audio_bitmask=0x%ux\n", - cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); + CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n", + cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); - h = cx18_find_handle(cx); - if (h == CX18_INVALID_TASK_HANDLE) { - CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n"); - return; - } - - if (cx18_vapi(cx, - CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) { + if (cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2, + cx18_find_handle(cx), new_bitmap) == 0) { cx->dualwatch_stereo_mode = new_stereo_mode; return; } @@ -232,7 +223,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); /* New buffers might have become available before we were added to the waitqueue */ - if (!atomic_read(&s->q_full.buffers)) + if (!s->q_full.buffers) schedule(); finish_wait(&s->waitq, &wait); if (signal_pending(current)) { @@ -518,7 +509,7 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) CX18_DEBUG_HI_FILE("Encoder poll\n"); poll_wait(filp, &s->waitq, wait); - if (atomic_read(&s->q_full.buffers) || atomic_read(&s->q_io.buffers)) + if (s->q_full.length || s->q_io.length) return POLLIN | POLLRDNORM; if (eof) return POLLHUP; @@ -704,28 +695,20 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) void cx18_mute(struct cx18 *cx) { - u32 h; - if (atomic_read(&cx->ana_capturing)) { - h = cx18_find_handle(cx); - if (h != CX18_INVALID_TASK_HANDLE) - cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1); - else - CX18_ERR("Can't find valid task handle for mute\n"); - } + if (atomic_read(&cx->ana_capturing)) + cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, + cx18_find_handle(cx), 1); CX18_DEBUG_INFO("Mute\n"); } void cx18_unmute(struct cx18 *cx) { - u32 h; if (atomic_read(&cx->ana_capturing)) { - h = cx18_find_handle(cx); - if (h != CX18_INVALID_TASK_HANDLE) { - cx18_msleep_timeout(100, 0); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12); - cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0); - } else - CX18_ERR("Can't find valid task handle for unmute\n"); + cx18_msleep_timeout(100, 0); + cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, + cx18_find_handle(cx), 12); + cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, + cx18_find_handle(cx), 0); } CX18_DEBUG_INFO("Unmute\n"); } diff --git a/trunk/drivers/media/video/cx18/cx18-firmware.c b/trunk/drivers/media/video/cx18/cx18-firmware.c index 51534428cd00..78fadd2ada5d 100644 --- a/trunk/drivers/media/video/cx18/cx18-firmware.c +++ b/trunk/drivers/media/video/cx18/cx18-firmware.c @@ -20,7 +20,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-scb.h" #include "cx18-irq.h" #include "cx18-firmware.h" @@ -114,11 +113,11 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) src = (const u32 *)fw->data; for (i = 0; i < fw->size; i += 4096) { - cx18_setup_page(cx, i); + setup_page(i); for (j = i; j < fw->size && j < i + 4096; j += 4) { /* no need for endianness conversion on the ppc */ - cx18_raw_writel(cx, *src, dst); - if (cx18_raw_readl(cx, dst) != *src) { + __raw_writel(*src, dst); + if (__raw_readl(dst) != *src) { CX18_ERR("Mismatch at offset %x\n", i); release_firmware(fw); return -EIO; @@ -171,15 +170,12 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) if (offset + seghdr.size > sz) break; for (i = 0; i < seghdr.size; i += 4096) { - cx18_setup_page(cx, offset + i); + setup_page(offset + i); for (j = i; j < seghdr.size && j < i + 4096; j += 4) { /* no need for endianness conversion on the ppc */ - cx18_raw_writel(cx, src[(offset + j) / 4], - dst + seghdr.addr + j); - if (cx18_raw_readl(cx, dst + seghdr.addr + j) - != src[(offset + j) / 4]) { - CX18_ERR("Mismatch at offset %x\n", - offset + j); + __raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j); + if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) { + CX18_ERR("Mismatch at offset %x\n", offset + j); release_firmware(fw); return -EIO; } @@ -193,45 +189,43 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) size = fw->size; release_firmware(fw); /* Clear bit0 for APU to start from 0 */ - cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030); + write_reg(read_reg(0xc72030) & ~1, 0xc72030); return size; } void cx18_halt_firmware(struct cx18 *cx) { CX18_DEBUG_INFO("Preparing for firmware halt.\n"); - cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ - cx18_write_reg(cx, 0x00020002, CX18_ADEC_CONTROL); + write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ + write_reg(0x00020002, CX18_ADEC_CONTROL); } void cx18_init_power(struct cx18 *cx, int lowpwr) { /* power-down Spare and AOM PLLs */ /* power-up fast, slow and mpeg PLLs */ - cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN); + write_reg(0x00000008, CX18_PLL_POWER_DOWN); /* ADEC out of sleep */ - cx18_write_reg(cx, 0x00020000, CX18_ADEC_CONTROL); + write_reg(0x00020000, CX18_ADEC_CONTROL); /* The fast clock is at 200/245 MHz */ - cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT); - cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7, - CX18_FAST_CLOCK_PLL_FRAC); + write_reg(lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT); + write_reg(lowpwr ? 0x1EFBF37 : 0x038E3D7, CX18_FAST_CLOCK_PLL_FRAC); - cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST); - cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE); - cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH); + write_reg(2, CX18_FAST_CLOCK_PLL_POST); + write_reg(1, CX18_FAST_CLOCK_PLL_PRESCALE); + write_reg(4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH); /* set slow clock to 125/120 MHz */ - cx18_write_reg(cx, lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT); - cx18_write_reg(cx, lowpwr ? 0xEBAF05 : 0x18618A8, - CX18_SLOW_CLOCK_PLL_FRAC); - cx18_write_reg(cx, 4, CX18_SLOW_CLOCK_PLL_POST); + write_reg(lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT); + write_reg(lowpwr ? 0xEBAF05 : 0x18618A8, CX18_SLOW_CLOCK_PLL_FRAC); + write_reg(4, CX18_SLOW_CLOCK_PLL_POST); /* mpeg clock pll 54MHz */ - cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT); - cx18_write_reg(cx, 0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC); - cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST); + write_reg(0xF, CX18_MPEG_CLOCK_PLL_INT); + write_reg(0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC); + write_reg(8, CX18_MPEG_CLOCK_PLL_POST); /* Defaults */ /* APU = SC or SC/2 = 125/62.5 */ @@ -248,84 +242,81 @@ void cx18_init_power(struct cx18 *cx, int lowpwr) /* VFC = disabled */ /* USB = disabled */ - cx18_write_reg(cx, lowpwr ? 0xFFFF0020 : 0x00060004, - CX18_CLOCK_SELECT1); - cx18_write_reg(cx, lowpwr ? 0xFFFF0004 : 0x00060006, - CX18_CLOCK_SELECT2); + write_reg(lowpwr ? 0xFFFF0020 : 0x00060004, CX18_CLOCK_SELECT1); + write_reg(lowpwr ? 0xFFFF0004 : 0x00060006, CX18_CLOCK_SELECT2); - cx18_write_reg(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1); - cx18_write_reg(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2); + write_reg(0xFFFF0002, CX18_HALF_CLOCK_SELECT1); + write_reg(0xFFFF0104, CX18_HALF_CLOCK_SELECT2); - cx18_write_reg(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1); - cx18_write_reg(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2); + write_reg(0xFFFF9026, CX18_CLOCK_ENABLE1); + write_reg(0xFFFF3105, CX18_CLOCK_ENABLE2); } void cx18_init_memory(struct cx18 *cx) { cx18_msleep_timeout(10, 0); - cx18_write_reg(cx, 0x10000, CX18_DDR_SOFT_RESET); + write_reg(0x10000, CX18_DDR_SOFT_RESET); cx18_msleep_timeout(10, 0); - cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG); + write_reg(cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG); cx18_msleep_timeout(10, 0); - cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH); - cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1); - cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2); + write_reg(cx->card->ddr.refresh, CX18_DDR_REFRESH); + write_reg(cx->card->ddr.timing1, CX18_DDR_TIMING1); + write_reg(cx->card->ddr.timing2, CX18_DDR_TIMING2); cx18_msleep_timeout(10, 0); /* Initialize DQS pad time */ - cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE); - cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS); + write_reg(cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE); + write_reg(cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS); cx18_msleep_timeout(10, 0); - cx18_write_reg(cx, 0x20000, CX18_DDR_SOFT_RESET); + write_reg(0x20000, CX18_DDR_SOFT_RESET); cx18_msleep_timeout(10, 0); /* use power-down mode when idle */ - cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG); - - cx18_write_reg(cx, 0x10001, CX18_REG_BUS_TIMEOUT_EN); - - cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7); - cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR); - - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */ + write_reg(0x00000010, CX18_DDR_POWER_REG); + + write_reg(0x10001, CX18_REG_BUS_TIMEOUT_EN); + + write_reg(0x48, CX18_DDR_MB_PER_ROW_7); + write_reg(0xE0000, CX18_DDR_BASE_63_ADDR); + + write_reg(0x00000101, CX18_WMB_CLIENT02); /* AO */ + write_reg(0x00000101, CX18_WMB_CLIENT09); /* AI2 */ + write_reg(0x00000101, CX18_WMB_CLIENT05); /* VIM1 */ + write_reg(0x00000101, CX18_WMB_CLIENT06); /* AI1 */ + write_reg(0x00000101, CX18_WMB_CLIENT07); /* 3D comb */ + write_reg(0x00000101, CX18_WMB_CLIENT10); /* ME */ + write_reg(0x00000101, CX18_WMB_CLIENT12); /* ENC */ + write_reg(0x00000101, CX18_WMB_CLIENT13); /* PK */ + write_reg(0x00000101, CX18_WMB_CLIENT11); /* RC */ + write_reg(0x00000101, CX18_WMB_CLIENT14); /* AVO */ } int cx18_firmware_init(struct cx18 *cx) { /* Allow chip to control CLKRUN */ - cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK); + write_reg(0x5, CX18_DSP0_INTERRUPT_MASK); - cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ + write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */ cx18_msleep_timeout(1, 0); - cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); - cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); + sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); + sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); /* Only if the processor is not running */ - if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) { + if (read_reg(CX18_PROC_SOFT_RESET) & 8) { int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx); - cx18_write_enc(cx, 0xE51FF004, 0); - cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */ - /* Start APU */ - cx18_write_reg(cx, 0x00010000, CX18_PROC_SOFT_RESET); + write_enc(0xE51FF004, 0); + write_enc(0xa00000, 4); /* todo: not hardcoded */ + write_reg(0x00010000, CX18_PROC_SOFT_RESET); /* Start APU */ cx18_msleep_timeout(500, 0); sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", @@ -335,10 +326,9 @@ int cx18_firmware_init(struct cx18 *cx) int retries = 0; /* start the CPU */ - cx18_write_reg(cx, 0x00080000, CX18_PROC_SOFT_RESET); + write_reg(0x00080000, CX18_PROC_SOFT_RESET); while (retries++ < 50) { /* Loop for max 500mS */ - if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) - & 1) == 0) + if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0) break; cx18_msleep_timeout(10, 0); } @@ -352,6 +342,6 @@ int cx18_firmware_init(struct cx18 *cx) return -EIO; } /* initialize GPIO */ - cx18_write_reg(cx, 0x14001400, 0xC78110); + write_reg(0x14001400, 0xC78110); return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.c b/trunk/drivers/media/video/cx18/cx18-gpio.c index 0e560421989e..3d495dba4983 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.c +++ b/trunk/drivers/media/video/cx18/cx18-gpio.c @@ -22,7 +22,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-cards.h" #include "cx18-gpio.h" #include "tuner-xc2028.h" @@ -50,11 +49,11 @@ static void gpio_write(struct cx18 *cx) u32 dir = cx->gpio_dir; u32 val = cx->gpio_val; - cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); - cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff), + write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); + write_reg(((dir & 0xffff) << 16) | (val & 0xffff), CX18_REG_GPIO_OUT1); - cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2); - cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16), + write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); + write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), CX18_REG_GPIO_OUT2); } @@ -142,17 +141,15 @@ void cx18_gpio_init(struct cx18 *cx) } CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", - cx18_read_reg(cx, CX18_REG_GPIO_DIR1), - cx18_read_reg(cx, CX18_REG_GPIO_DIR2), - cx18_read_reg(cx, CX18_REG_GPIO_OUT1), - cx18_read_reg(cx, CX18_REG_GPIO_OUT2)); + read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), + read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); gpio_write(cx); mutex_unlock(&cx->gpio_lock); } /* Xceive tuner reset function */ -int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) +int cx18_reset_tuner_gpio(void *dev, int cmd, int value) { struct i2c_algo_bit_data *algo = dev; struct cx18_i2c_algo_callback_data *cb_data = algo->data; diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.h b/trunk/drivers/media/video/cx18/cx18-gpio.h index beb7424b9944..22cd7ddf8554 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.h +++ b/trunk/drivers/media/video/cx18/cx18-gpio.h @@ -23,5 +23,5 @@ void cx18_gpio_init(struct cx18 *cx); void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); void cx18_reset_ir_gpio(void *data); -int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value); +int cx18_reset_tuner_gpio(void *dev, int cmd, int value); int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff --git a/trunk/drivers/media/video/cx18/cx18-i2c.c b/trunk/drivers/media/video/cx18/cx18-i2c.c index aa09e557b195..6023ba3bd3a6 100644 --- a/trunk/drivers/media/video/cx18/cx18-i2c.c +++ b/trunk/drivers/media/video/cx18/cx18-i2c.c @@ -22,12 +22,13 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-cards.h" #include "cx18-gpio.h" #include "cx18-av-core.h" #include "cx18-i2c.h" +#include + #define CX18_REG_I2C_1_WR 0xf15000 #define CX18_REG_I2C_1_RD 0xf15008 #define CX18_REG_I2C_2_WR 0xf25100 @@ -157,12 +158,12 @@ static void cx18_setscl(void *data, int state) struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; - u32 r = cx18_read_reg(cx, addr); + u32 r = read_reg(addr); if (state) - cx18_write_reg_sync(cx, r | SETSCL_BIT, addr); + write_reg_sync(r | SETSCL_BIT, addr); else - cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr); + write_reg_sync(r & ~SETSCL_BIT, addr); } static void cx18_setsda(void *data, int state) @@ -170,12 +171,12 @@ static void cx18_setsda(void *data, int state) struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; - u32 r = cx18_read_reg(cx, addr); + u32 r = read_reg(addr); if (state) - cx18_write_reg_sync(cx, r | SETSDL_BIT, addr); + write_reg_sync(r | SETSDL_BIT, addr); else - cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr); + write_reg_sync(r & ~SETSDL_BIT, addr); } static int cx18_getscl(void *data) @@ -184,7 +185,7 @@ static int cx18_getscl(void *data) int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; - return cx18_read_reg(cx, addr) & GETSCL_BIT; + return read_reg(addr) & GETSCL_BIT; } static int cx18_getsda(void *data) @@ -193,7 +194,7 @@ static int cx18_getsda(void *data) int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; - return cx18_read_reg(cx, addr) & GETSDL_BIT; + return read_reg(addr) & GETSDL_BIT; } /* template for i2c-bit-algo */ @@ -393,33 +394,29 @@ int init_cx18_i2c(struct cx18 *cx) cx->i2c_adap[i].dev.parent = &cx->dev->dev; } - if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) { + if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) { /* Reset/Unreset I2C hardware block */ - /* Clock select 220MHz */ - cx18_write_reg(cx, 0x10000000, 0xc71004); - /* Clock Enable */ - cx18_write_reg_sync(cx, 0x10001000, 0xc71024); + write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */ + write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */ } /* courtesy of Steven Toth */ - cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c); + write_reg_sync(0x00c00000, 0xc7001c); mdelay(10); - cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c); + write_reg_sync(0x00c000c0, 0xc7001c); mdelay(10); - cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c); + write_reg_sync(0x00c00000, 0xc7001c); mdelay(10); - /* Set to edge-triggered intrs. */ - cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8); - /* Clear any stale intrs */ - cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4); + write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */ + write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */ /* Hw I2C1 Clock Freq ~100kHz */ - cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR); + write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR); cx18_setscl(&cx->i2c_algo_cb_data[0], 1); cx18_setsda(&cx->i2c_algo_cb_data[0], 1); /* Hw I2C2 Clock Freq ~100kHz */ - cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR); + write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR); cx18_setscl(&cx->i2c_algo_cb_data[1], 1); cx18_setsda(&cx->i2c_algo_cb_data[1], 1); @@ -433,10 +430,8 @@ void exit_cx18_i2c(struct cx18 *cx) { int i; CX18_DEBUG_I2C("i2c exit\n"); - cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4, - CX18_REG_I2C_1_WR); - cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4, - CX18_REG_I2C_2_WR); + write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR); + write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR); for (i = 0; i < 2; i++) { i2c_del_adapter(&cx->i2c_adap[i]); diff --git a/trunk/drivers/media/video/cx18/cx18-io.c b/trunk/drivers/media/video/cx18/cx18-io.c deleted file mode 100644 index 700ab9439c16..000000000000 --- a/trunk/drivers/media/video/cx18/cx18-io.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * cx18 driver PCI memory mapped IO access routines - * - * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls - * - * 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 "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-irq.h" - -void cx18_log_statistics(struct cx18 *cx) -{ - int i; - - if (!(cx18_debug & CX18_DBGFLG_INFO)) - return; - - for (i = 0; i <= CX18_MAX_MMIO_RETRIES; i++) - CX18_DEBUG_INFO("retried_write[%d] = %d\n", i, - atomic_read(&cx->mmio_stats.retried_write[i])); - for (i = 0; i <= CX18_MAX_MMIO_RETRIES; i++) - CX18_DEBUG_INFO("retried_read[%d] = %d\n", i, - atomic_read(&cx->mmio_stats.retried_read[i])); - return; -} - -void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - cx18_raw_writel_noretry(cx, val, addr); - if (val == cx18_raw_readl_noretry(cx, addr)) - break; - } - cx18_log_write_retries(cx, i, addr); -} - -u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr) -{ - int i; - u32 val; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - val = cx18_raw_readl_noretry(cx, addr); - if (val != 0xffffffff) /* PCI bus read error */ - break; - } - cx18_log_read_retries(cx, i, addr); - return val; -} - -u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr) -{ - int i; - u16 val; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - val = cx18_raw_readw_noretry(cx, addr); - if (val != 0xffff) /* PCI bus read error */ - break; - } - cx18_log_read_retries(cx, i, addr); - return val; -} - -void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - cx18_writel_noretry(cx, val, addr); - if (val == cx18_readl_noretry(cx, addr)) - break; - } - cx18_log_write_retries(cx, i, addr); -} - -void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - cx18_writew_noretry(cx, val, addr); - if (val == cx18_readw_noretry(cx, addr)) - break; - } - cx18_log_write_retries(cx, i, addr); -} - -void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - cx18_writeb_noretry(cx, val, addr); - if (val == cx18_readb_noretry(cx, addr)) - break; - } - cx18_log_write_retries(cx, i, addr); -} - -u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr) -{ - int i; - u32 val; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - val = cx18_readl_noretry(cx, addr); - if (val != 0xffffffff) /* PCI bus read error */ - break; - } - cx18_log_read_retries(cx, i, addr); - return val; -} - -u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr) -{ - int i; - u16 val; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - val = cx18_readw_noretry(cx, addr); - if (val != 0xffff) /* PCI bus read error */ - break; - } - cx18_log_read_retries(cx, i, addr); - return val; -} - -u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr) -{ - int i; - u8 val; - for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { - val = cx18_readb_noretry(cx, addr); - if (val != 0xff) /* PCI bus read error */ - break; - } - cx18_log_read_retries(cx, i, addr); - return val; -} - -void cx18_memcpy_fromio(struct cx18 *cx, void *to, - const void __iomem *from, unsigned int len) -{ - const u8 __iomem *src = from; - u8 *dst = to; - - /* Align reads on the CX23418's addresses */ - if ((len > 0) && ((unsigned long) src & 1)) { - *dst = cx18_readb(cx, src); - len--; - dst++; - src++; - } - if ((len > 1) && ((unsigned long) src & 2)) { - *((u16 *)dst) = cx18_raw_readw(cx, src); - len -= 2; - dst += 2; - src += 2; - } - while (len > 3) { - *((u32 *)dst) = cx18_raw_readl(cx, src); - len -= 4; - dst += 4; - src += 4; - } - if (len > 1) { - *((u16 *)dst) = cx18_raw_readw(cx, src); - len -= 2; - dst += 2; - src += 2; - } - if (len > 0) - *dst = cx18_readb(cx, src); -} - -void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) -{ - u8 __iomem *dst = addr; - u16 val2 = val | (val << 8); - u32 val4 = val2 | (val2 << 16); - - /* Align writes on the CX23418's addresses */ - if ((count > 0) && ((unsigned long)dst & 1)) { - cx18_writeb(cx, (u8) val, dst); - count--; - dst++; - } - if ((count > 1) && ((unsigned long)dst & 2)) { - cx18_writew(cx, val2, dst); - count -= 2; - dst += 2; - } - while (count > 3) { - cx18_writel(cx, val4, dst); - count -= 4; - dst += 4; - } - if (count > 1) { - cx18_writew(cx, val2, dst); - count -= 2; - dst += 2; - } - if (count > 0) - cx18_writeb(cx, (u8) val, dst); -} - -void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) -{ - u32 r; - cx18_write_reg(cx, val, SW1_INT_STATUS); - r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); - cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); -} - -void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) -{ - u32 r; - r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); - cx18_write_reg(cx, r & ~val, SW1_INT_ENABLE_PCI); -} - -void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) -{ - u32 r; - cx18_write_reg(cx, val, SW2_INT_STATUS); - r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); - cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); -} - -void cx18_sw2_irq_disable(struct cx18 *cx, u32 val) -{ - u32 r; - r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); - cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI); -} - -void cx18_setup_page(struct cx18 *cx, u32 addr) -{ - u32 val; - val = cx18_read_reg(cx, 0xD000F8); - val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00); - cx18_write_reg(cx, val, 0xD000F8); -} diff --git a/trunk/drivers/media/video/cx18/cx18-io.h b/trunk/drivers/media/video/cx18/cx18-io.h deleted file mode 100644 index 197d4fbd9f95..000000000000 --- a/trunk/drivers/media/video/cx18/cx18-io.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - * cx18 driver PCI memory mapped IO access routines - * - * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls - * - * 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 - */ - -#ifndef CX18_IO_H -#define CX18_IO_H - -#include "cx18-driver.h" - -static inline void cx18_io_delay(struct cx18 *cx) -{ - if (cx->options.mmio_ndelay) - ndelay(cx->options.mmio_ndelay); -} - -/* - * Readback and retry of MMIO access for reliability: - * The concept was suggested by Steve Toth . - * The implmentation is the fault of Andy Walls . - */ - -/* Statistics gathering */ -static inline -void cx18_log_write_retries(struct cx18 *cx, int i, const void *addr) -{ - if (i > CX18_MAX_MMIO_RETRIES) - i = CX18_MAX_MMIO_RETRIES; - atomic_inc(&cx->mmio_stats.retried_write[i]); - return; -} - -static inline -void cx18_log_read_retries(struct cx18 *cx, int i, const void *addr) -{ - if (i > CX18_MAX_MMIO_RETRIES) - i = CX18_MAX_MMIO_RETRIES; - atomic_inc(&cx->mmio_stats.retried_read[i]); - return; -} - -void cx18_log_statistics(struct cx18 *cx); - -/* Non byteswapping memory mapped IO */ -static inline -void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - __raw_writel(val, addr); - cx18_io_delay(cx); -} - -void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr); - -static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr) -{ - if (cx18_retry_mmio) - cx18_raw_writel_retry(cx, val, addr); - else - cx18_raw_writel_noretry(cx, val, addr); -} - - -static inline -u32 cx18_raw_readl_noretry(struct cx18 *cx, const void __iomem *addr) -{ - u32 ret = __raw_readl(addr); - cx18_io_delay(cx); - return ret; -} - -u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr); - -static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr) -{ - if (cx18_retry_mmio) - return cx18_raw_readl_retry(cx, addr); - - return cx18_raw_readl_noretry(cx, addr); -} - - -static inline -u16 cx18_raw_readw_noretry(struct cx18 *cx, const void __iomem *addr) -{ - u16 ret = __raw_readw(addr); - cx18_io_delay(cx); - return ret; -} - -u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr); - -static inline u16 cx18_raw_readw(struct cx18 *cx, const void __iomem *addr) -{ - if (cx18_retry_mmio) - return cx18_raw_readw_retry(cx, addr); - - return cx18_raw_readw_noretry(cx, addr); -} - - -/* Normal memory mapped IO */ -static inline -void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - writel(val, addr); - cx18_io_delay(cx); -} - -void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr); - -static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) -{ - if (cx18_retry_mmio) - cx18_writel_retry(cx, val, addr); - else - cx18_writel_noretry(cx, val, addr); -} - - -static inline -void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) -{ - writew(val, addr); - cx18_io_delay(cx); -} - -void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr); - -static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr) -{ - if (cx18_retry_mmio) - cx18_writew_retry(cx, val, addr); - else - cx18_writew_noretry(cx, val, addr); -} - - -static inline -void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr) -{ - writeb(val, addr); - cx18_io_delay(cx); -} - -void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr); - -static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr) -{ - if (cx18_retry_mmio) - cx18_writeb_retry(cx, val, addr); - else - cx18_writeb_noretry(cx, val, addr); -} - - -static inline u32 cx18_readl_noretry(struct cx18 *cx, const void __iomem *addr) -{ - u32 ret = readl(addr); - cx18_io_delay(cx); - return ret; -} - -u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr); - -static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr) -{ - if (cx18_retry_mmio) - return cx18_readl_retry(cx, addr); - - return cx18_readl_noretry(cx, addr); -} - - -static inline u16 cx18_readw_noretry(struct cx18 *cx, const void __iomem *addr) -{ - u16 ret = readw(addr); - cx18_io_delay(cx); - return ret; -} - -u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr); - -static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr) -{ - if (cx18_retry_mmio) - return cx18_readw_retry(cx, addr); - - return cx18_readw_noretry(cx, addr); -} - - -static inline u8 cx18_readb_noretry(struct cx18 *cx, const void __iomem *addr) -{ - u8 ret = readb(addr); - cx18_io_delay(cx); - return ret; -} - -u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr); - -static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr) -{ - if (cx18_retry_mmio) - return cx18_readb_retry(cx, addr); - - return cx18_readb_noretry(cx, addr); -} - - -static inline -u32 cx18_write_sync_noretry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - cx18_writel_noretry(cx, val, addr); - return cx18_readl_noretry(cx, addr); -} - -static inline -u32 cx18_write_sync_retry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - cx18_writel_retry(cx, val, addr); - return cx18_readl_retry(cx, addr); -} - -static inline u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr) -{ - if (cx18_retry_mmio) - return cx18_write_sync_retry(cx, val, addr); - - return cx18_write_sync_noretry(cx, val, addr); -} - - -void cx18_memcpy_fromio(struct cx18 *cx, void *to, - const void __iomem *from, unsigned int len); -void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count); - - -/* Access "register" region of CX23418 memory mapped I/O */ -static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg) -{ - cx18_writel_noretry(cx, val, cx->reg_mem + reg); -} - -static inline void cx18_write_reg_retry(struct cx18 *cx, u32 val, u32 reg) -{ - cx18_writel_retry(cx, val, cx->reg_mem + reg); -} - -static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) -{ - if (cx18_retry_mmio) - cx18_write_reg_retry(cx, val, reg); - else - cx18_write_reg_noretry(cx, val, reg); -} - - -static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg) -{ - return cx18_readl_noretry(cx, cx->reg_mem + reg); -} - -static inline u32 cx18_read_reg_retry(struct cx18 *cx, u32 reg) -{ - return cx18_readl_retry(cx, cx->reg_mem + reg); -} - -static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg) -{ - if (cx18_retry_mmio) - return cx18_read_reg_retry(cx, reg); - - return cx18_read_reg_noretry(cx, reg); -} - - -static inline u32 cx18_write_reg_sync_noretry(struct cx18 *cx, u32 val, u32 reg) -{ - return cx18_write_sync_noretry(cx, val, cx->reg_mem + reg); -} - -static inline u32 cx18_write_reg_sync_retry(struct cx18 *cx, u32 val, u32 reg) -{ - return cx18_write_sync_retry(cx, val, cx->reg_mem + reg); -} - -static inline u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg) -{ - if (cx18_retry_mmio) - return cx18_write_reg_sync_retry(cx, val, reg); - - return cx18_write_reg_sync_noretry(cx, val, reg); -} - - -/* Access "encoder memory" region of CX23418 memory mapped I/O */ -static inline void cx18_write_enc_noretry(struct cx18 *cx, u32 val, u32 addr) -{ - cx18_writel_noretry(cx, val, cx->enc_mem + addr); -} - -static inline void cx18_write_enc_retry(struct cx18 *cx, u32 val, u32 addr) -{ - cx18_writel_retry(cx, val, cx->enc_mem + addr); -} - -static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr) -{ - if (cx18_retry_mmio) - cx18_write_enc_retry(cx, val, addr); - else - cx18_write_enc_noretry(cx, val, addr); -} - - -static inline u32 cx18_read_enc_noretry(struct cx18 *cx, u32 addr) -{ - return cx18_readl_noretry(cx, cx->enc_mem + addr); -} - -static inline u32 cx18_read_enc_retry(struct cx18 *cx, u32 addr) -{ - return cx18_readl_retry(cx, cx->enc_mem + addr); -} - -static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr) -{ - if (cx18_retry_mmio) - return cx18_read_enc_retry(cx, addr); - - return cx18_read_enc_noretry(cx, addr); -} - -static inline -u32 cx18_write_enc_sync_noretry(struct cx18 *cx, u32 val, u32 addr) -{ - return cx18_write_sync_noretry(cx, val, cx->enc_mem + addr); -} - -static inline -u32 cx18_write_enc_sync_retry(struct cx18 *cx, u32 val, u32 addr) -{ - return cx18_write_sync_retry(cx, val, cx->enc_mem + addr); -} - -static inline -u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr) -{ - if (cx18_retry_mmio) - return cx18_write_enc_sync_retry(cx, val, addr); - - return cx18_write_enc_sync_noretry(cx, val, addr); -} - -void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); -void cx18_sw1_irq_disable(struct cx18 *cx, u32 val); -void cx18_sw2_irq_enable(struct cx18 *cx, u32 val); -void cx18_sw2_irq_disable(struct cx18 *cx, u32 val); -void cx18_setup_page(struct cx18 *cx, u32 addr); - -#endif /* CX18_IO_H */ diff --git a/trunk/drivers/media/video/cx18/cx18-ioctl.c b/trunk/drivers/media/video/cx18/cx18-ioctl.c index f0ca50f5fdde..a7f839631d6a 100644 --- a/trunk/drivers/media/video/cx18/cx18-ioctl.c +++ b/trunk/drivers/media/video/cx18/cx18-ioctl.c @@ -22,7 +22,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-version.h" #include "cx18-mailbox.h" #include "cx18-i2c.h" @@ -171,6 +170,7 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; + int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; @@ -202,7 +202,8 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; int ret; - int w, h; + int w = fmt->fmt.pix.width; + int h = fmt->fmt.pix.height; ret = v4l2_prio_check(&cx->prio, &id->prio); if (ret) @@ -211,8 +212,6 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, ret = cx18_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; - w = fmt->fmt.pix.width; - h = fmt->fmt.pix.height; if (cx->params.width == w && cx->params.height == h) return 0; @@ -287,9 +286,9 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) spin_lock_irqsave(&cx18_cards_lock, flags); if (cmd == VIDIOC_DBG_G_REGISTER) - regs->val = cx18_read_enc(cx, regs->reg); + regs->val = read_enc(regs->reg); else - cx18_write_enc(cx, regs->val, regs->reg); + write_enc(regs->val, regs->reg); spin_unlock_irqrestore(&cx18_cards_lock, flags); return 0; } @@ -346,7 +345,7 @@ static int cx18_querycap(struct file *file, void *fh, strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev)); + strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info)); vcap->version = CX18_DRIVER_VERSION; /* version */ vcap->capabilities = cx->v4l2_cap; /* capabilities */ return 0; @@ -623,7 +622,6 @@ static int cx18_encoder_cmd(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; - u32 h; switch (enc->cmd) { case V4L2_ENC_CMD_START: @@ -645,14 +643,8 @@ static int cx18_encoder_cmd(struct file *file, void *fh, return -EPERM; if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; - h = cx18_find_handle(cx); - if (h == CX18_INVALID_TASK_HANDLE) { - CX18_ERR("Can't find valid task handle for " - "V4L2_ENC_CMD_PAUSE\n"); - return -EBADFD; - } cx18_mute(cx); - cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h); + cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx)); break; case V4L2_ENC_CMD_RESUME: @@ -662,13 +654,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, return -EPERM; if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; - h = cx18_find_handle(cx); - if (h == CX18_INVALID_TASK_HANDLE) { - CX18_ERR("Can't find valid task handle for " - "V4L2_ENC_CMD_RESUME\n"); - return -EBADFD; - } - cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); + cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx)); cx18_unmute(cx); break; @@ -745,14 +731,12 @@ static int cx18_log_status(struct file *file, void *fh) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, - (s->buffers - atomic_read(&s->q_free.buffers)) - * 100 / s->buffers, + (s->buffers - s->q_free.buffers) * 100 / s->buffers, (s->buffers * s->buf_size) / 1024, s->buffers); } CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)cx->mpg_data_received, (long long)cx->vbi_data_inserted); - cx18_log_statistics(cx); CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-irq.c b/trunk/drivers/media/video/cx18/cx18-irq.c index 360330f5463f..ab218315c84b 100644 --- a/trunk/drivers/media/video/cx18/cx18-irq.c +++ b/trunk/drivers/media/video/cx18/cx18-irq.c @@ -20,7 +20,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-firmware.h" #include "cx18-fileops.h" #include "cx18-queue.h" @@ -49,8 +48,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) break; } if (i == CX18_MAX_STREAMS) { - CX18_WARN("Got DMA done notification for unknown/inactive" - " handle %d\n", handle); + CX18_WARN("DMA done for unknown handle %d for stream %s\n", + handle, s->name); mb->error = CXERR_NOT_OPEN; mb->cmd = 0; cx18_mb_ack(cx, mb); @@ -61,8 +60,8 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) if (mb->args[2] != 1) CX18_WARN("Ack struct = %d for %s\n", mb->args[2], s->name); - id = cx18_read_enc(cx, off); - buf = cx18_queue_get_buf_irq(s, id, cx18_read_enc(cx, off + 4)); + id = read_enc(off); + buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); if (buf) { cx18_buf_sync_for_cpu(s, buf); @@ -82,7 +81,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); } else { CX18_WARN("Could not find buf %d for stream %s\n", - cx18_read_enc(cx, off), s->name); + read_enc(off), s->name); } mb->error = 0; mb->cmd = 0; @@ -98,8 +97,8 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb) char *p; if (mb->args[1]) { - cx18_setup_page(cx, mb->args[1]); - cx18_memcpy_fromio(cx, str, cx->enc_mem + mb->args[1], 252); + setup_page(mb->args[1]); + memcpy_fromio(str, cx->enc_mem + mb->args[1], 252); str[252] = 0; } cx18_mb_ack(cx, mb); @@ -114,7 +113,7 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1) struct cx18_mailbox mb; if (sw1 & IRQ_CPU_TO_EPU) { - cx18_memcpy_fromio(cx, &mb, &cx->scb->cpu2epu_mb, sizeof(mb)); + memcpy_fromio(&mb, &cx->scb->cpu2epu_mb, sizeof(mb)); mb.error = 0; switch (mb.cmd) { @@ -142,16 +141,16 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) spin_lock(&cx->dma_reg_lock); - hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); - hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; - sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; - sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; - sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; - sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; + hw2_mask = read_reg(HW2_INT_MASK5_PCI); + hw2 = read_reg(HW2_INT_CLR_STATUS) & hw2_mask; + sw2_mask = read_reg(SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; + sw2 = read_reg(SW2_INT_STATUS) & sw2_mask; + sw1_mask = read_reg(SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; + sw1 = read_reg(SW1_INT_STATUS) & sw1_mask; - cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS); - cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS); - cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); + write_reg(sw2&sw2_mask, SW2_INT_STATUS); + write_reg(sw1&sw1_mask, SW1_INT_STATUS); + write_reg(hw2&hw2_mask, HW2_INT_CLR_STATUS); if (sw1 || sw2 || hw2) CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); @@ -162,15 +161,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) */ if (sw2) { - if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) | - cx18_readl(cx, &cx->scb->cpu2epu_irq_ack))) + if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) | + readl(&cx->scb->cpu2epu_irq_ack))) wake_up(&cx->mb_cpu_waitq); - if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) | - cx18_readl(cx, &cx->scb->apu2epu_irq_ack))) + if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) | + readl(&cx->scb->apu2epu_irq_ack))) wake_up(&cx->mb_apu_waitq); - if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack)) + if (sw2 & readl(&cx->scb->epu2hpu_irq_ack)) wake_up(&cx->mb_epu_waitq); - if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack)) + if (sw2 & readl(&cx->scb->hpu2epu_irq_ack)) wake_up(&cx->mb_hpu_waitq); } diff --git a/trunk/drivers/media/video/cx18/cx18-mailbox.c b/trunk/drivers/media/video/cx18/cx18-mailbox.c index 9d18dd22de76..93177514e846 100644 --- a/trunk/drivers/media/video/cx18/cx18-mailbox.c +++ b/trunk/drivers/media/video/cx18/cx18-mailbox.c @@ -22,7 +22,6 @@ #include #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-scb.h" #include "cx18-irq.h" #include "cx18-mailbox.h" @@ -83,7 +82,6 @@ static const struct cx18_api_info api_info[] = { API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), - API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0), API_ENTRY(0, 0, 0), }; @@ -107,20 +105,20 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu switch (rpu) { case APU: mb = &cx->scb->epu2apu_mb; - *state = cx18_readl(cx, &cx->scb->apu_state); - *irq = cx18_readl(cx, &cx->scb->epu2apu_irq); + *state = readl(&cx->scb->apu_state); + *irq = readl(&cx->scb->epu2apu_irq); break; case CPU: mb = &cx->scb->epu2cpu_mb; - *state = cx18_readl(cx, &cx->scb->cpu_state); - *irq = cx18_readl(cx, &cx->scb->epu2cpu_irq); + *state = readl(&cx->scb->cpu_state); + *irq = readl(&cx->scb->epu2cpu_irq); break; case HPU: mb = &cx->scb->epu2hpu_mb; - *state = cx18_readl(cx, &cx->scb->hpu_state); - *irq = cx18_readl(cx, &cx->scb->epu2hpu_irq); + *state = readl(&cx->scb->hpu_state); + *irq = readl(&cx->scb->epu2hpu_irq); break; } @@ -128,8 +126,8 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu return mb; do { - *req = cx18_readl(cx, &mb->request); - ack = cx18_readl(cx, &mb->ack); + *req = readl(&mb->request); + ack = readl(&mb->ack); wait_count++; } while (*req != ack && wait_count < 600); @@ -174,9 +172,9 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) return -EINVAL; } - cx18_setup_page(cx, SCB_OFFSET); - cx18_write_sync(cx, mb->request, &ack_mb->ack); - cx18_write_reg(cx, ack_irq, SW2_INT_SET); + setup_page(SCB_OFFSET); + write_sync(mb->request, &ack_mb->ack); + write_reg(ack_irq, SW2_INT_SET); return 0; } @@ -201,7 +199,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) CX18_DEBUG_HI_API("%s\n", info->name); else CX18_DEBUG_API("%s\n", info->name); - cx18_setup_page(cx, SCB_OFFSET); + setup_page(SCB_OFFSET); mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req); if (mb == NULL) { @@ -210,11 +208,11 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) } oldreq = req - 1; - cx18_writel(cx, cmd, &mb->cmd); + writel(cmd, &mb->cmd); for (i = 0; i < args; i++) - cx18_writel(cx, data[i], &mb->args[i]); - cx18_writel(cx, 0, &mb->error); - cx18_writel(cx, req, &mb->request); + writel(data[i], &mb->args[i]); + writel(0, &mb->error); + writel(req, &mb->request); switch (info->rpu) { case APU: waitq = &cx->mb_apu_waitq; break; @@ -225,10 +223,9 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) } if (info->flags & API_FAST) timeout /= 2; - cx18_write_reg(cx, irq, SW1_INT_SET); + write_reg(irq, SW1_INT_SET); - while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) - && cnt < 660) { + while (!sig && readl(&mb->ack) != readl(&mb->request) && cnt < 660) { if (cnt > 200 && !in_atomic()) sig = cx18_msleep_timeout(10, 1); cnt++; @@ -236,13 +233,13 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) if (sig) return -EINTR; if (cnt == 660) { - cx18_writel(cx, oldreq, &mb->request); + writel(oldreq, &mb->request); CX18_ERR("mb %s failed\n", info->name); return -EINVAL; } for (i = 0; i < MAX_MB_ARGUMENTS; i++) - data[i] = cx18_readl(cx, &mb->args[i]); - err = cx18_readl(cx, &mb->error); + data[i] = readl(&mb->args[i]); + err = readl(&mb->error); if (!in_atomic() && (info->flags & API_SLOW)) cx18_msleep_timeout(300, 0); if (err) diff --git a/trunk/drivers/media/video/cx18/cx18-queue.c b/trunk/drivers/media/video/cx18/cx18-queue.c index a33ba04a2686..dbe792ac3001 100644 --- a/trunk/drivers/media/video/cx18/cx18-queue.c +++ b/trunk/drivers/media/video/cx18/cx18-queue.c @@ -37,7 +37,8 @@ void cx18_buf_swap(struct cx18_buffer *buf) void cx18_queue_init(struct cx18_queue *q) { INIT_LIST_HEAD(&q->list); - atomic_set(&q->buffers, 0); + q->buffers = 0; + q->length = 0; q->bytesused = 0; } @@ -54,7 +55,8 @@ void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, } spin_lock_irqsave(&s->qlock, flags); list_add_tail(&buf->list, &q->list); - atomic_inc(&q->buffers); + q->buffers++; + q->length += s->buf_size; q->bytesused += buf->bytesused - buf->readpos; spin_unlock_irqrestore(&s->qlock, flags); } @@ -68,7 +70,8 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) if (!list_empty(&q->list)) { buf = list_entry(q->list.next, struct cx18_buffer, list); list_del_init(q->list.next); - atomic_dec(&q->buffers); + q->buffers--; + q->length -= s->buf_size; q->bytesused -= buf->bytesused - buf->readpos; } spin_unlock_irqrestore(&s->qlock, flags); @@ -92,8 +95,10 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, /* the transport buffers are handled differently, they are not moved to the full queue */ if (s->type != CX18_ENC_STREAM_TYPE_TS) { - atomic_dec(&s->q_free.buffers); - atomic_inc(&s->q_full.buffers); + s->q_free.buffers--; + s->q_free.length -= s->buf_size; + s->q_full.buffers++; + s->q_full.length += s->buf_size; s->q_full.bytesused += buf->bytesused; list_move_tail(&buf->list, &s->q_full.list); } @@ -119,7 +124,8 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) buf = list_entry(q->list.next, struct cx18_buffer, list); list_move_tail(q->list.next, &s->q_free.list); buf->bytesused = buf->readpos = buf->b_flags = 0; - atomic_inc(&s->q_free.buffers); + s->q_free.buffers++; + s->q_free.length += s->buf_size; } cx18_queue_init(q); spin_unlock_irqrestore(&s->qlock, flags); diff --git a/trunk/drivers/media/video/cx18/cx18-scb.c b/trunk/drivers/media/video/cx18/cx18-scb.c index f56d3772aa67..30bc803e30da 100644 --- a/trunk/drivers/media/video/cx18/cx18-scb.c +++ b/trunk/drivers/media/video/cx18/cx18-scb.c @@ -20,103 +20,102 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-scb.h" void cx18_init_scb(struct cx18 *cx) { - cx18_setup_page(cx, SCB_OFFSET); - cx18_memset_io(cx, cx->scb, 0, 0x10000); + setup_page(SCB_OFFSET); + memset_io(cx->scb, 0, 0x10000); - cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack); + writel(IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq); + writel(IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack); + writel(IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq); + writel(IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack); + writel(IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq); + writel(IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack); + writel(IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq); + writel(IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack); - cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack); + writel(IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq); + writel(IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack); + writel(IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq); + writel(IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack); + writel(IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq); + writel(IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack); + writel(IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq); + writel(IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack); - cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack); - cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack); + writel(IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq); + writel(IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack); + writel(IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq); + writel(IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack); + writel(IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq); + writel(IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack); + writel(IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq); + writel(IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack); - cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack); - cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack); + writel(IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq); + writel(IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack); + writel(IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq); + writel(IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack); + writel(IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq); + writel(IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack); + writel(IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq); + writel(IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack); - cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack); - cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack); + writel(IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq); + writel(IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack); + writel(IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq); + writel(IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack); + writel(IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq); + writel(IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack); + writel(IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq); + writel(IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb), &cx->scb->apu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb), &cx->scb->hpu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb), &cx->scb->ppu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb), &cx->scb->epu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb), &cx->scb->cpu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb), &cx->scb->hpu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb), &cx->scb->ppu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb), &cx->scb->epu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb), &cx->scb->cpu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb), &cx->scb->apu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb), &cx->scb->ppu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb), &cx->scb->epu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb), &cx->scb->cpu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb), &cx->scb->apu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb), &cx->scb->hpu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb), &cx->scb->epu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb), &cx->scb->cpu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb), &cx->scb->apu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb), &cx->scb->hpu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb), + writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb), &cx->scb->ppu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state), + writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu_state), &cx->scb->ipc_offset); - cx18_writel(cx, 1, &cx->scb->hpu_state); - cx18_writel(cx, 1, &cx->scb->epu_state); + writel(1, &cx->scb->hpu_state); + writel(1, &cx->scb->epu_state); } diff --git a/trunk/drivers/media/video/cx18/cx18-streams.c b/trunk/drivers/media/video/cx18/cx18-streams.c index 0c8e7542cf60..0da57f583bf7 100644 --- a/trunk/drivers/media/video/cx18/cx18-streams.c +++ b/trunk/drivers/media/video/cx18/cx18-streams.c @@ -22,7 +22,6 @@ */ #include "cx18-driver.h" -#include "cx18-io.h" #include "cx18-fileops.h" #include "cx18-mailbox.h" #include "cx18-i2c.h" @@ -57,7 +56,7 @@ static struct file_operations cx18_v4l2_enc_fops = { static struct { const char *name; int vfl_type; - int num_offset; + int minor_offset; int dma; enum v4l2_buf_type buf_type; struct file_operations *fops; @@ -120,7 +119,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) s->cx = cx; s->type = type; s->name = cx18_stream_info[type].name; - s->handle = CX18_INVALID_TASK_HANDLE; + s->handle = 0xffffffff; s->dma = cx18_stream_info[type].dma; s->buf_size = cx->stream_buf_size[type]; @@ -144,8 +143,8 @@ static int cx18_prep_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; u32 cap = cx->v4l2_cap; - int num_offset = cx18_stream_info[type].num_offset; - int num = cx->num + cx18_first_minor + num_offset; + int minor_offset = cx18_stream_info[type].minor_offset; + int minor; /* These four fields are always initialized. If v4l2dev == NULL, then this stream is not in use. In that case no other fields but these @@ -164,6 +163,9 @@ static int cx18_prep_dev(struct cx18 *cx, int type) !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) return 0; + /* card number + user defined offset + device offset */ + minor = cx->num + cx18_first_minor + minor_offset; + /* User explicitly selected 0 buffers for these streams, so don't create them. */ if (cx18_stream_info[type].dma != PCI_DMA_NONE && @@ -174,7 +176,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) cx18_stream_init(cx, type); - if (num_offset == -1) + if (minor_offset == -1) return 0; /* allocate and initialize the v4l2 video device structure */ @@ -188,7 +190,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", cx->num); - s->v4l2dev->num = num; + s->v4l2dev->minor = minor; s->v4l2dev->parent = &cx->dev->dev; s->v4l2dev->fops = cx18_stream_info[type].fops; s->v4l2dev->release = video_device_release; @@ -224,7 +226,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; int vfl_type = cx18_stream_info[type].vfl_type; - int num; + int minor; /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? * We need a VFL_TYPE_TS defined. @@ -242,44 +244,38 @@ static int cx18_reg_dev(struct cx18 *cx, int type) if (s->v4l2dev == NULL) return 0; - num = s->v4l2dev->num; - /* card number + user defined offset + device offset */ - if (type != CX18_ENC_STREAM_TYPE_MPG) { - struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; - - if (s_mpg->v4l2dev) - num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset; - } + minor = s->v4l2dev->minor; /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, num)) { - CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", - s->name, num); + if (video_register_device(s->v4l2dev, vfl_type, minor) && + video_register_device(s->v4l2dev, vfl_type, -1)) { + CX18_ERR("Couldn't register v4l2 device for %s minor %d\n", + s->name, minor); video_device_release(s->v4l2dev); s->v4l2dev = NULL; return -ENOMEM; } - num = s->v4l2dev->num; + minor = s->v4l2dev->minor; switch (vfl_type) { case VFL_TYPE_GRABBER: CX18_INFO("Registered device video%d for %s (%d MB)\n", - num, s->name, cx->options.megabytes[type]); + minor, s->name, cx->options.megabytes[type]); break; case VFL_TYPE_RADIO: CX18_INFO("Registered device radio%d for %s\n", - num, s->name); + minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); break; case VFL_TYPE_VBI: if (cx->options.megabytes[type]) CX18_INFO("Registered device vbi%d for %s (%d MB)\n", - num, + minor - MINOR_VFL_TYPE_VBI_MIN, s->name, cx->options.megabytes[type]); else CX18_INFO("Registered device vbi%d for %s\n", - num, s->name); + minor - MINOR_VFL_TYPE_VBI_MIN, s->name); break; } @@ -436,6 +432,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) default: return -EINVAL; } + s->buffers_stolen = 0; /* mute/unmute video */ cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, @@ -473,7 +470,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) if (atomic_read(&cx->tot_capturing) == 0) { clear_bit(CX18_F_I_EOS, &cx->i_flags); - cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK); + write_reg(7, CX18_DSP0_INTERRUPT_MASK); } cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, @@ -483,9 +480,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) list_for_each(p, &s->q_free.list) { struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); - cx18_writel(cx, buf->dma_handle, - &cx->scb->cpu_mdl[buf->id].paddr); - cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); + writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); + writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1, buf->id, s->buf_size); @@ -493,14 +489,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) /* begin_capture */ if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { CX18_DEBUG_WARN("Error starting capture!\n"); - /* Ensure we're really not capturing before releasing MDLs */ - if (s->type == CX18_ENC_STREAM_TYPE_MPG) - cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); - else - cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); - cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); - /* FIXME - clean-up DSP0_INT mask, i_flags, s_flags, etc. */ return -EINVAL; } @@ -552,9 +541,6 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); } - /* Tell the CX23418 it can't use our buffers anymore */ - cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); - if (s->type != CX18_ENC_STREAM_TYPE_TS) atomic_dec(&cx->ana_capturing); atomic_dec(&cx->tot_capturing); @@ -563,12 +549,12 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) clear_bit(CX18_F_S_STREAMING, &s->s_flags); cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); - s->handle = CX18_INVALID_TASK_HANDLE; + s->handle = 0xffffffff; if (atomic_read(&cx->tot_capturing) > 0) return 0; - cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); + write_reg(5, CX18_DSP0_INTERRUPT_MASK); wake_up(&s->waitq); return 0; @@ -582,8 +568,8 @@ u32 cx18_find_handle(struct cx18 *cx) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) + if (s->v4l2dev && s->handle) return s->handle; } - return CX18_INVALID_TASK_HANDLE; + return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-version.h b/trunk/drivers/media/video/cx18/cx18-version.h index 9f6be2d457fb..d5c7a6f968dd 100644 --- a/trunk/drivers/media/video/cx18/cx18-version.h +++ b/trunk/drivers/media/video/cx18/cx18-version.h @@ -25,7 +25,7 @@ #define CX18_DRIVER_NAME "cx18" #define CX18_DRIVER_VERSION_MAJOR 1 #define CX18_DRIVER_VERSION_MINOR 0 -#define CX18_DRIVER_VERSION_PATCHLEVEL 1 +#define CX18_DRIVER_VERSION_PATCHLEVEL 0 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) #define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \ diff --git a/trunk/drivers/media/video/cx18/cx23418.h b/trunk/drivers/media/video/cx18/cx23418.h index 668f968d7761..e7ed053059a8 100644 --- a/trunk/drivers/media/video/cx18/cx23418.h +++ b/trunk/drivers/media/video/cx18/cx23418.h @@ -351,7 +351,7 @@ Descriptor Lists to the driver IN[0] - Task handle. Handle of the task to start ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006) +/* #define CX18_CPU_DE_ReleaseMDL (CPU_CMD_MASK_DE | 0x0006) */ /* Description: This command signals the cpu that the dat buffer has been consumed and ready for re-use. diff --git a/trunk/drivers/media/video/cx2341x.c b/trunk/drivers/media/video/cx2341x.c index cbbe47fb87b7..22847a0444f5 100644 --- a/trunk/drivers/media/video/cx2341x.c +++ b/trunk/drivers/media/video/cx2341x.c @@ -508,10 +508,7 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, /* this setting is read-only for the cx2341x since the V4L2_CID_MPEG_STREAM_TYPE really determines the MPEG-1/2 setting */ - err = v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2); + err = v4l2_ctrl_query_fill_std(qctrl); if (err == 0) qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; return err; diff --git a/trunk/drivers/media/video/cx23885/Kconfig b/trunk/drivers/media/video/cx23885/Kconfig index 8c1b7fa47a41..e60bd31b51a3 100644 --- a/trunk/drivers/media/video/cx23885/Kconfig +++ b/trunk/drivers/media/video/cx23885/Kconfig @@ -15,7 +15,6 @@ config VIDEO_CX23885 select DVB_S5H1409 if !DVB_FE_CUSTOMISE select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE diff --git a/trunk/drivers/media/video/cx23885/cx23885-417.c b/trunk/drivers/media/video/cx23885/cx23885-417.c index 395c11fa47ce..7b0e8c01692e 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-417.c +++ b/trunk/drivers/media/video/cx23885/cx23885-417.c @@ -36,6 +36,7 @@ #include #include "cx23885.h" +#include "media/cx2341x.h" #define CX23885_FIRM_IMAGE_SIZE 376836 #define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -631,7 +632,7 @@ int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value) /* ------------------------------------------------------------------ */ /* MPEG encoder API */ -static char *cmd_to_str(int cmd) +char *cmd_to_str(int cmd) { switch (cmd) { case CX2341X_ENC_PING_FW: @@ -1582,7 +1583,6 @@ static int mpeg_open(struct inode *inode, struct file *file) dprintk(2, "%s()\n", __func__); - lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); if (h->v4l_device->minor == minor) { @@ -1591,17 +1591,13 @@ static int mpeg_open(struct inode *inode, struct file *file) } } - if (dev == NULL) { - unlock_kernel(); + if (dev == NULL) return -ENODEV; - } /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } file->private_data = fh; fh->dev = dev; @@ -1612,7 +1608,6 @@ static int mpeg_open(struct inode *inode, struct file *file) V4L2_FIELD_INTERLACED, sizeof(struct cx23885_buffer), fh); - unlock_kernel(); return 0; } diff --git a/trunk/drivers/media/video/cx23885/cx23885-cards.c b/trunk/drivers/media/video/cx23885/cx23885-cards.c index 2cda15f829fd..c36d3f632104 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-cards.c +++ b/trunk/drivers/media/video/cx23885/cx23885-cards.c @@ -26,7 +26,6 @@ #include #include "cx23885.h" -#include "tuner-xc2028.h" /* ------------------------------------------------------------------ */ /* board config info */ @@ -149,15 +148,6 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, - [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP] = { - .name = "DViCO FusionHDTV DVB-T Dual Express", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H] = { - .name = "Leadtek Winfast PxDVR3200 H", - .portc = CX23885_MPEG_DVB, - }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -229,14 +219,6 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x18ac, .subdevice = 0xd618, .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, - },{ - .subvendor = 0x18ac, - .subdevice = 0xdb78, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, - }, { - .subvendor = 0x107d, - .subdevice = 0x6681, - .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -337,15 +319,15 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) dev->name, tv.model); } -int cx23885_tuner_callback(void *priv, int component, int command, int arg) +/* Tuner callback function for cx23885 boards. Currently only needed + * for HVR1500Q, which has an xc5000 tuner. + */ +int cx23885_tuner_callback(void *priv, int command, int arg) { - struct cx23885_tsport *port = priv; - struct cx23885_dev *dev = port->dev; + struct cx23885_i2c *bus = priv; + struct cx23885_dev *dev = bus->dev; u32 bitmask = 0; - if (command == XC2028_RESET_CLK) - return 0; - if (command != 0) { printk(KERN_ERR "%s(): Unknown command 0x%x.\n", __func__, command); @@ -353,21 +335,21 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) } switch(dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - /* Tuner Reset Command */ - bitmask = 0x04; + /* Tuner Reset Command from xc5000 */ + if (command == 0) + bitmask = 0x04; break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - /* Two identical tuners on two different i2c buses, - * we need to reset the correct gpio. */ - if (port->nr == 0) - bitmask = 0x01; - else if (port->nr == 1) - bitmask = 0x04; + if (command == 0) { + + /* Two identical tuners on two different i2c buses, + * we need to reset the correct gpio. */ + if (bus->nr == 0) + bitmask = 0x01; + else if (bus->nr == 1) + bitmask = 0x04; + } break; } @@ -483,32 +465,6 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(20); cx_set(GP0_IO, 0x000f000f); break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - /* GPIO-0 portb xc3028 reset */ - /* GPIO-1 portb zl10353 reset */ - /* GPIO-2 portc xc3028 reset */ - /* GPIO-3 portc zl10353 reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x000f0000); - mdelay(20); - cx_clear(GP0_IO, 0x0000000f); - mdelay(20); - cx_set(GP0_IO, 0x000f000f); - break; - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - /* GPIO-2 xc3028 tuner reset */ - - /* The following GPIO's are on the internal AVCore (cx25840) */ - /* GPIO-? zl10353 demod reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00040000); - mdelay(20); - cx_clear(GP0_IO, 0x00000004); - mdelay(20); - cx_set(GP0_IO, 0x00040004); - break; } } @@ -523,9 +479,6 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1400: /* FIXME: Implement me */ break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - request_module("ir-kbd-i2c"); - break; } return 0; @@ -563,7 +516,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) switch (dev->board) { case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; @@ -596,7 +548,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: default: ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ @@ -610,7 +561,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1700: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: request_module("cx25840"); break; } diff --git a/trunk/drivers/media/video/cx23885/cx23885-core.c b/trunk/drivers/media/video/cx23885/cx23885-core.c index beb3e61669a3..25fb09938744 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-core.c +++ b/trunk/drivers/media/video/cx23885/cx23885-core.c @@ -1442,7 +1442,7 @@ void cx23885_cancel_buffers(struct cx23885_tsport *port) struct cx23885_dev *dev = port->dev; struct cx23885_dmaqueue *q = &port->mpegq; - dprintk(1, "%s()\n", __func__); + dprintk(1, "%s()\n", __FUNCTION__); del_timer_sync(&q->timeout); cx23885_stop_dma(port); do_cancel_buffers(port, "cancel", 0); diff --git a/trunk/drivers/media/video/cx23885/cx23885-dvb.c b/trunk/drivers/media/video/cx23885/cx23885-dvb.c index 24bd18327aa0..291b9d008da8 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-dvb.c +++ b/trunk/drivers/media/video/cx23885/cx23885-dvb.c @@ -42,7 +42,6 @@ #include "tuner-simple.h" #include "dib7000p.h" #include "dibx000_common.h" -#include "zl10353.h" static unsigned int debug; @@ -189,11 +188,13 @@ static struct s5h1411_config dvico_s5h1411_config = { static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { .i2c_address = 0x61, .if_khz = 5380, + .tuner_callback = cx23885_tuner_callback }; static struct xc5000_config dvico_xc5000_tunerconfig = { .i2c_address = 0x64, .if_khz = 5380, + .tuner_callback = cx23885_tuner_callback }; static struct tda829x_config tda829x_no_probe = { @@ -302,11 +303,35 @@ static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { .output_mode = OUTMODE_MPEG2_SERIAL, }; -static struct zl10353_config dvico_fusionhdtv_xc3028 = { - .demod_address = 0x0f, - .if2 = 45600, - .no_tuner = 1, -}; +static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) +{ + struct cx23885_tsport *port = ptr; + struct cx23885_dev *dev = port->dev; + + switch (command) { + case XC2028_TUNER_RESET: + /* Send the tuner in then out of reset */ + /* GPIO-2 xc3028 tuner */ + dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); + + cx_set(GP0_IO, 0x00040000); + cx_clear(GP0_IO, 0x00000004); + msleep(5); + + cx_set(GP0_IO, 0x00040004); + msleep(5); + break; + case XC2028_RESET_CLK: + dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); + break; + default: + dprintk(1, "%s: unknown command %d, arg %d\n", __func__, + command, arg); + return -EINVAL; + } + + return 0; +} static int dvb_register(struct cx23885_tsport *port) { @@ -388,8 +413,8 @@ static int dvb_register(struct cx23885_tsport *port) &dev->i2c_bus[0].i2c_adap); if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_hvr1500q_tunerconfig); + &i2c_bus->i2c_adap, + &hauppauge_hvr1500q_tunerconfig, i2c_bus); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; @@ -401,9 +426,10 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &i2c_bus->i2c_adap, .i2c_addr = 0x61, + .callback = cx23885_hvr1500_xc3028_callback, }; static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, + .fname = "xc3028-v27.fw", .max_len = 64, .scode_table = XC3028_FE_OREN538, }; @@ -439,13 +465,13 @@ static int dvb_register(struct cx23885_tsport *port) struct xc2028_config cfg = { .i2c_adap = &dev->i2c_bus[1].i2c_adap, .i2c_addr = 0x64, + .callback = cx23885_hvr1500_xc3028_callback, }; static struct xc2028_ctrl ctl = { - .fname = XC3028L_DEFAULT_FIRMWARE, + .fname = "xc3028L-v36.fw", .max_len = 64, .demod = 5000, - /* This is true for all demods with v36 firmware? */ - .type = XC2028_D2633, + .d2633 = 1 }; fe = dvb_attach(xc2028_attach, @@ -466,57 +492,8 @@ static int dvb_register(struct cx23885_tsport *port) &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, - &i2c_bus->i2c_adap, - &dvico_xc5000_tunerconfig); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { - i2c_bus = &dev->i2c_bus[port->nr - 1]; - - port->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (port->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &i2c_bus->i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - fe = dvb_attach(xc2028_attach, port->dvb.frontend, - &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - } - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - i2c_bus = &dev->i2c_bus[0]; - - port->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (port->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_bus[1].i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - fe = dvb_attach(xc2028_attach, port->dvb.frontend, - &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } + &i2c_bus->i2c_adap, + &dvico_xc5000_tunerconfig, i2c_bus); break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", @@ -527,8 +504,6 @@ static int dvb_register(struct cx23885_tsport *port) printk("%s: frontend initialization failed\n", dev->name); return -1; } - /* define general-purpose callback pointer */ - port->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); diff --git a/trunk/drivers/media/video/cx23885/cx23885-vbi.c b/trunk/drivers/media/video/cx23885/cx23885-vbi.c index 5b297f0323b6..35e61cd112fc 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-vbi.c +++ b/trunk/drivers/media/video/cx23885/cx23885-vbi.c @@ -85,8 +85,18 @@ static int cx23885_start_vbi_dma(struct cx23885_dev *dev, return 0; } +int cx23885_stop_vbi_dma(struct cx23885_dev *dev) +{ + /* stop dma */ + cx_clear(VID_A_DMA_CTL, 0x00000022); + + /* disable irqs */ + cx_clear(PCI_INT_MSK, 0x000001); + cx_clear(VID_A_INT_MSK, 0x00000022); + return 0; +} -static int cx23885_restart_vbi_queue(struct cx23885_dev *dev, +int cx23885_restart_vbi_queue(struct cx23885_dev *dev, struct cx23885_dmaqueue *q) { struct cx23885_buffer *buf; diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c index f75ed1c9b71a..6047c78d84bf 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-video.c +++ b/trunk/drivers/media/video/cx23885/cx23885-video.c @@ -244,7 +244,7 @@ static struct cx23885_ctrl cx23885_ctls[] = { }; static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); -static const u32 cx23885_user_ctrls[] = { +const u32 cx23885_user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, V4L2_CID_CONTRAST, @@ -254,13 +254,14 @@ static const u32 cx23885_user_ctrls[] = { V4L2_CID_AUDIO_MUTE, 0 }; +EXPORT_SYMBOL(cx23885_user_ctrls); static const u32 *ctrl_classes[] = { cx23885_user_ctrls, NULL }; -static void cx23885_video_wakeup(struct cx23885_dev *dev, +void cx23885_video_wakeup(struct cx23885_dev *dev, struct cx23885_dmaqueue *q, u32 count) { struct cx23885_buffer *buf; @@ -295,7 +296,7 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev, __func__, bc); } -static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) +int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) { dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__, @@ -313,7 +314,7 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) return 0; } -static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, +struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, struct pci_dev *pci, struct video_device *template, char *type) @@ -333,7 +334,7 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, return vfd; } -static int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) +int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) { int i; @@ -350,6 +351,7 @@ static int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) *qctrl = cx23885_ctls[i].v; return 0; } +EXPORT_SYMBOL(cx23885_ctrl_query); /* ------------------------------------------------------------------- */ /* resource management */ @@ -400,7 +402,7 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, mutex_unlock(&dev->lock); } -static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) +int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) { struct v4l2_routing route; memset(&route, 0, sizeof(route)); @@ -420,9 +422,10 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) return 0; } +EXPORT_SYMBOL(cx23885_video_mux); /* ------------------------------------------------------------------ */ -static int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, +int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, unsigned int height, enum v4l2_field field) { dprintk(1, "%s()\n", __func__); @@ -728,7 +731,6 @@ static int video_open(struct inode *inode, struct file *file) enum v4l2_buf_type type = 0; int radio = 0; - lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); if (h->video_dev->minor == minor) { @@ -746,20 +748,16 @@ static int video_open(struct inode *inode, struct file *file) dev = h; } } - if (NULL == dev) { - unlock_kernel(); + if (NULL == dev) return -ENODEV; - } dprintk(1, "open minor=%d radio=%d type=%s\n", minor, radio, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -777,7 +775,6 @@ static int video_open(struct inode *inode, struct file *file) dprintk(1, "post videobuf_queue_init()\n"); - unlock_kernel(); return 0; } @@ -887,19 +884,21 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma) /* ------------------------------------------------------------------ */ /* VIDEO CTRL IOCTLS */ -static int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) +int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); return 0; } +EXPORT_SYMBOL(cx23885_get_control); -static int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) +int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" " (disabled - no action)\n", __func__); return 0; } +EXPORT_SYMBOL(cx23885_set_control); static void init_controls(struct cx23885_dev *dev) { @@ -1147,7 +1146,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) return 0; } -static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) +int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) { static const char *iname[] = { [CX23885_VMUX_COMPOSITE1] = "Composite1", @@ -1180,6 +1179,7 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) i->std = CX23885_NORMS; return 0; } +EXPORT_SYMBOL(cx23885_enum_input); static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) @@ -1288,7 +1288,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, return 0; } -static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) +int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) { if (unlikely(UNSET == dev->tuner_type)) return -EINVAL; @@ -1307,6 +1307,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) return 0; } +EXPORT_SYMBOL(cx23885_set_freq); static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) diff --git a/trunk/drivers/media/video/cx23885/cx23885.h b/trunk/drivers/media/video/cx23885/cx23885.h index ba4e0aaed463..e23d97c071e0 100644 --- a/trunk/drivers/media/video/cx23885/cx23885.h +++ b/trunk/drivers/media/video/cx23885/cx23885.h @@ -64,8 +64,6 @@ #define CX23885_BOARD_HAUPPAUGE_HVR1700 8 #define CX23885_BOARD_HAUPPAUGE_HVR1400 9 #define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10 -#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11 -#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ #define CX23885_NORMS (\ @@ -411,7 +409,7 @@ extern const unsigned int cx23885_bcount; extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; -extern int cx23885_tuner_callback(void *priv, int component, int command, int arg); +extern int cx23885_tuner_callback(void *priv, int command, int arg); extern void cx23885_card_list(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev); extern void cx23885_gpio_setup(struct cx23885_dev *dev); diff --git a/trunk/drivers/media/video/cx25840/cx25840-vbi.c b/trunk/drivers/media/video/cx25840/cx25840-vbi.c index 58e6ef1c28a0..69f2bbdbb929 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-vbi.c +++ b/trunk/drivers/media/video/cx25840/cx25840-vbi.c @@ -141,11 +141,10 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) u8 lcr[24]; fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && - fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) return -EINVAL; svbi = &fmt->fmt.sliced; - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + if (svbi->service_set == 0) { /* raw VBI */ memset(svbi, 0, sizeof(*svbi)); diff --git a/trunk/drivers/media/video/cx88/Kconfig b/trunk/drivers/media/video/cx88/Kconfig index 0b9e5fac6239..9dd7bdf659b9 100644 --- a/trunk/drivers/media/video/cx88/Kconfig +++ b/trunk/drivers/media/video/cx88/Kconfig @@ -58,10 +58,6 @@ config VIDEO_CX88_DVB select DVB_ISL6421 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_CX24116 if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_STV0288 if !DVB_FE_CUSTOMISE - select DVB_STB6000 if !DVB_FE_CUSTOMISE ---help--- This adds support for DVB/ATSC cards based on the Conexant 2388x chip. diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index e71369754305..9a1374a38ec7 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -1057,15 +1057,12 @@ static int mpeg_open(struct inode *inode, struct file *file) struct cx8802_driver *drv = NULL; int err; - lock_kernel(); dev = cx8802_get_device(inode); dprintk( 1, "%s\n", __func__); - if (dev == NULL) { - unlock_kernel(); + if (dev == NULL) return -ENODEV; - } /* Make sure we can acquire the hardware */ drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); @@ -1073,7 +1070,6 @@ static int mpeg_open(struct inode *inode, struct file *file) err = drv->request_acquire(drv); if(err != 0) { dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); - unlock_kernel(); return err; } } @@ -1081,7 +1077,6 @@ static int mpeg_open(struct inode *inode, struct file *file) if (blackbird_initialize_codec(dev) < 0) { if (drv) drv->request_release(drv); - unlock_kernel(); return -EINVAL; } dprintk(1,"open minor=%d\n",minor); @@ -1091,7 +1086,6 @@ static int mpeg_open(struct inode *inode, struct file *file) if (NULL == fh) { if (drv) drv->request_release(drv); - unlock_kernel(); return -ENOMEM; } file->private_data = fh; @@ -1107,7 +1101,6 @@ static int mpeg_open(struct inode *inode, struct file *file) /* FIXME: locking against other video device */ cx88_set_scale(dev->core, dev->width, dev->height, fh->mpegq.field); - unlock_kernel(); return 0; } diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index 5da04e811ca2..de199a206a15 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -1349,30 +1349,27 @@ static const struct cx88_board cx88_boards[] = { .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, .audio_chip = V4L2_IDENT_WM8775, - /* - * gpio0 as reported by Mike Crash - */ .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0xef88, + .gpio0 = 0xe780, .audioroute = 1, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0xef88, + .gpio0 = 0xe780, .audioroute = 2, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0xef88, + .gpio0 = 0xe780, .audioroute = 2, }}, /* fixme: Add radio support */ .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, .radio = { .type = CX88_RADIO, - .gpio0 = 0xef88, + .gpio0 = 0xe780, }, }, [CX88_BOARD_ADSTECH_PTV_390] = { @@ -1449,26 +1446,15 @@ static const struct cx88_board cx88_boards[] = { .name = "Pinnacle Hybrid PCTV", .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, - .radio_type = TUNER_XC2028, - .radio_addr = 0x61, .input = { { .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0x004ff, - .gpio1 = 0x010ff, - .gpio2 = 0x00001, }, { .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0x004fb, - .gpio1 = 0x010ef, - .audioroute = 1, }, { .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0x004fb, - .gpio1 = 0x010ef, - .audioroute = 1, } }, .radio = { .type = CX88_RADIO, @@ -1476,7 +1462,6 @@ static const struct cx88_board cx88_boards[] = { .gpio1 = 0x010ff, .gpio2 = 0x0ff, }, - .mpeg = CX88_MPEG_DVB, }, [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = { .name = "Winfast TV2000 XP Global", @@ -1581,9 +1566,9 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = { .name = "DViCO FusionHDTV DVB-T PRO", - .tuner_type = TUNER_XC2028, - .tuner_addr = 0x61, + .tuner_type = TUNER_ABSENT, /* XXX: Has XC3028 */ .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .input = { { .type = CX88_VMUX_COMPOSITE1, @@ -1640,36 +1625,6 @@ static const struct cx88_board cx88_boards[] = { .gpio2 = 0x0cfb, }, }, - [CX88_BOARD_PROLINK_PV_GLOBAL_XTREME] = { - .name = "Prolink Pixelview Global Extreme", - .tuner_type = TUNER_XC2028, - .tuner_addr = 0x61, - .input = { { - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x04fb, - .gpio1 = 0x04080, - .gpio2 = 0x0cf7, - }, { - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x04fb, - .gpio1 = 0x04080, - .gpio2 = 0x0cfb, - }, { - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x04fb, - .gpio1 = 0x04080, - .gpio2 = 0x0cfb, - } }, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0x04ff, - .gpio1 = 0x04080, - .gpio2 = 0x0cf7, - }, - }, /* Both radio, analog and ATSC work with this board. However, for analog to work, s5h1409 gate should be open, otherwise, tuner-xc3028 won't be detected. @@ -1709,131 +1664,6 @@ static const struct cx88_board cx88_boards[] = { }, .mpeg = CX88_MPEG_DVB, }, - [CX88_BOARD_HAUPPAUGE_HVR4000] = { - .name = "Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid", - .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, - /* - * GPIO0 (WINTV2000) - * - * Analogue SAT DVB-T - * Antenna 0xc4bf 0xc4bb - * Composite 0xc4bf 0xc4bb - * S-Video 0xc4bf 0xc4bb - * Composite1 0xc4ff 0xc4fb - * S-Video1 0xc4ff 0xc4fb - * - * BIT VALUE FUNCTION GP{x}_IO - * 0 1 I:? - * 1 1 I:? - * 2 1 O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH - * 3 1 I:? - * 4 1 I:? - * 5 1 I:? - * 6 0 O:INPUT SELECTOR 0=INTERNAL 1=EXPANSION - * 7 1 O:DVB-T DEMOD RESET LOW - * - * BIT VALUE FUNCTION GP{x}_OE - * 8 0 I - * 9 0 I - * a 1 O - * b 0 I - * c 0 I - * d 0 I - * e 1 O - * f 1 O - */ - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0xc4bf, - }, { - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0xc4bf, - }, { - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0xc4bf, - } }, - /* fixme: Add radio support */ - .mpeg = CX88_MPEG_DVB, - }, - [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = { - .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2", - .tuner_type = UNSET, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - } }, - .mpeg = CX88_MPEG_DVB, - }, - [CX88_BOARD_TEVII_S420] = { - .name = "TeVii S420 DVB-S", - .tuner_type = UNSET, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - } }, - .mpeg = CX88_MPEG_DVB, - }, - [CX88_BOARD_TEVII_S460] = { - .name = "TeVii S460 DVB-S/S2", - .tuner_type = UNSET, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - } }, - .mpeg = CX88_MPEG_DVB, - }, - [CX88_BOARD_OMICOM_SS4_PCI] = { - .name = "Omicom SS4 DVB-S/S2 PCI", - .tuner_type = UNSET, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - } }, - .mpeg = CX88_MPEG_DVB, - }, - [CX88_BOARD_TBS_8920] = { - .name = "TBS 8920 DVB-S/S2", - .tuner_type = TUNER_ABSENT, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 1, - } }, - .mpeg = CX88_MPEG_DVB, - }, - [CX88_BOARD_PROF_7300] = { - .name = "PROF 7300 DVB-S/S2", - .tuner_type = UNSET, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - } }, - .mpeg = CX88_MPEG_DVB, - }, }; /* ------------------------------------------------------------------ */ @@ -2179,54 +2009,10 @@ static const struct cx88_subid cx88_subids[] = { .subvendor = 0x1554, .subdevice = 0x4935, .card = CX88_BOARD_PROLINK_PV_8000GT, - }, { - .subvendor = 0x1554, - .subdevice = 0x4976, - .card = CX88_BOARD_PROLINK_PV_GLOBAL_XTREME, }, { .subvendor = 0x17de, .subdevice = 0x08c1, .card = CX88_BOARD_KWORLD_ATSC_120, - }, { - .subvendor = 0x0070, - .subdevice = 0x6900, - .card = CX88_BOARD_HAUPPAUGE_HVR4000, - }, { - .subvendor = 0x0070, - .subdevice = 0x6904, - .card = CX88_BOARD_HAUPPAUGE_HVR4000, - }, { - .subvendor = 0x0070, - .subdevice = 0x6902, - .card = CX88_BOARD_HAUPPAUGE_HVR4000, - }, { - .subvendor = 0x0070, - .subdevice = 0x6905, - .card = CX88_BOARD_HAUPPAUGE_HVR4000LITE, - }, { - .subvendor = 0x0070, - .subdevice = 0x6906, - .card = CX88_BOARD_HAUPPAUGE_HVR4000LITE, - }, { - .subvendor = 0xd420, - .subdevice = 0x9022, - .card = CX88_BOARD_TEVII_S420, - }, { - .subvendor = 0xd460, - .subdevice = 0x9022, - .card = CX88_BOARD_TEVII_S460, - }, { - .subvendor = 0xA044, - .subdevice = 0x2011, - .card = CX88_BOARD_OMICOM_SS4_PCI, - }, { - .subvendor = 0x8920, - .subdevice = 0x8888, - .card = CX88_BOARD_TBS_8920, - }, { - .subvendor = 0xB033, - .subdevice = 0x3033, - .card = CX88_BOARD_PROF_7300, }, }; @@ -2279,13 +2065,6 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */ case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ case 34519: /* WinTV-PCI-FM */ - case 69009: - /* WinTV-HVR4000 (DVBS/S2/T, Video and IR, back panel inputs) */ - case 69100: /* WinTV-HVR4000LITE (DVBS/S2, IR) */ - case 69500: /* WinTV-HVR4000LITE (DVBS/S2, No IR) */ - case 69559: - /* WinTV-HVR4000 (DVBS/S2/T, Video no IR, back panel inputs) */ - case 69569: /* WinTV-HVR4000 (DVBS/S2/T, Video no IR) */ case 90002: /* Nova-T-PCI (9002) */ case 92001: /* Nova-S-Plus (Video and IR) */ case 92002: /* Nova-S-Plus (Video and IR) */ @@ -2370,21 +2149,9 @@ static int cx88_dvico_xc2028_callback(struct cx88_core *core, { switch (command) { case XC2028_TUNER_RESET: - switch (core->boardnr) { - case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: - /* GPIO-4 xc3028 tuner */ - - cx_set(MO_GP0_IO, 0x00001000); - cx_clear(MO_GP0_IO, 0x00000010); - msleep(100); - cx_set(MO_GP0_IO, 0x00000010); - msleep(100); - break; - default: - cx_write(MO_GP0_IO, 0x101000); - mdelay(5); - cx_set(MO_GP0_IO, 0x101010); - } + cx_write(MO_GP0_IO, 0x101000); + mdelay(5); + cx_set(MO_GP0_IO, 0x101010); break; default: return -EINVAL; @@ -2491,10 +2258,8 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core, return cx88_xc3028_geniatech_tuner_callback(core, command, arg); case CX88_BOARD_PROLINK_PV_8000GT: - case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: return cx88_pv_8000gt_callback(core, command, arg); case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: - case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: return cx88_dvico_xc2028_callback(core, command, arg); } @@ -2562,7 +2327,7 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core, return 0; /* Should never be here */ } -int cx88_tuner_callback(void *priv, int component, int command, int arg) +int cx88_tuner_callback(void *priv, int command, int arg) { struct i2c_algo_bit_data *i2c_algo = priv; struct cx88_core *core; @@ -2579,9 +2344,6 @@ int cx88_tuner_callback(void *priv, int component, int command, int arg) return -EINVAL; } - if (component != DVB_FRONTEND_COMPONENT_TUNER) - return -EINVAL; - switch (core->board.tuner_type) { case TUNER_XC2028: info_printk(core, "Calling XC2028/3028 callback\n"); @@ -2630,22 +2392,16 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) { switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: - /* - * Bring the 702 demod up before i2c scanning/attach or devices are hidden - * We leave here with the 702 on the bus - * - * "reset the IR receiver on GPIO[3]" - * Reported by Mike Crash - */ - cx_write(MO_GP0_IO, 0x0000ef88); + /* Bring the 702 demod up before i2c scanning/attach or devices are hidden */ + /* We leave here with the 702 on the bus */ + cx_write(MO_GP0_IO, 0x0000e780); udelay(1000); - cx_clear(MO_GP0_IO, 0x00000088); + cx_clear(MO_GP0_IO, 0x00000080); udelay(50); - cx_set(MO_GP0_IO, 0x00000088); /* 702 out of reset */ + cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ udelay(1000); break; - case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: case CX88_BOARD_PROLINK_PV_8000GT: cx_write(MO_GP2_IO, 0xcf7); mdelay(50); @@ -2655,18 +2411,10 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) msleep(10); break; - case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: + case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: /* Enable the xc5000 tuner */ cx_set(MO_GP0_IO, 0x00001010); break; - - case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - case CX88_BOARD_HAUPPAUGE_HVR4000LITE: - /* Init GPIO */ - cx_write(MO_GP0_IO, core->board.input[0].gpio0); - udelay(1000); - break; } } @@ -2687,22 +2435,17 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) core->i2c_algo.udelay = 16; break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: - ctl->demod = XC3028_FE_ZARLINK456; + ctl->scode_table = XC3028_FE_ZARLINK456; break; case CX88_BOARD_KWORLD_ATSC_120: case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: ctl->demod = XC3028_FE_OREN538; break; - case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: case CX88_BOARD_PROLINK_PV_8000GT: /* - * Those boards uses non-MTS firmware + * This board uses non-MTS firmware */ break; - case CX88_BOARD_PINNACLE_HYBRID_PCTV: - ctl->demod = XC3028_FE_ZARLINK456; - ctl->mts = 1; - break; default: ctl->demod = XC3028_FE_OREN538; ctl->mts = 1; @@ -2746,8 +2489,6 @@ static void cx88_card_setup(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR1300: - case CX88_BOARD_HAUPPAUGE_HVR4000: - case CX88_BOARD_HAUPPAUGE_HVR4000LITE: if (0 == core->i2c_rc) hauppauge_eeprom(core, eeprom); break; @@ -2829,18 +2570,7 @@ static void cx88_card_setup(struct cx88_core *core) tea5767_cfg.priv = &ctl; cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); - break; } - case CX88_BOARD_TEVII_S420: - case CX88_BOARD_TEVII_S460: - case CX88_BOARD_OMICOM_SS4_PCI: - case CX88_BOARD_TBS_8920: - case CX88_BOARD_PROF_7300: - cx_write(MO_SRST_IO, 0); - msleep(100); - cx_write(MO_SRST_IO, 1); - msleep(100); - break; } /*end switch() */ diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index 344ed2626e59..d96173ff1dba 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -48,11 +48,6 @@ #include "tuner-simple.h" #include "tda9887.h" #include "s5h1411.h" -#include "stv0299.h" -#include "z0194a.h" -#include "stv0288.h" -#include "stb6000.h" -#include "cx24116.h" MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); MODULE_AUTHOR("Chris Pascoe "); @@ -380,28 +375,37 @@ static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, return 0; } -static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) +static int cx88_pci_nano_callback(void *ptr, int command, int arg) { - struct cx8802_dev *dev= fe->dvb->priv; - struct cx88_core *core = dev->core; - - switch (voltage) { - case SEC_VOLTAGE_13: - printk("LNB Voltage SEC_VOLTAGE_13\n"); - cx_write(MO_GP0_IO, 0x00006040); - break; - case SEC_VOLTAGE_18: - printk("LNB Voltage SEC_VOLTAGE_18\n"); - cx_write(MO_GP0_IO, 0x00006060); - break; - case SEC_VOLTAGE_OFF: - printk("LNB Voltage SEC_VOLTAGE_off\n"); + struct cx88_core *core = ptr; + + switch (command) { + case XC2028_TUNER_RESET: + /* Send the tuner in then out of reset */ + dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); + + switch (core->boardnr) { + case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: + /* GPIO-4 xc3028 tuner */ + + cx_set(MO_GP0_IO, 0x00001000); + cx_clear(MO_GP0_IO, 0x00000010); + msleep(100); + cx_set(MO_GP0_IO, 0x00000010); + msleep(100); break; + } + + break; + case XC2028_RESET_CLK: + dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); + break; + default: + dprintk(1, "%s: unknown command %d, arg %d\n", __func__, + command, arg); + return -EINVAL; } - if (core->prev_set_voltage) - return core->prev_set_voltage(fe, voltage); return 0; } @@ -452,12 +456,7 @@ static struct s5h1409_config kworld_atsc_120_config = { static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { .i2c_address = 0x64, .if_khz = 5380, -}; - -static struct zl10353_config cx88_pinnacle_hybrid_pctv = { - .demod_address = (0x1e >> 1), - .no_tuner = 1, - .if2 = 45600, + .tuner_callback = cx88_tuner_callback, }; static struct zl10353_config cx88_geniatech_x8000_mt = { @@ -478,6 +477,7 @@ static struct s5h1411_config dvico_fusionhdtv7_config = { static struct xc5000_config dvico_fusionhdtv7_tuner_config = { .i2c_address = 0xc2 >> 1, .if_khz = 5380, + .tuner_callback = cx88_tuner_callback, }; static int attach_xc3028(u8 addr, struct cx8802_dev *dev) @@ -488,6 +488,7 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) .i2c_adap = &dev->core->i2c_adap, .i2c_addr = addr, .ctrl = &ctl, + .callback = cx88_tuner_callback, }; if (!dev->dvb.frontend) { @@ -517,60 +518,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) return 0; } -static int cx24116_set_ts_param(struct dvb_frontend *fe, - int is_punctured) -{ - struct cx8802_dev *dev = fe->dvb->priv; - dev->ts_gen_cntrl = 0x2; - - return 0; -} - -static int cx24116_reset_device(struct dvb_frontend *fe) -{ - struct cx8802_dev *dev = fe->dvb->priv; - struct cx88_core *core = dev->core; - - /* Reset the part */ - cx_write(MO_SRST_IO, 0); - msleep(10); - cx_write(MO_SRST_IO, 1); - msleep(10); - - return 0; -} - -static struct cx24116_config hauppauge_hvr4000_config = { - .demod_address = 0x05, - .set_ts_params = cx24116_set_ts_param, - .reset_device = cx24116_reset_device, -}; - -static struct cx24116_config tevii_s460_config = { - .demod_address = 0x55, - .set_ts_params = cx24116_set_ts_param, - .reset_device = cx24116_reset_device, -}; - -static struct stv0299_config tevii_tuner_sharp_config = { - .demod_address = 0x68, - .inittab = sharp_z0194a__inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = 1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a__set_symbol_rate, - .set_ts_params = cx24116_set_ts_param, -}; - -static struct stv0288_config tevii_tuner_earda_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - .set_ts_params = cx24116_set_ts_param, -}; - static int dvb_register(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; @@ -839,7 +786,7 @@ static int dvb_register(struct cx8802_dev *dev) &core->i2c_adap); if (dev->dvb.frontend) { if (!dvb_attach(isl6421_attach, dev->dvb.frontend, - &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) + &core->i2c_adap, 0x08, 0x00, 0x00)) goto frontend_detach; } break; @@ -866,9 +813,13 @@ static int dvb_register(struct cx8802_dev *dev) &pinnacle_pctv_hd_800i_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { + /* tuner_config.video_dev must point to + * i2c_adap.algo_data + */ if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, - &pinnacle_pctv_hd_800i_tuner_config)) + &pinnacle_pctv_hd_800i_tuner_config, + core->i2c_adap.algo_data)) goto frontend_detach; } break; @@ -881,9 +832,10 @@ static int dvb_register(struct cx8802_dev *dev) struct xc2028_config cfg = { .i2c_adap = &core->i2c_adap, .i2c_addr = 0x61, + .callback = cx88_pci_nano_callback, }; static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, + .fname = "xc3028-v27.fw", .max_len = 64, .scode_table = XC3028_FE_OREN538, }; @@ -896,13 +848,10 @@ static int dvb_register(struct cx8802_dev *dev) break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: dev->dvb.frontend = dvb_attach(zl10353_attach, - &cx88_pinnacle_hybrid_pctv, + &cx88_geniatech_x8000_mt, &core->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; - if (attach_xc3028(0x61, dev) < 0) - goto frontend_detach; - } + if (attach_xc3028(0x61, dev) < 0) + goto frontend_detach; break; case CX88_BOARD_GENIATECH_X8000_MT: dev->ts_gen_cntrl = 0x00; @@ -925,69 +874,16 @@ static int dvb_register(struct cx8802_dev *dev) &dvico_fusionhdtv7_config, &core->i2c_adap); if (dev->dvb.frontend != NULL) { + /* tuner_config.video_dev must point to + * i2c_adap.algo_data + */ if (!dvb_attach(xc5000_attach, dev->dvb.frontend, &core->i2c_adap, - &dvico_fusionhdtv7_tuner_config)) + &dvico_fusionhdtv7_tuner_config, + core->i2c_adap.algo_data)) goto frontend_detach; } break; - case CX88_BOARD_HAUPPAUGE_HVR4000: - case CX88_BOARD_HAUPPAUGE_HVR4000LITE: - /* Support for DVB-S only, not DVB-T support */ - dev->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &dev->core->i2c_adap); - if (dev->dvb.frontend) { - dvb_attach(isl6421_attach, dev->dvb.frontend, - &dev->core->i2c_adap, - 0x08, ISL6421_DCL, 0x00); - } - break; - case CX88_BOARD_TEVII_S420: - dev->dvb.frontend = dvb_attach(stv0299_attach, - &tevii_tuner_sharp_config, - &core->i2c_adap); - if (dev->dvb.frontend != NULL) { - if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, - &core->i2c_adap, DVB_PLL_OPERA1)) - goto frontend_detach; - core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; - dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - - } else { - dev->dvb.frontend = dvb_attach(stv0288_attach, - &tevii_tuner_earda_config, - &core->i2c_adap); - if (dev->dvb.frontend != NULL) { - if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61, - &core->i2c_adap)) - goto frontend_detach; - core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; - dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - - } - } - break; - case CX88_BOARD_TEVII_S460: - dev->dvb.frontend = dvb_attach(cx24116_attach, - &tevii_s460_config, - &core->i2c_adap); - if (dev->dvb.frontend != NULL) { - core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; - dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - } - break; - case CX88_BOARD_OMICOM_SS4_PCI: - case CX88_BOARD_TBS_8920: - case CX88_BOARD_PROF_7300: - dev->dvb.frontend = dvb_attach(cx24116_attach, - &hauppauge_hvr4000_config, - &core->i2c_adap); - if (dev->dvb.frontend != NULL) { - core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; - dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - } - break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", core->name); @@ -999,8 +895,6 @@ static int dvb_register(struct cx8802_dev *dev) core->name); return -EINVAL; } - /* define general-purpose callback pointer */ - dev->dvb.frontend->callback = cx88_tuner_callback; /* Ensure all frontends negotiate bus access */ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; diff --git a/trunk/drivers/media/video/cx88/cx88-i2c.c b/trunk/drivers/media/video/cx88/cx88-i2c.c index 8e74d64fdcd2..d7406a994f09 100644 --- a/trunk/drivers/media/video/cx88/cx88-i2c.c +++ b/trunk/drivers/media/video/cx88/cx88-i2c.c @@ -201,23 +201,7 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap); if (0 == core->i2c_rc) { - static u8 tuner_data[] = - { 0x0b, 0xdc, 0x86, 0x52 }; - static struct i2c_msg tuner_msg = - { .flags = 0, .addr = 0xc2 >> 1, .buf = tuner_data, .len = 4 }; - dprintk(1, "i2c register ok\n"); - switch( core->boardnr ) { - case CX88_BOARD_HAUPPAUGE_HVR1300: - case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - printk("%s: i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n", - core->name); - i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1); - break; - default: - break; - } if (i2c_scan) do_i2c_scan(core->name,&core->i2c_client); } else diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index 8683d104de72..53526d997a4e 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -224,8 +224,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - case CX88_BOARD_HAUPPAUGE_HVR4000LITE: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; @@ -261,7 +259,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->polling = 1; /* ms */ break; case CX88_BOARD_PROLINK_PV_8000GT: - case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: ir_codes = ir_codes_pixelview_new; ir->gpio_addr = MO_GP1_IO; ir->mask_keycode = 0x3f; @@ -395,7 +392,7 @@ void cx88_ir_irq(struct cx88_core *core) { struct cx88_IR *ir = core->ir; u32 samples, ircode; - int i, start, range, toggle, dev, code; + int i; if (NULL == ir) return; @@ -464,34 +461,6 @@ void cx88_ir_irq(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR3000: - case CX88_BOARD_HAUPPAUGE_HVR4000: - case CX88_BOARD_HAUPPAUGE_HVR4000LITE: - ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); - ir_dprintk("biphase decoded: %x\n", ircode); - /* - * RC5 has an extension bit which adds a new range - * of available codes, this is detected here. Also - * hauppauge remotes (black/silver) always use - * specific device ids. If we do not filter the - * device ids then messages destined for devices - * such as TVs (id=0) will get through to the - * device causing mis-fired events. - */ - /* split rc5 data block ... */ - start = (ircode & 0x2000) >> 13; - range = (ircode & 0x1000) >> 12; - toggle= (ircode & 0x0800) >> 11; - dev = (ircode & 0x07c0) >> 6; - code = (ircode & 0x003f) | ((range << 6) ^ 0x0040); - if( start != 1) - /* no key pressed */ - break; - if ( dev != 0x1e && dev != 0x1f ) - /* not a hauppauge remote */ - break; - ir_input_keydown(ir->input, &ir->ir, code, ircode); - ir->release = jiffies + msecs_to_jiffies(120); - break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); ir_dprintk("biphase decoded: %x\n", ircode); diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index be45955dff68..ef4d56ea0027 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -773,7 +773,6 @@ static int video_open(struct inode *inode, struct file *file) enum v4l2_buf_type type = 0; int radio = 0; - lock_kernel(); list_for_each_entry(h, &cx8800_devlist, devlist) { if (h->video_dev->minor == minor) { dev = h; @@ -789,10 +788,8 @@ static int video_open(struct inode *inode, struct file *file) dev = h; } } - if (NULL == dev) { - unlock_kernel(); + if (NULL == dev) return -ENODEV; - } core = dev->core; @@ -801,10 +798,8 @@ static int video_open(struct inode *inode, struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -837,9 +832,6 @@ static int video_open(struct inode *inode, struct file *file) cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); } - unlock_kernel(); - - atomic_inc(&core->users); return 0; } @@ -928,8 +920,7 @@ static int video_release(struct inode *inode, struct file *file) file->private_data = NULL; kfree(fh); - if(atomic_dec_and_test(&dev->core->users)) - cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); + cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); return 0; } diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index dbf01b8b57a5..54fe65094711 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -221,14 +221,6 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65 #define CX88_BOARD_PROLINK_PV_8000GT 66 #define CX88_BOARD_KWORLD_ATSC_120 67 -#define CX88_BOARD_HAUPPAUGE_HVR4000 68 -#define CX88_BOARD_HAUPPAUGE_HVR4000LITE 69 -#define CX88_BOARD_TEVII_S460 70 -#define CX88_BOARD_OMICOM_SS4_PCI 71 -#define CX88_BOARD_TBS_8920 72 -#define CX88_BOARD_TEVII_S420 73 -#define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74 -#define CX88_BOARD_PROF_7300 75 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -350,7 +342,6 @@ struct cx88_core { struct mutex lock; /* various v4l controls */ u32 freq; - atomic_t users; /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ struct cx8802_dev *dvbdev; @@ -610,7 +601,7 @@ extern void cx88_call_i2c_clients(struct cx88_core *core, /* ----------------------------------------------------------- */ /* cx88-cards.c */ -extern int cx88_tuner_callback(void *dev, int component, int command, int arg); +extern int cx88_tuner_callback(void *dev, int command, int arg); extern int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci); extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); diff --git a/trunk/drivers/media/video/dabusb.c b/trunk/drivers/media/video/dabusb.c index 3aa538afcc0b..79faedf58521 100644 --- a/trunk/drivers/media/video/dabusb.c +++ b/trunk/drivers/media/video/dabusb.c @@ -866,8 +866,7 @@ static int __init dabusb_init (void) dbg("dabusb_init: driver registered"); - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_VERSION ":" DRIVER_DESC); out: return retval; diff --git a/trunk/drivers/media/video/dpc7146.c b/trunk/drivers/media/video/dpc7146.c new file mode 100644 index 000000000000..88d6df71d051 --- /dev/null +++ b/trunk/drivers/media/video/dpc7146.c @@ -0,0 +1,408 @@ +/* + dpc7146.c - v4l2 driver for the dpc7146 demonstration board + + Copyright (C) 2000-2003 Michael Hunold + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define DEBUG_VARIABLE debug + +#include +#include /* for saa7111a */ + +#define I2C_SAA7111A 0x24 + +/* All unused bytes are reserverd. */ +#define SAA711X_CHIP_VERSION 0x00 +#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02 +#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03 +#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04 +#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05 +#define SAA711X_HORIZONTAL_SYNC_START 0x06 +#define SAA711X_HORIZONTAL_SYNC_STOP 0x07 +#define SAA711X_SYNC_CONTROL 0x08 +#define SAA711X_LUMINANCE_CONTROL 0x09 +#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A +#define SAA711X_LUMINANCE_CONTRAST 0x0B +#define SAA711X_CHROMA_SATURATION 0x0C +#define SAA711X_CHROMA_HUE_CONTROL 0x0D +#define SAA711X_CHROMA_CONTROL 0x0E +#define SAA711X_FORMAT_DELAY_CONTROL 0x10 +#define SAA711X_OUTPUT_CONTROL_1 0x11 +#define SAA711X_OUTPUT_CONTROL_2 0x12 +#define SAA711X_OUTPUT_CONTROL_3 0x13 +#define SAA711X_V_GATE_1_START 0x15 +#define SAA711X_V_GATE_1_STOP 0x16 +#define SAA711X_V_GATE_1_MSB 0x17 +#define SAA711X_TEXT_SLICER_STATUS 0x1A +#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B +#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C +#define SAA711X_STATUS_BYTE 0x1F + +#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) + +static int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "debug verbosity"); + +static int dpc_num; + +#define DPC_INPUTS 2 +static struct v4l2_input dpc_inputs[DPC_INPUTS] = { + { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, + { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, +}; + +#define DPC_AUDIOS 0 + +static struct saa7146_extension_ioctls ioctls[] = { + { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_STD, SAA7146_AFTER }, + { 0, 0 } +}; + +struct dpc +{ + struct video_device *video_dev; + struct video_device *vbi_dev; + + struct i2c_adapter i2c_adapter; + struct i2c_client *saa7111a; + + int cur_input; /* current input */ +}; + +static int dpc_check_clients(struct device *dev, void *data) +{ + struct dpc* dpc = data; + struct i2c_client *client = i2c_verify_client(dev); + + if( !client ) + return 0; + + if( I2C_SAA7111A == client->addr ) + dpc->saa7111a = client; + + return 0; +} + +/* fixme: add vbi stuff here */ +static int dpc_probe(struct saa7146_dev* dev) +{ + struct dpc* dpc = NULL; + + dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); + if( NULL == dpc ) { + printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n"); + return -ENOMEM; + } + + /* FIXME: enable i2c-port pins, video-port-pins + video port pins should be enabled here ?! */ + saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); + + dpc->i2c_adapter = (struct i2c_adapter) { + .class = I2C_CLASS_TV_ANALOG, + .name = "dpc7146", + }; + saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); + if(i2c_add_adapter(&dpc->i2c_adapter) < 0) { + DEB_S(("cannot register i2c-device. skipping.\n")); + kfree(dpc); + return -EFAULT; + } + + /* loop through all i2c-devices on the bus and look who is there */ + device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); + + /* check if all devices are present */ + if (!dpc->saa7111a) { + DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); + i2c_del_adapter(&dpc->i2c_adapter); + kfree(dpc); + return -ENODEV; + } + + /* all devices are present, probe was successful */ + DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); + + /* we store the pointer in our private data field */ + dev->ext_priv = dpc; + + return 0; +} + +/* bring hardware to a sane state. this has to be done, just in case someone + wants to capture from this device before it has been properly initialized. + the capture engine would badly fail, because no valid signal arrives on the + saa7146, thus leading to timeouts and stuff. */ +static int dpc_init_done(struct saa7146_dev* dev) +{ + struct dpc* dpc = (struct dpc*)dev->ext_priv; + + DEB_D(("dpc_v4l2.o: dpc_init_done called.\n")); + + /* initialize the helper ics to useful values */ + i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11); + + i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03); + + i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1); + i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30); + + i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81); + + return 0; +} + +static struct saa7146_ext_vv vv_data; + +/* this function only gets called when the probing was successful */ +static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) +{ + struct dpc* dpc = (struct dpc*)dev->ext_priv; + + DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); + + /* checking for i2c-devices can be omitted here, because we + already did this in "dpc_vl42_probe" */ + + saa7146_vv_init(dev,&vv_data); + if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) { + ERR(("cannot register capture v4l2 device. skipping.\n")); + return -1; + } + + /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ + if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { + if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { + ERR(("cannot register vbi v4l2 device. skipping.\n")); + } + } + + i2c_use_client(dpc->saa7111a); + + printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); + dpc_num++; + + /* the rest */ + dpc->cur_input = 0; + dpc_init_done(dev); + + return 0; +} + +static int dpc_detach(struct saa7146_dev* dev) +{ + struct dpc* dpc = (struct dpc*)dev->ext_priv; + + DEB_EE(("dev:%p\n",dev)); + + i2c_release_client(dpc->saa7111a); + + saa7146_unregister_device(&dpc->video_dev,dev); + if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { + saa7146_unregister_device(&dpc->vbi_dev,dev); + } + saa7146_vv_release(dev); + + dpc_num--; + + i2c_del_adapter(&dpc->i2c_adapter); + kfree(dpc); + return 0; +} + +#ifdef axa +int dpc_vbi_bypass(struct saa7146_dev* dev) +{ + struct dpc* dpc = (struct dpc*)dev->ext_priv; + + int i = 1; + + /* switch bypass in saa7111a */ + if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { + printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); + return -1; + } + + return 0; +} +#endif + +static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +{ + struct saa7146_dev *dev = fh->dev; + struct dpc* dpc = (struct dpc*)dev->ext_priv; +/* + struct saa7146_vv *vv = dev->vv_data; +*/ + switch(cmd) + { + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; + DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); + + if( i->index < 0 || i->index >= DPC_INPUTS) { + return -EINVAL; + } + + memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); + + DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); + return 0; + } + case VIDIOC_G_INPUT: + { + int *input = (int *)arg; + *input = dpc->cur_input; + + DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input)); + return 0; + } + case VIDIOC_S_INPUT: + { + int input = *(int *)arg; + + if (input < 0 || input >= DPC_INPUTS) { + return -EINVAL; + } + + dpc->cur_input = input; + + /* fixme: switch input here, switch audio, too! */ +// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); + printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); + + return 0; + } + default: +/* + DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n")); +*/ + return -ENOIOCTLCMD; + } + return 0; +} + +static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) +{ + return 0; +} + +static struct saa7146_standard standard[] = { + { + .name = "PAL", .id = V4L2_STD_PAL, + .v_offset = 0x17, .v_field = 288, + .h_offset = 0x14, .h_pixels = 680, + .v_max_out = 576, .h_max_out = 768, + }, { + .name = "NTSC", .id = V4L2_STD_NTSC, + .v_offset = 0x16, .v_field = 240, + .h_offset = 0x06, .h_pixels = 708, + .v_max_out = 480, .h_max_out = 640, + }, { + .name = "SECAM", .id = V4L2_STD_SECAM, + .v_offset = 0x14, .v_field = 288, + .h_offset = 0x14, .h_pixels = 720, + .v_max_out = 576, .h_max_out = 768, + } +}; + +static struct saa7146_extension extension; + +static struct saa7146_pci_extension_data dpc = { + .ext_priv = "Multimedia eXtension Board", + .ext = &extension, +}; + +static struct pci_device_id pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7146, + .subvendor = 0x0000, + .subdevice = 0x0000, + .driver_data = (unsigned long)&dpc, + }, { + .vendor = 0, + } +}; + +MODULE_DEVICE_TABLE(pci, pci_tbl); + +static struct saa7146_ext_vv vv_data = { + .inputs = DPC_INPUTS, + .capabilities = V4L2_CAP_VBI_CAPTURE, + .stds = &standard[0], + .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), + .std_callback = &std_callback, + .ioctls = &ioctls[0], + .ioctl = dpc_ioctl, +}; + +static struct saa7146_extension extension = { + .name = "dpc7146 demonstration board", + .flags = SAA7146_USE_I2C_IRQ, + + .pci_tbl = &pci_tbl[0], + .module = THIS_MODULE, + + .probe = dpc_probe, + .attach = dpc_attach, + .detach = dpc_detach, + + .irq_mask = 0, + .irq_func = NULL, +}; + +static int __init dpc_init_module(void) +{ + if( 0 != saa7146_register_extension(&extension)) { + DEB_S(("failed to register extension.\n")); + return -ENODEV; + } + + return 0; +} + +static void __exit dpc_cleanup_module(void) +{ + saa7146_unregister_extension(&extension); +} + +module_init(dpc_init_module); +module_exit(dpc_cleanup_module); + +MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'"); +MODULE_AUTHOR("Michael Hunold "); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index d65d0572403b..de943cf6c169 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -1101,7 +1101,7 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2821), - .driver_info = EM2820_BOARD_PROLINK_PLAYTV_USB2 }, + .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2860), .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2861), @@ -1271,7 +1271,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, }; -int em28xx_tuner_callback(void *ptr, int component, int command, int arg) +int em28xx_tuner_callback(void *ptr, int command, int arg) { int rc = 0; struct em28xx *dev = ptr; diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c index c99e2383b7ec..d2b1a1a52689 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c +++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c @@ -249,6 +249,7 @@ static int attach_xc3028(u8 addr, struct em28xx *dev) memset(&cfg, 0, sizeof(cfg)); cfg.i2c_adap = &dev->i2c_adap; cfg.i2c_addr = addr; + cfg.callback = em28xx_tuner_callback; if (!dev->dvb->frontend) { printk(KERN_ERR "%s/2: dvb frontend not attached. " @@ -273,7 +274,7 @@ static int attach_xc3028(u8 addr, struct em28xx *dev) /* ------------------------------------------------------------------ */ -static int register_dvb(struct em28xx_dvb *dvb, +int register_dvb(struct em28xx_dvb *dvb, struct module *module, struct em28xx *dev, struct device *device) @@ -421,8 +422,6 @@ static int dvb_init(struct em28xx *dev) } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: - case EM2880_BOARD_TERRATEC_HYBRID_XS: - case EM2880_BOARD_KWORLD_DVB_310U: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, &dev->i2c_adap); @@ -444,6 +443,24 @@ static int dvb_init(struct em28xx *dev) } break; #endif + case EM2880_BOARD_TERRATEC_HYBRID_XS: + dvb->frontend = dvb_attach(zl10353_attach, + &em28xx_zl10353_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; + case EM2880_BOARD_KWORLD_DVB_310U: + dvb->frontend = dvb_attach(zl10353_attach, + &em28xx_zl10353_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", @@ -457,8 +474,6 @@ static int dvb_init(struct em28xx *dev) result = -EINVAL; goto out_free; } - /* define general-purpose callback pointer */ - dvb->frontend->callback = em28xx_tuner_callback; /* register everything */ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); diff --git a/trunk/drivers/media/video/em28xx/em28xx-i2c.c b/trunk/drivers/media/video/em28xx/em28xx-i2c.c index 3bab56b997fc..97853384c943 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-i2c.c +++ b/trunk/drivers/media/video/em28xx/em28xx-i2c.c @@ -143,11 +143,10 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr) } for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; write_timeout -= 5) { - unsigned reg = dev->em28xx_read_reg(dev, 0x5); - - if (reg == 0x94) + unsigned msg = dev->em28xx_read_reg(dev, 0x5); + if (msg == 0x94) return -ENODEV; - else if (reg == 0x84) + else if (msg == 0x84) return 0; msleep(5); } @@ -336,11 +335,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) /* Check if board has eeprom */ err = i2c_master_recv(&dev->i2c_client, &buf, 0); - if (err < 0) { - em28xx_errdev("%s: i2c_master_recv failed! err [%d]\n", - __func__, err); - return err; - } + if (err < 0) + return -1; buf = 0; @@ -348,7 +344,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) if (err != 1) { printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", dev->name, err); - return err; + return -1; } while (size > 0) { if (size > 16) @@ -361,7 +357,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n", dev->name, err); - return err; + return -1; } size -= block; p += block; @@ -589,31 +585,18 @@ void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg) */ int em28xx_i2c_register(struct em28xx *dev) { - int retval; - BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); dev->i2c_adap = em28xx_adap_template; dev->i2c_adap.dev.parent = &dev->udev->dev; strcpy(dev->i2c_adap.name, dev->name); dev->i2c_adap.algo_data = dev; - - retval = i2c_add_adapter(&dev->i2c_adap); - if (retval < 0) { - em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", - __func__, retval); - return retval; - } + i2c_add_adapter(&dev->i2c_adap); dev->i2c_client = em28xx_client_template; dev->i2c_client.adapter = &dev->i2c_adap; - retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); - if (retval < 0) { - em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", - __func__, retval); - return retval; - } + em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); if (i2c_scan) em28xx_do_i2c_scan(dev); diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index c53649e5315b..49ab0629702e 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -513,17 +513,10 @@ static struct videobuf_queue_ops em28xx_video_qops = { */ static int em28xx_config(struct em28xx *dev) { - int retval; /* Sets I2C speed to 100 KHz */ - if (!dev->is_em2800) { - retval = em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); - if (retval < 0) { - em28xx_errdev("%s: em28xx_write_regs_req failed! retval [%d]\n", - __func__, retval); - return retval; - } - } + if (!dev->is_em2800) + em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); /* enable vbi capturing */ @@ -1519,7 +1512,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) struct em28xx_fh *fh; enum v4l2_buf_type fh_type = 0; - lock_kernel(); list_for_each_entry(h, &em28xx_devlist, devlist) { if (h->vdev->minor == minor) { dev = h; @@ -1535,10 +1527,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) dev = h; } } - if (NULL == dev) { - unlock_kernel(); + if (NULL == dev) return -ENODEV; - } em28xx_videodbg("open minor=%d type=%s users=%d\n", minor, v4l2_type_names[fh_type], dev->users); @@ -1547,7 +1537,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); if (!fh) { em28xx_errdev("em28xx-video.c: Out of memory?!\n"); - unlock_kernel(); return -ENOMEM; } mutex_lock(&dev->lock); @@ -1584,7 +1573,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) sizeof(struct em28xx_buffer), fh); mutex_unlock(&dev->lock); - unlock_kernel(); return errCode; } @@ -1600,7 +1588,8 @@ static void em28xx_release_resources(struct em28xx *dev) /*FIXME: I2C IR should be disconnected */ em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", - dev->vdev->num, dev->vbi_dev->num); + dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, + dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); list_del(&dev->devlist); if (dev->sbutton_input_dev) em28xx_deregister_snapshot_button(dev); @@ -1959,23 +1948,13 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, } /* register i2c bus */ - errCode = em28xx_i2c_register(dev); - if (errCode < 0) { - em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n", - __func__, errCode); - return errCode; - } + em28xx_i2c_register(dev); /* Do board specific init and eeprom reading */ em28xx_card_setup(dev); /* Configure audio */ - errCode = em28xx_audio_analog_set(dev); - if (errCode < 0) { - em28xx_errdev("%s: em28xx_audio_analog_set - errCode [%d]!\n", - __func__, errCode); - return errCode; - } + em28xx_audio_analog_set(dev); /* configure the device */ em28xx_config_i2c(dev); @@ -1995,11 +1974,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->ctl_input = 2; errCode = em28xx_config(dev); - if (errCode < 0) { - em28xx_errdev("%s: em28xx_config - errCode [%d]!\n", - __func__, errCode); - return errCode; - } list_add_tail(&dev->devlist, &em28xx_devlist); @@ -2052,27 +2026,17 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, if (dev->has_msp34xx) { /* Send a reset to other chips via gpio */ - errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); - if (errCode < 0) { - em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(1) failed! errCode [%d]\n", - __func__, errCode); - return errCode; - } + em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); msleep(3); - - errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1); - if (errCode < 0) { - em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(2) failed! errCode [%d]\n", - __func__, errCode); - return errCode; - } + em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1); msleep(3); } video_mux(dev, 0); em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", - dev->vdev->num, dev->vbi_dev->num); + dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, + dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); mutex_lock(&em28xx_extension_devlist_lock); if (!list_empty(&em28xx_extension_devlist)) { @@ -2272,7 +2236,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) em28xx_warn ("device /dev/video%d is open! Deregistration and memory " "deallocation are deferred on close.\n", - dev->vdev->num); + dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); dev->state |= DEV_MISCONFIGURED; em28xx_uninit_isoc(dev); diff --git a/trunk/drivers/media/video/em28xx/em28xx.h b/trunk/drivers/media/video/em28xx/em28xx.h index 82781178e0a3..9a3310748685 100644 --- a/trunk/drivers/media/video/em28xx/em28xx.h +++ b/trunk/drivers/media/video/em28xx/em28xx.h @@ -411,8 +411,8 @@ struct em28xx { /* frame properties */ int width; /* current frame width */ int height; /* current frame height */ - unsigned hscale; /* horizontal scale factor (see datasheet) */ - unsigned vscale; /* vertical scale factor (see datasheet) */ + int hscale; /* horizontal scale factor (see datasheet) */ + int vscale; /* vertical scale factor (see datasheet) */ int interlaced; /* 1=interlace fileds, 0=just top fileds */ unsigned int video_bytesread; /* Number of bytes read */ @@ -528,7 +528,7 @@ extern struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; extern const unsigned int em28xx_bcount; void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); -int em28xx_tuner_callback(void *ptr, int component, int command, int arg); +int em28xx_tuner_callback(void *ptr, int command, int arg); /* Provided by em28xx-input.c */ /* TODO: Check if the standard get_key handlers on ir-common can be used */ diff --git a/trunk/drivers/media/video/et61x251/et61x251_core.c b/trunk/drivers/media/video/et61x251/et61x251_core.c index 7a85c41b0eea..8db2a05bf9c5 100644 --- a/trunk/drivers/media/video/et61x251/et61x251_core.c +++ b/trunk/drivers/media/video/et61x251/et61x251_core.c @@ -1214,7 +1214,7 @@ static int et61x251_open(struct inode* inode, struct file* filp) if (!down_read_trylock(&et61x251_dev_lock)) return -ERESTARTSYS; - cam = video_drvdata(filp); + cam = video_get_drvdata(video_devdata(filp)); if (wait_for_completion_interruptible(&cam->probe)) { up_read(&et61x251_dev_lock); @@ -1297,7 +1297,7 @@ static int et61x251_release(struct inode* inode, struct file* filp) down_write(&et61x251_dev_lock); - cam = video_drvdata(filp); + cam = video_get_drvdata(video_devdata(filp)); et61x251_stop_transfer(cam); et61x251_release_buffers(cam); @@ -1318,7 +1318,7 @@ static ssize_t et61x251_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) { - struct et61x251_device *cam = video_drvdata(filp); + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); struct et61x251_frame_t* f, * i; unsigned long lock_flags; long timeout; @@ -1426,7 +1426,7 @@ et61x251_read(struct file* filp, char __user * buf, static unsigned int et61x251_poll(struct file *filp, poll_table *wait) { - struct et61x251_device *cam = video_drvdata(filp); + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); struct et61x251_frame_t* f; unsigned long lock_flags; unsigned int mask = 0; @@ -1502,7 +1502,7 @@ static struct vm_operations_struct et61x251_vm_ops = { static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) { - struct et61x251_device *cam = video_drvdata(filp); + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, start = vma->vm_start; void *pos; @@ -2395,7 +2395,7 @@ et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg) static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, unsigned int cmd, void __user * arg) { - struct et61x251_device *cam = video_drvdata(filp); + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); switch (cmd) { @@ -2490,7 +2490,7 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, static int et61x251_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg) { - struct et61x251_device *cam = video_drvdata(filp); + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); int err = 0; if (mutex_lock_interruptible(&cam->fileop_mutex)) diff --git a/trunk/drivers/media/video/gspca/Kconfig b/trunk/drivers/media/video/gspca/Kconfig index 4d0817471c9f..42b90742b40b 100644 --- a/trunk/drivers/media/video/gspca/Kconfig +++ b/trunk/drivers/media/video/gspca/Kconfig @@ -1,212 +1,13 @@ -menuconfig USB_GSPCA - tristate "GSPCA based webcams" +config USB_GSPCA + tristate "USB GSPCA driver" depends on VIDEO_V4L2 - default m ---help--- - Say Y here if you want to enable selecting webcams based - on the GSPCA framework. + Say Y here if you want support for various USB webcams. - See for more info. + See for more info. - This driver uses the Video For Linux API. You must say Y or M to - "Video For Linux" to use this driver. + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" to use this driver. - To compile this driver as modules, choose M here: the - modules will be called gspca_main. - - -if USB_GSPCA && VIDEO_V4L2 - -source "drivers/media/video/gspca/m5602/Kconfig" - -config USB_GSPCA_CONEX - tristate "Conexant Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Conexant chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_conex. - -config USB_GSPCA_ETOMS - tristate "Etoms USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Etoms chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_etoms. - -config USB_GSPCA_FINEPIX - tristate "Fujifilm FinePix USB V4L2 driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the FinePix chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_finepix. - -config USB_GSPCA_MARS - tristate "Mars USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Mars chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_mars. - -config USB_GSPCA_OV519 - tristate "OV519 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the OV519 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_ov519. - -config USB_GSPCA_PAC207 - tristate "Pixart PAC207 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the PAC207 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_pac207. - -config USB_GSPCA_PAC7311 - tristate "Pixart PAC7311 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the PAC7311 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_pac7311. - -config USB_GSPCA_SONIXB - tristate "SN9C102 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SONIXB chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sonixb. - -config USB_GSPCA_SONIXJ - tristate "SONIX JPEG USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SONIXJ chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sonixj - -config USB_GSPCA_SPCA500 - tristate "SPCA500 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA500 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca500. - -config USB_GSPCA_SPCA501 - tristate "SPCA501 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA501 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca501. - -config USB_GSPCA_SPCA505 - tristate "SPCA505 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA505 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca505. - -config USB_GSPCA_SPCA506 - tristate "SPCA506 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA506 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca506. - -config USB_GSPCA_SPCA508 - tristate "SPCA508 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA508 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca508. - -config USB_GSPCA_SPCA561 - tristate "SPCA561 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SPCA561 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca561. - -config USB_GSPCA_STK014 - tristate "Syntek DV4000 (STK014) USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the STK014 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_stk014. - -config USB_GSPCA_SUNPLUS - tristate "SUNPLUS USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the Sunplus - SPCA504(abc) SPCA533 SPCA536 chips. - - To compile this driver as a module, choose M here: the - module will be called gspca_spca5xx. - -config USB_GSPCA_T613 - tristate "T613 (JPEG Compliance) USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the T613 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_t613. - -config USB_GSPCA_TV8532 - tristate "TV8532 USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the TV8531 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_tv8532. - -config USB_GSPCA_VC032X - tristate "VC032X USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the VC032X chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_vc032x. - -config USB_GSPCA_ZC3XX - tristate "VC3xx USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the ZC3XX chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_zc3xx. - -endif + To compile this driver as modules, choose M here: the + modules will be called gspca_xxxx. diff --git a/trunk/drivers/media/video/gspca/Makefile b/trunk/drivers/media/video/gspca/Makefile index 22734f5a6c32..e68a8965297a 100644 --- a/trunk/drivers/media/video/gspca/Makefile +++ b/trunk/drivers/media/video/gspca/Makefile @@ -1,48 +1,29 @@ -obj-$(CONFIG_USB_GSPCA) += gspca_main.o -obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o -obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o -obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o -obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o -obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o -obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o -obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o -obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o -obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o -obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o -obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o -obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o -obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o -obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o -obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o -obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o -obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o -obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o -obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o -obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o -obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o - -gspca_main-objs := gspca.o -gspca_conex-objs := conex.o -gspca_etoms-objs := etoms.o -gspca_finepix-objs := finepix.o -gspca_mars-objs := mars.o -gspca_ov519-objs := ov519.o -gspca_pac207-objs := pac207.o -gspca_pac7311-objs := pac7311.o -gspca_sonixb-objs := sonixb.o -gspca_sonixj-objs := sonixj.o -gspca_spca500-objs := spca500.o -gspca_spca501-objs := spca501.o -gspca_spca505-objs := spca505.o -gspca_spca506-objs := spca506.o -gspca_spca508-objs := spca508.o -gspca_spca561-objs := spca561.o -gspca_stk014-objs := stk014.o -gspca_sunplus-objs := sunplus.o -gspca_t613-objs := t613.o -gspca_tv8532-objs := tv8532.o -gspca_vc032x-objs := vc032x.o -gspca_zc3xx-objs := zc3xx.o - -obj-$(CONFIG_USB_M5602) += m5602/ +obj-$(CONFIG_USB_GSPCA) += gspca_main.o \ + gspca_conex.o gspca_etoms.o gspca_mars.o \ + gspca_ov519.o gspca_pac207.o gspca_pac7311.o \ + gspca_sonixb.o gspca_sonixj.o gspca_spca500.o gspca_spca501.o \ + gspca_spca505.o gspca_spca506.o gspca_spca508.o gspca_spca561.o \ + gspca_sunplus.o gspca_stk014.o gspca_t613.o gspca_tv8532.o \ + gspca_vc032x.o gspca_zc3xx.o +gspca_main-objs := gspca.o +gspca_conex-objs := conex.o +gspca_etoms-objs := etoms.o +gspca_mars-objs := mars.o +gspca_ov519-objs := ov519.o +gspca_pac207-objs := pac207.o +gspca_pac7311-objs := pac7311.o +gspca_sonixb-objs := sonixb.o +gspca_sonixj-objs := sonixj.o +gspca_spca500-objs := spca500.o +gspca_spca501-objs := spca501.o +gspca_spca505-objs := spca505.o +gspca_spca506-objs := spca506.o +gspca_spca508-objs := spca508.o +gspca_spca561-objs := spca561.o +gspca_stk014-objs := stk014.o +gspca_sunplus-objs := sunplus.o +gspca_t613-objs := t613.o +gspca_tv8532-objs := tv8532.o +gspca_vc032x-objs := vc032x.o +gspca_zc3xx-objs := zc3xx.o diff --git a/trunk/drivers/media/video/gspca/conex.c b/trunk/drivers/media/video/gspca/conex.c index a9d51ba7c57c..4d9f4cc255a9 100644 --- a/trunk/drivers/media/video/gspca/conex.c +++ b/trunk/drivers/media/video/gspca/conex.c @@ -837,13 +837,12 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { cx11646_initsize(gspca_dev); cx11646_fw(gspca_dev); cx_sensor(gspca_dev); cx11646_jpeg(gspca_dev); - return 0; } static void sd_stop0(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/etoms.c b/trunk/drivers/media/video/gspca/etoms.c index 3be30b420a26..4ff0e386914b 100644 --- a/trunk/drivers/media/video/gspca/etoms.c +++ b/trunk/drivers/media/video/gspca/etoms.c @@ -691,7 +691,7 @@ static int sd_init(struct gspca_dev *gspca_dev) } /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -704,7 +704,6 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); et_video(gspca_dev, 1); /* video on */ - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/finepix.c b/trunk/drivers/media/video/gspca/finepix.c deleted file mode 100644 index 65d3cbfe6b27..000000000000 --- a/trunk/drivers/media/video/gspca/finepix.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Fujifilm Finepix subdriver - * - * Copyright (C) 2008 Frank Zago - * - * 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 - * 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 - */ - -#define MODULE_NAME "finepix" - -#include "gspca.h" - -MODULE_AUTHOR("Frank Zago "); -MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver"); -MODULE_LICENSE("GPL"); - -/* Default timeout, in ms */ -#define FPIX_TIMEOUT (HZ / 10) - -/* Maximum transfer size to use. The windows driver reads by chunks of - * 0x2000 bytes, so do the same. Note: reading more seems to work - * too. */ -#define FPIX_MAX_TRANSFER 0x2000 - -/* Structure to hold all of our device specific stuff */ -struct usb_fpix { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - /* - * USB stuff - */ - struct usb_ctrlrequest ctrlreq; - struct urb *control_urb; - struct timer_list bulk_timer; - - enum { - FPIX_NOP, /* inactive, else streaming */ - FPIX_RESET, /* must reset */ - FPIX_REQ_FRAME, /* requesting a frame */ - FPIX_READ_FRAME, /* reading frame */ - } state; - - /* - * Driver stuff - */ - struct delayed_work wqe; - struct completion can_close; - int streaming; -}; - -/* Delay after which claim the next frame. If the delay is too small, - * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms - * will fail every 4 or 5 frames, but 30ms is perfect. */ -#define NEXT_FRAME_DELAY (((HZ * 30) + 999) / 1000) - -#define dev_new_state(new_state) { \ - PDEBUG(D_STREAM, "new state from %d to %d at %s:%d", \ - dev->state, new_state, __func__, __LINE__); \ - dev->state = new_state; \ -} - -/* These cameras only support 320x200. */ -static struct v4l2_pix_format fpix_mode[1] = { - { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0} -}; - -/* Reads part of a frame */ -static void read_frame_part(struct usb_fpix *dev) -{ - int ret; - - PDEBUG(D_STREAM, "read_frame_part"); - - /* Reads part of a frame */ - ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC); - if (ret) { - dev_new_state(FPIX_RESET); - schedule_delayed_work(&dev->wqe, 1); - PDEBUG(D_STREAM, "usb_submit_urb failed with %d", - ret); - } else { - /* Sometimes we never get a callback, so use a timer. - * Is this masking a bug somewhere else? */ - dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150); - add_timer(&dev->bulk_timer); - } -} - -/* Callback for URBs. */ -static void urb_callback(struct urb *urb) -{ - struct gspca_dev *gspca_dev = urb->context; - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - - PDEBUG(D_PACK, - "enter urb_callback - status=%d, length=%d", - urb->status, urb->actual_length); - - if (dev->state == FPIX_READ_FRAME) - del_timer(&dev->bulk_timer); - - if (urb->status != 0) { - /* We kill a stuck urb every 50 frames on average, so don't - * display a log message for that. */ - if (urb->status != -ECONNRESET) - PDEBUG(D_STREAM, "bad URB status %d", urb->status); - dev_new_state(FPIX_RESET); - schedule_delayed_work(&dev->wqe, 1); - } - - switch (dev->state) { - case FPIX_REQ_FRAME: - dev_new_state(FPIX_READ_FRAME); - read_frame_part(dev); - break; - - case FPIX_READ_FRAME: { - unsigned char *data = urb->transfer_buffer; - struct gspca_frame *frame; - - frame = gspca_get_i_frame(&dev->gspca_dev); - if (frame == NULL) - gspca_dev->last_packet_type = DISCARD_PACKET; - if (urb->actual_length < FPIX_MAX_TRANSFER || - (data[urb->actual_length-2] == 0xff && - data[urb->actual_length-1] == 0xd9)) { - - /* If the result is less than what was asked - * for, then it's the end of the - * frame. Sometime the jpeg is not complete, - * but there's nothing we can do. We also end - * here if the the jpeg ends right at the end - * of the frame. */ - if (frame) - gspca_frame_add(gspca_dev, LAST_PACKET, - frame, - data, urb->actual_length); - dev_new_state(FPIX_REQ_FRAME); - schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY); - } else { - - /* got a partial image */ - if (frame) - gspca_frame_add(gspca_dev, - gspca_dev->last_packet_type - == LAST_PACKET - ? FIRST_PACKET : INTER_PACKET, - frame, - data, urb->actual_length); - read_frame_part(dev); - } - break; - } - - case FPIX_NOP: - case FPIX_RESET: - PDEBUG(D_STREAM, "invalid state %d", dev->state); - break; - } -} - -/* Request a new frame */ -static void request_frame(struct usb_fpix *dev) -{ - int ret; - struct gspca_dev *gspca_dev = &dev->gspca_dev; - - /* Setup command packet */ - memset(gspca_dev->usb_buf, 0, 12); - gspca_dev->usb_buf[0] = 0xd3; - gspca_dev->usb_buf[7] = 0x01; - - /* Request a frame */ - dev->ctrlreq.bRequestType = - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; - dev->ctrlreq.bRequest = USB_REQ_GET_STATUS; - dev->ctrlreq.wValue = 0; - dev->ctrlreq.wIndex = 0; - dev->ctrlreq.wLength = cpu_to_le16(12); - - usb_fill_control_urb(dev->control_urb, - gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - (unsigned char *) &dev->ctrlreq, - gspca_dev->usb_buf, - 12, urb_callback, gspca_dev); - - ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC); - if (ret) { - dev_new_state(FPIX_RESET); - schedule_delayed_work(&dev->wqe, 1); - PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret); - } -} - -/*--------------------------------------------------------------------------*/ - -/* State machine. */ -static void fpix_sm(struct work_struct *work) -{ - struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work); - - PDEBUG(D_STREAM, "fpix_sm state %d", dev->state); - - /* verify that the device wasn't unplugged */ - if (!dev->gspca_dev.present) { - PDEBUG(D_STREAM, "device is gone"); - dev_new_state(FPIX_NOP); - complete(&dev->can_close); - return; - } - - if (!dev->streaming) { - PDEBUG(D_STREAM, "stopping state machine"); - dev_new_state(FPIX_NOP); - complete(&dev->can_close); - return; - } - - switch (dev->state) { - case FPIX_RESET: - dev_new_state(FPIX_REQ_FRAME); - schedule_delayed_work(&dev->wqe, HZ / 10); - break; - - case FPIX_REQ_FRAME: - /* get an image */ - request_frame(dev); - break; - - case FPIX_NOP: - case FPIX_READ_FRAME: - PDEBUG(D_STREAM, "invalid state %d", dev->state); - break; - } -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - - cam->cam_mode = fpix_mode; - cam->nmodes = 1; - cam->epaddr = 0x01; /* todo: correct for all cams? */ - cam->bulk_size = FPIX_MAX_TRANSFER; - -/* gspca_dev->nbalt = 1; * use bulk transfer */ - return 0; -} - -/* Stop streaming and free the ressources allocated by sd_start. */ -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - - dev->streaming = 0; - - /* Stop the state machine */ - if (dev->state != FPIX_NOP) - wait_for_completion(&dev->can_close); - - usb_free_urb(dev->control_urb); - dev->control_urb = NULL; -} - -/* Kill an URB that hasn't completed. */ -static void timeout_kill(unsigned long data) -{ - struct urb *urb = (struct urb *) data; - - usb_unlink_urb(urb); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - - INIT_DELAYED_WORK(&dev->wqe, fpix_sm); - - init_timer(&dev->bulk_timer); - dev->bulk_timer.function = timeout_kill; - - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - int ret; - int size_ret; - - /* Reset bulk in endpoint */ - usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr); - - /* Init the device */ - memset(gspca_dev->usb_buf, 0, 12); - gspca_dev->usb_buf[0] = 0xc6; - gspca_dev->usb_buf[8] = 0x20; - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_STATUS, - USB_DIR_OUT | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, - 12, FPIX_TIMEOUT); - - if (ret != 12) { - PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret); - ret = -EIO; - goto error; - } - - /* Read the result of the command. Ignore the result, for it - * varies with the device. */ - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, - gspca_dev->cam.epaddr), - gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret, - FPIX_TIMEOUT); - if (ret != 0) { - PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret); - ret = -EIO; - goto error; - } - - /* Request a frame, but don't read it */ - memset(gspca_dev->usb_buf, 0, 12); - gspca_dev->usb_buf[0] = 0xd3; - gspca_dev->usb_buf[7] = 0x01; - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_STATUS, - USB_DIR_OUT | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, - 12, FPIX_TIMEOUT); - if (ret != 12) { - PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret); - ret = -EIO; - goto error; - } - - /* Again, reset bulk in endpoint */ - usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr); - - /* Allocate a control URB */ - dev->control_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->control_urb) { - PDEBUG(D_STREAM, "No free urbs available"); - ret = -EIO; - goto error; - } - - /* Various initializations. */ - init_completion(&dev->can_close); - dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0]; - dev->gspca_dev.urb[0]->complete = urb_callback; - dev->streaming = 1; - - /* Schedule a frame request. */ - dev_new_state(FPIX_REQ_FRAME); - schedule_delayed_work(&dev->wqe, 1); - - return 0; - -error: - /* Free the ressources */ - sd_stopN(gspca_dev); - return ret; -} - -/* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x04cb, 0x0104)}, - {USB_DEVICE(0x04cb, 0x0109)}, - {USB_DEVICE(0x04cb, 0x010b)}, - {USB_DEVICE(0x04cb, 0x010f)}, - {USB_DEVICE(0x04cb, 0x0111)}, - {USB_DEVICE(0x04cb, 0x0113)}, - {USB_DEVICE(0x04cb, 0x0115)}, - {USB_DEVICE(0x04cb, 0x0117)}, - {USB_DEVICE(0x04cb, 0x0119)}, - {USB_DEVICE(0x04cb, 0x011b)}, - {USB_DEVICE(0x04cb, 0x011d)}, - {USB_DEVICE(0x04cb, 0x0121)}, - {USB_DEVICE(0x04cb, 0x0123)}, - {USB_DEVICE(0x04cb, 0x0125)}, - {USB_DEVICE(0x04cb, 0x0127)}, - {USB_DEVICE(0x04cb, 0x0129)}, - {USB_DEVICE(0x04cb, 0x012b)}, - {USB_DEVICE(0x04cb, 0x012d)}, - {USB_DEVICE(0x04cb, 0x012f)}, - {USB_DEVICE(0x04cb, 0x0131)}, - {USB_DEVICE(0x04cb, 0x013b)}, - {USB_DEVICE(0x04cb, 0x013d)}, - {USB_DEVICE(0x04cb, 0x013f)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct usb_fpix), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, -#endif -}; - -/* -- module insert / remove -- */ -static int __init sd_mod_init(void) -{ - if (usb_register(&sd_driver) < 0) - return -1; - PDEBUG(D_PROBE, "registered"); - return 0; -} -static void __exit sd_mod_exit(void) -{ - usb_deregister(&sd_driver); - PDEBUG(D_PROBE, "deregistered"); -} - -module_init(sd_mod_init); -module_exit(sd_mod_exit); diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c index c21af312ee7c..ac95c55887df 100644 --- a/trunk/drivers/media/video/gspca/gspca.c +++ b/trunk/drivers/media/video/gspca/gspca.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,7 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0) +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 2, 0) static int video_nr = -1; @@ -103,22 +102,6 @@ static struct vm_operations_struct gspca_vm_ops = { .close = gspca_vm_close, }; -/* get the current input frame buffer */ -struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev) -{ - struct gspca_frame *frame; - int i; - - i = gspca_dev->fr_i; - i = gspca_dev->fr_queue[i]; - frame = &gspca_dev->frame[i]; - if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) - != V4L2_BUF_FLAG_QUEUED) - return NULL; - return frame; -} -EXPORT_SYMBOL(gspca_get_i_frame); - /* * fill a video frame from an URB and resubmit */ @@ -127,7 +110,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, { struct gspca_frame *frame; __u8 *data; /* address of data in the iso message */ - int i, len, st; + int i, j, len, st; cam_pkt_op pkt_scan; if (urb->status != 0) { @@ -141,8 +124,11 @@ static void fill_frame(struct gspca_dev *gspca_dev, for (i = 0; i < urb->number_of_packets; i++) { /* check the availability of the frame buffer */ - frame = gspca_get_i_frame(gspca_dev); - if (!frame) { + j = gspca_dev->fr_i; + j = gspca_dev->fr_queue[j]; + frame = &gspca_dev->frame[j]; + if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) + != V4L2_BUF_FLAG_QUEUED) { gspca_dev->last_packet_type = DISCARD_PACKET; break; } @@ -191,39 +177,6 @@ static void isoc_irq(struct urb *urb fill_frame(gspca_dev, urb); } -/* - * bulk message interrupt from the USB device - */ -static void bulk_irq(struct urb *urb -) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - struct gspca_frame *frame; - - PDEBUG(D_PACK, "bulk irq"); - if (!gspca_dev->streaming) - return; - if (urb->status != 0 && urb->status != -ECONNRESET) { -#ifdef CONFIG_PM - if (!gspca_dev->frozen) -#endif - PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; /* disconnection ? */ - } - - /* check the availability of the frame buffer */ - frame = gspca_get_i_frame(gspca_dev); - if (!frame) { - gspca_dev->last_packet_type = DISCARD_PACKET; - } else { - PDEBUG(D_PACK, "packet l:%d", urb->actual_length); - gspca_dev->sd_desc->pkt_scan(gspca_dev, - frame, - urb->transfer_buffer, - urb->actual_length); - } -} - /* * add data to the current frame * @@ -237,7 +190,7 @@ static void bulk_irq(struct urb *urb * On LAST_PACKET, a new frame is returned. */ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, - enum gspca_packet_type packet_type, + int packet_type, struct gspca_frame *frame, const __u8 *data, int len) @@ -279,7 +232,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, } gspca_dev->last_packet_type = packet_type; - /* if last packet, wake up the application and advance in the queue */ + /* if last packet, wake the application and advance in the queue */ if (packet_type == LAST_PACKET) { frame->v4l2_buf.bytesused = frame->data_end - frame->data; frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; @@ -317,6 +270,7 @@ static void *rvmalloc(unsigned long size) void *mem; unsigned long adr; +/* size = PAGE_ALIGN(size); (already done) */ mem = vmalloc_32(size); if (mem != NULL) { adr = (unsigned long) mem; @@ -420,11 +374,10 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) } /* - * look for an input transfer endpoint in an alternate setting + * search an input isochronous endpoint in an alternate setting */ -static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, - __u8 epaddr, - __u8 xfer) +static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt, + __u8 epaddr) { struct usb_host_endpoint *ep; int i, attr; @@ -435,7 +388,7 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, if (ep->desc.bEndpointAddress == epaddr) { attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - if (attr == xfer) + if (attr == USB_ENDPOINT_XFER_ISOC) return ep; break; } @@ -444,14 +397,14 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, } /* - * look for an input (isoc or bulk) endpoint + * search an input isochronous endpoint * * The endpoint is defined by the subdriver. * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep). * This routine may be called many times when the bandwidth is too small * (the bandwidth is checked on urb submit). */ -static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) +static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) { struct usb_interface *intf; struct usb_host_endpoint *ep; @@ -460,41 +413,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); ep = NULL; i = gspca_dev->alt; /* previous alt setting */ - - /* try isoc */ while (--i > 0) { /* alt 0 is unusable */ - ep = alt_xfer(&intf->altsetting[i], - gspca_dev->cam.epaddr, - USB_ENDPOINT_XFER_ISOC); + ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); if (ep) break; } - - /* if no isoc, try bulk */ if (ep == NULL) { - ep = alt_xfer(&intf->altsetting[0], - gspca_dev->cam.epaddr, - USB_ENDPOINT_XFER_BULK); - if (ep == NULL) { - err("no transfer endpoint found"); - return NULL; - } + err("no ISOC endpoint found"); + return NULL; } - PDEBUG(D_STREAM, "use alt %d ep 0x%02x", + PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x", i, ep->desc.bEndpointAddress); - if (i > 0) { - ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); - if (ret < 0) { - err("set interface err %d", ret); - return NULL; - } + ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); + if (ret < 0) { + err("set interface err %d", ret); + return NULL; } gspca_dev->alt = i; /* memorize the current alt setting */ return ep; } /* - * create the URBs for image transfer + * create the isochronous URBs */ static int create_urbs(struct gspca_dev *gspca_dev, struct usb_host_endpoint *ep) @@ -505,27 +445,15 @@ static int create_urbs(struct gspca_dev *gspca_dev, /* calculate the packet size and the number of packets */ psize = le16_to_cpu(ep->desc.wMaxPacketSize); - if (gspca_dev->alt != 0) { /* isoc */ - - /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - npkt = ISO_MAX_SIZE / psize; - if (npkt > ISO_MAX_PKT) - npkt = ISO_MAX_PKT; - bsize = psize * npkt; - PDEBUG(D_STREAM, - "isoc %d pkts size %d = bsize:%d", - npkt, psize, bsize); - nurbs = DEF_NURBS; - } else { /* bulk */ - npkt = 0; - bsize = gspca_dev->cam. bulk_size; - if (bsize == 0) - bsize = psize; - PDEBUG(D_STREAM, "bulk bsize:%d", bsize); - nurbs = 1; - } - + /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ + psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + npkt = ISO_MAX_SIZE / psize; + if (npkt > ISO_MAX_PKT) + npkt = ISO_MAX_PKT; + bsize = psize * npkt; + PDEBUG(D_STREAM, + "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); + nurbs = DEF_NURBS; gspca_dev->nurbs = nurbs; for (n = 0; n < nurbs; n++) { urb = usb_alloc_urb(npkt, GFP_KERNEL); @@ -548,24 +476,17 @@ static int create_urbs(struct gspca_dev *gspca_dev, gspca_dev->urb[n] = urb; urb->dev = gspca_dev->dev; urb->context = gspca_dev; - urb->transfer_buffer_length = bsize; - if (npkt != 0) { /* ISOC */ - urb->pipe = usb_rcvisocpipe(gspca_dev->dev, - ep->desc.bEndpointAddress); - urb->transfer_flags = URB_ISO_ASAP + urb->pipe = usb_rcvisocpipe(gspca_dev->dev, + ep->desc.bEndpointAddress); + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - urb->interval = ep->desc.bInterval; - urb->complete = isoc_irq; - urb->number_of_packets = npkt; - for (i = 0; i < npkt; i++) { - urb->iso_frame_desc[i].length = psize; - urb->iso_frame_desc[i].offset = psize * i; - } - } else { /* bulk */ - urb->pipe = usb_rcvbulkpipe(gspca_dev->dev, - ep->desc.bEndpointAddress), - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; - urb->complete = bulk_irq; + urb->interval = ep->desc.bInterval; + urb->complete = isoc_irq; + urb->number_of_packets = npkt; + urb->transfer_buffer_length = bsize; + for (i = 0; i < npkt; i++) { + urb->iso_frame_desc[i].length = psize; + urb->iso_frame_desc[i].offset = psize * i; } } return 0; @@ -587,7 +508,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) gspca_dev->alt = gspca_dev->nbalt; for (;;) { PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); - ep = get_ep(gspca_dev); + ep = get_isoc_ep(gspca_dev); if (ep == NULL) { ret = -EIO; goto out; @@ -597,18 +518,10 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) goto out; /* start the cam */ - ret = gspca_dev->sd_desc->start(gspca_dev); - if (ret < 0) { - destroy_urbs(gspca_dev); - goto out; - } + gspca_dev->sd_desc->start(gspca_dev); gspca_dev->streaming = 1; atomic_set(&gspca_dev->nevent, 0); - /* bulk transfers are started by the subdriver */ - if (gspca_dev->alt == 0) - break; - /* submit the URBs */ for (n = 0; n < gspca_dev->nurbs; n++) { ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); @@ -640,7 +553,7 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) return ret; } -/* Note: both the queue and the usb locks should be held when calling this */ +/* Note both the queue and the usb lock should be hold when calling this */ static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; @@ -846,16 +759,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return ret; } -static void gspca_delete(struct kref *kref) -{ - struct gspca_dev *gspca_dev = container_of(kref, struct gspca_dev, kref); - - PDEBUG(D_STREAM, "device deleted"); - - kfree(gspca_dev->usb_buf); - kfree(gspca_dev); -} - static int dev_open(struct inode *inode, struct file *file) { struct gspca_dev *gspca_dev; @@ -875,19 +778,13 @@ static int dev_open(struct inode *inode, struct file *file) goto out; } gspca_dev->users++; - - /* one more user */ - kref_get(&gspca_dev->kref); - file->private_data = gspca_dev; #ifdef GSPCA_DEBUG /* activate the v4l2 debug */ if (gspca_debug & D_V4L2) - gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL - | V4L2_DEBUG_IOCTL_ARG; + gspca_dev->vdev.debug |= 3; else - gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL - | V4L2_DEBUG_IOCTL_ARG); + gspca_dev->vdev.debug &= ~3; #endif ret = 0; out: @@ -921,11 +818,7 @@ static int dev_close(struct inode *inode, struct file *file) } file->private_data = NULL; mutex_unlock(&gspca_dev->queue_lock); - PDEBUG(D_STREAM, "close done"); - - kref_put(&gspca_dev->kref, gspca_delete); - return 0; } @@ -936,6 +829,7 @@ static int vidioc_querycap(struct file *file, void *priv, memset(cap, 0, sizeof *cap); strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); +/* strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */ if (gspca_dev->dev->product != NULL) { strncpy(cap->card, gspca_dev->dev->product, sizeof cap->card); @@ -1569,6 +1463,7 @@ static int vidioc_qbuf(struct file *file, void *priv, } frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; +/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */ if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; @@ -1715,7 +1610,7 @@ static ssize_t dev_read(struct file *file, char __user *data, } /* if the process slept for more than 1 second, - * get a newer frame */ + * get anewer frame */ frame = &gspca_dev->frame[v4l2_buf.index]; if (--n < 0) break; /* avoid infinite loop */ @@ -1833,21 +1728,21 @@ int gspca_dev_probe(struct usb_interface *intf, if (dev_size < sizeof *gspca_dev) dev_size = sizeof *gspca_dev; gspca_dev = kzalloc(dev_size, GFP_KERNEL); - if (!gspca_dev) { + if (gspca_dev == NULL) { err("couldn't kzalloc gspca struct"); - return -ENOMEM; + return -EIO; } - kref_init(&gspca_dev->kref); gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); if (!gspca_dev->usb_buf) { err("out of memory"); - ret = -ENOMEM; + ret = -EIO; goto out; } gspca_dev->dev = dev; gspca_dev->iface = interface->bInterfaceNumber; gspca_dev->nbalt = intf->num_altsetting; gspca_dev->sd_desc = sd_desc; +/* gspca_dev->users = 0; (done by kzalloc) */ gspca_dev->nbufread = 2; /* configure the subdriver and initialize the USB device */ @@ -1886,7 +1781,8 @@ int gspca_dev_probe(struct usb_interface *intf, PDEBUG(D_PROBE, "probe ok"); return 0; out: - kref_put(&gspca_dev->kref, gspca_delete); + kfree(gspca_dev->usb_buf); + kfree(gspca_dev); return ret; } EXPORT_SYMBOL(gspca_dev_probe); @@ -1901,16 +1797,25 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - -/* We don't want people trying to open up the device */ - video_unregister_device(&gspca_dev->vdev); - + if (!gspca_dev) + return; gspca_dev->present = 0; + mutex_lock(&gspca_dev->queue_lock); + mutex_lock(&gspca_dev->usb_lock); gspca_dev->streaming = 0; - - kref_put(&gspca_dev->kref, gspca_delete); - + destroy_urbs(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + mutex_unlock(&gspca_dev->queue_lock); + while (gspca_dev->users != 0) { /* wait until fully closed */ + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); /* wake processes */ + schedule(); + } +/* We don't want people trying to open up the device */ + video_unregister_device(&gspca_dev->vdev); +/* Free the memory */ + kfree(gspca_dev->usb_buf); + kfree(gspca_dev); PDEBUG(D_PROBE, "disconnect complete"); } EXPORT_SYMBOL(gspca_disconnect); diff --git a/trunk/drivers/media/video/gspca/gspca.h b/trunk/drivers/media/video/gspca/gspca.h index 4779dd0b06da..c17625cff9ba 100644 --- a/trunk/drivers/media/video/gspca/gspca.h +++ b/trunk/drivers/media/video/gspca/gspca.h @@ -49,14 +49,13 @@ extern int gspca_debug; } while (0) #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ -/* image transfers */ -#define MAX_NURBS 4 /* max number of URBs */ +/* ISOC transfers */ +#define MAX_NURBS 16 /* max number of URBs */ #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ /* device information - set at probe time */ struct cam { - int bulk_size; /* buffer size when image transfer by bulk */ struct v4l2_pix_format *cam_mode; /* size nmodes */ char nmodes; __u8 epaddr; @@ -94,7 +93,7 @@ struct sd_desc { /* mandatory operations */ cam_cf_op config; /* called on probe */ cam_op init; /* called on probe and resume */ - cam_op start; /* called on stream on */ + cam_v_op start; /* called on stream on */ cam_pkt_op pkt_scan; /* optional operations */ cam_v_op stopN; /* called on stream off - main alt */ @@ -106,12 +105,10 @@ struct sd_desc { }; /* packet types when moving from iso buf to frame buf */ -enum gspca_packet_type { - DISCARD_PACKET, - FIRST_PACKET, - INTER_PACKET, - LAST_PACKET -}; +#define DISCARD_PACKET 0 +#define FIRST_PACKET 1 +#define INTER_PACKET 2 +#define LAST_PACKET 3 struct gspca_frame { __u8 *data; /* frame buffer */ @@ -124,7 +121,6 @@ struct gspca_dev { struct video_device vdev; /* !! must be the first item */ struct file_operations fops; struct usb_device *dev; - struct kref kref; struct file *capt_file; /* file doing video capture */ struct cam cam; /* device information */ @@ -177,11 +173,10 @@ int gspca_dev_probe(struct usb_interface *intf, struct module *module); void gspca_disconnect(struct usb_interface *intf); struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, - enum gspca_packet_type packet_type, + int packet_type, struct gspca_frame *frame, const __u8 *data, int len); -struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev); #ifdef CONFIG_PM int gspca_suspend(struct usb_interface *intf, pm_message_t message); int gspca_resume(struct usb_interface *intf); diff --git a/trunk/drivers/media/video/gspca/m5602/Kconfig b/trunk/drivers/media/video/gspca/m5602/Kconfig deleted file mode 100644 index 5a69016ed75f..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config USB_M5602 - tristate "ALi USB m5602 Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the - ALi m5602 connected to various image sensors. - - See for more info. - - To compile this driver as a module, choose M here: the - module will be called gspca_m5602. diff --git a/trunk/drivers/media/video/gspca/m5602/Makefile b/trunk/drivers/media/video/gspca/m5602/Makefile deleted file mode 100644 index 226ab4fc9d60..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -obj-$(CONFIG_USB_M5602) += gspca_m5602.o - -gspca_m5602-objs := m5602_core.o \ - m5602_ov9650.o \ - m5602_mt9m111.o \ - m5602_po1030.o \ - m5602_s5k83a.o \ - m5602_s5k4aa.o - -EXTRA_CFLAGS += -Idrivers/media/video/gspca - diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h b/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h deleted file mode 100644 index c786d7d3d44a..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_bridge.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * USB Driver for ALi m5602 based webcams - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_BRIDGE_H_ -#define M5602_BRIDGE_H_ - -#include "gspca.h" - -#define MODULE_NAME "ALi m5602" - -/*****************************************************************************/ - -#undef PDEBUG -#undef info -#undef err - -#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ - format "\n" , ## arg) -#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \ - format "\n" , ## arg) - -/* Debug parameters */ -#define DBG_INIT 0x1 -#define DBG_PROBE 0x2 -#define DBG_V4L2 0x4 -#define DBG_TRACE 0x8 -#define DBG_DATA 0x10 -#define DBG_V4L2_CID 0x20 -#define DBG_GSPCA 0x40 - -#define PDEBUG(level, fmt, args...) \ - do { \ - if (m5602_debug & level) \ - info("[%s:%d] " fmt, __func__, __LINE__ , \ - ## args); \ - } while (0) - -/*****************************************************************************/ - -#define M5602_XB_SENSOR_TYPE 0x00 -#define M5602_XB_SENSOR_CTRL 0x01 -#define M5602_XB_LINE_OF_FRAME_H 0x02 -#define M5602_XB_LINE_OF_FRAME_L 0x03 -#define M5602_XB_PIX_OF_LINE_H 0x04 -#define M5602_XB_PIX_OF_LINE_L 0x05 -#define M5602_XB_VSYNC_PARA 0x06 -#define M5602_XB_HSYNC_PARA 0x07 -#define M5602_XB_TEST_MODE_1 0x08 -#define M5602_XB_TEST_MODE_2 0x09 -#define M5602_XB_SIG_INI 0x0a -#define M5602_XB_DS_PARA 0x0e -#define M5602_XB_TRIG_PARA 0x0f -#define M5602_XB_CLK_PD 0x10 -#define M5602_XB_MCU_CLK_CTRL 0x12 -#define M5602_XB_MCU_CLK_DIV 0x13 -#define M5602_XB_SEN_CLK_CTRL 0x14 -#define M5602_XB_SEN_CLK_DIV 0x15 -#define M5602_XB_AUD_CLK_CTRL 0x16 -#define M5602_XB_AUD_CLK_DIV 0x17 -#define M5602_XB_DEVCTR1 0x41 -#define M5602_XB_EPSETR0 0x42 -#define M5602_XB_EPAFCTR 0x47 -#define M5602_XB_EPBFCTR 0x49 -#define M5602_XB_EPEFCTR 0x4f -#define M5602_XB_TEST_REG 0x53 -#define M5602_XB_ALT2SIZE 0x54 -#define M5602_XB_ALT3SIZE 0x55 -#define M5602_XB_OBSFRAME 0x56 -#define M5602_XB_PWR_CTL 0x59 -#define M5602_XB_ADC_CTRL 0x60 -#define M5602_XB_ADC_DATA 0x61 -#define M5602_XB_MISC_CTRL 0x62 -#define M5602_XB_SNAPSHOT 0x63 -#define M5602_XB_SCRATCH_1 0x64 -#define M5602_XB_SCRATCH_2 0x65 -#define M5602_XB_SCRATCH_3 0x66 -#define M5602_XB_SCRATCH_4 0x67 -#define M5602_XB_I2C_CTRL 0x68 -#define M5602_XB_I2C_CLK_DIV 0x69 -#define M5602_XB_I2C_DEV_ADDR 0x6a -#define M5602_XB_I2C_REG_ADDR 0x6b -#define M5602_XB_I2C_DATA 0x6c -#define M5602_XB_I2C_STATUS 0x6d -#define M5602_XB_GPIO_DAT_H 0x70 -#define M5602_XB_GPIO_DAT_L 0x71 -#define M5602_XB_GPIO_DIR_H 0x72 -#define M5602_XB_GPIO_DIR_L 0x73 -#define M5602_XB_GPIO_EN_H 0x74 -#define M5602_XB_GPIO_EN_L 0x75 -#define M5602_XB_GPIO_DAT 0x76 -#define M5602_XB_GPIO_DIR 0x77 -#define M5602_XB_MISC_CTL 0x70 - -#define I2C_BUSY 0x80 - -/*****************************************************************************/ - -/* Driver info */ -#define DRIVER_AUTHOR "ALi m5602 Linux Driver Project" -#define DRIVER_DESC "ALi m5602 webcam driver" - -#define M5602_ISOC_ENDPOINT_ADDR 0x81 -#define M5602_INTR_ENDPOINT_ADDR 0x82 - -#define M5602_MAX_FRAMES 32 -#define M5602_URBS 2 -#define M5602_ISOC_PACKETS 14 - -#define M5602_URB_TIMEOUT msecs_to_jiffies(2 * M5602_ISOC_PACKETS) -#define M5602_URB_MSG_TIMEOUT 5000 -#define M5602_FRAME_TIMEOUT 2 - -/*****************************************************************************/ - -/* A skeleton used for sending messages to the m5602 bridge */ -static const unsigned char bridge_urb_skeleton[] = { - 0x13, 0x00, 0x81, 0x00 -}; - -/* A skeleton used for sending messages to the sensor */ -static const unsigned char sensor_urb_skeleton[] = { - 0x23, M5602_XB_GPIO_EN_H, 0x81, 0x06, - 0x23, M5602_XB_MISC_CTRL, 0x81, 0x80, - 0x13, M5602_XB_I2C_DEV_ADDR, 0x81, 0x00, - 0x13, M5602_XB_I2C_REG_ADDR, 0x81, 0x00, - 0x13, M5602_XB_I2C_DATA, 0x81, 0x00, - 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11 -}; - -/* m5602 device descriptor, currently it just wraps the m5602_camera struct */ -struct sd { - struct gspca_dev gspca_dev; - - /* The name of the m5602 camera */ - char *name; - - /* A pointer to the currently connected sensor */ - struct m5602_sensor *sensor; - - struct sd_desc *desc; - - /* The current frame's id, used to detect frame boundaries */ - u8 frame_id; - - /* The current frame count */ - u32 frame_count; -}; - -int m5602_read_bridge( - struct sd *sd, u8 address, u8 *i2c_data); - -int m5602_write_bridge( - struct sd *sd, u8 address, u8 i2c_data); - -#endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_core.c b/trunk/drivers/media/video/gspca/m5602/m5602_core.c deleted file mode 100644 index 19d5e351ccc1..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_core.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * USB Driver for ALi m5602 based webcams - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include "m5602_ov9650.h" -#include "m5602_mt9m111.h" -#include "m5602_po1030.h" -#include "m5602_s5k83a.h" -#include "m5602_s5k4aa.h" - -/* Kernel module parameters */ -int force_sensor; -int dump_bridge; -int dump_sensor; -unsigned int m5602_debug; - -static const __devinitdata struct usb_device_id m5602_table[] = { - {USB_DEVICE(0x0402, 0x5602)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, m5602_table); - -/* Reads a byte from the m5602 */ -int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x04, 0xc0, 0x14, - 0x8100 + address, buf, - 1, M5602_URB_MSG_TIMEOUT); - *i2c_data = buf[0]; - - PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x", - address, *i2c_data); - - /* usb_control_msg(...) returns the number of bytes sent upon success, - mask that and return zero upon success instead*/ - return (err < 0) ? err : 0; -} - -/* Writes a byte to to the m5602 */ -int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) -{ - int err; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x", - address, i2c_data); - - memcpy(buf, bridge_urb_skeleton, - sizeof(bridge_urb_skeleton)); - buf[1] = address; - buf[3] = i2c_data; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 4, M5602_URB_MSG_TIMEOUT); - - /* usb_control_msg(...) returns the number of bytes sent upon success, - mask that and return zero upon success instead */ - return (err < 0) ? err : 0; -} - -/* Dump all the registers of the m5602 bridge, - unfortunately this breaks the camera until it's power cycled */ -static void m5602_dump_bridge(struct sd *sd) -{ - int i; - for (i = 0; i < 0x80; i++) { - unsigned char val = 0; - m5602_read_bridge(sd, i, &val); - info("ALi m5602 address 0x%x contains 0x%x", i, val); - } - info("Warning: The camera probably won't work until it's power cycled"); -} - -static int m5602_probe_sensor(struct sd *sd) -{ - /* Try the po1030 */ - sd->sensor = &po1030; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the mt9m111 sensor */ - sd->sensor = &mt9m111; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the s5k4aa */ - sd->sensor = &s5k4aa; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the ov9650 */ - sd->sensor = &ov9650; - if (!sd->sensor->probe(sd)) - return 0; - - /* Try the s5k83a */ - sd->sensor = &s5k83a; - if (!sd->sensor->probe(sd)) - return 0; - - /* More sensor probe function goes here */ - info("Failed to find a sensor"); - sd->sensor = NULL; - return -ENODEV; -} - -static int m5602_configure(struct gspca_dev *gspca_dev, - const struct usb_device_id *id); - -static int m5602_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int err; - - PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam"); - /* Run the init sequence */ - err = sd->sensor->init(sd); - - return err; -} - -static int m5602_start_transfer(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* Send start command to the camera */ - const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; - memcpy(buf, buffer, sizeof(buffer)); - usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), - 0x04, 0x40, 0x19, 0x0000, buf, - 4, M5602_URB_MSG_TIMEOUT); - - PDEBUG(DBG_V4L2, "Transfer started"); - return 0; -} - -static void m5602_urb_complete(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, - __u8 *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (len < 6) { - PDEBUG(DBG_DATA, "Packet is less than 6 bytes"); - return; - } - - /* Frame delimiter: ff xx xx xx ff ff */ - if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff && - data[2] != sd->frame_id) { - PDEBUG(DBG_DATA, "Frame delimiter detected"); - sd->frame_id = data[2]; - - /* Remove the extra fluff appended on each header */ - data += 6; - len -= 6; - - /* Complete the last frame (if any) */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, 0); - sd->frame_count++; - - /* Create a new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); - - PDEBUG(DBG_V4L2, "Starting new frame %d", - sd->frame_count); - - } else { - int cur_frame_len = frame->data_end - frame->data; - - /* Remove urb header */ - data += 4; - len -= 4; - - if (cur_frame_len + len <= frame->v4l2_buf.length) { - PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes", - sd->frame_count, len); - - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); - } else if (frame->v4l2_buf.length - cur_frame_len > 0) { - /* Add the remaining data up to frame size */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, - frame->v4l2_buf.length - cur_frame_len); - } - } -} - -static void m5602_stop_transfer(struct gspca_dev *gspca_dev) -{ - /* Is there are a command to stop a data transfer? */ -} - -/* sub-driver description, the ctrl and nctrl is filled at probe time */ -static struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = m5602_configure, - .init = m5602_init, - .start = m5602_start_transfer, - .stopN = m5602_stop_transfer, - .pkt_scan = m5602_urb_complete -}; - -/* this function is called at probe time */ -static int m5602_configure(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct cam *cam; - int err; - - PDEBUG(DBG_GSPCA, "m5602_configure start"); - - cam = &gspca_dev->cam; - cam->epaddr = M5602_ISOC_ENDPOINT_ADDR; - sd->desc = &sd_desc; - - if (dump_bridge) - m5602_dump_bridge(sd); - - /* Probe sensor */ - err = m5602_probe_sensor(sd); - if (err) - goto fail; - - PDEBUG(DBG_GSPCA, "m5602_configure end"); - return 0; - -fail: - PDEBUG(DBG_GSPCA, "m5602_configure failed"); - cam->cam_mode = NULL; - cam->nmodes = 0; - - return err; -} - -static int m5602_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = m5602_table, - .probe = m5602_probe, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, -#endif - .disconnect = gspca_disconnect -}; - -/* -- module insert / remove -- */ -static int __init mod_m5602_init(void) -{ - if (usb_register(&sd_driver) < 0) - return -1; - PDEBUG(D_PROBE, "m5602 module registered"); - return 0; -} -static void __exit mod_m5602_exit(void) -{ - usb_deregister(&sd_driver); - PDEBUG(D_PROBE, "m5602 module deregistered"); -} - -module_init(mod_m5602_init); -module_exit(mod_m5602_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "toggles debug on/off"); - -module_param(force_sensor, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(force_sensor, - "force detection of sensor, " - "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030"); - -module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); - -module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_sensor, "Dumps all usb sensor registers " - "at startup providing a sensor is found"); diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c deleted file mode 100644 index 566d4925a0e8..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Driver for the mt9m111 sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include "m5602_mt9m111.h" - -int mt9m111_probe(struct sd *sd) -{ - u8 data[2] = {0x00, 0x00}; - int i; - - if (force_sensor) { - if (force_sensor == MT9M111_SENSOR) { - info("Forcing a %s sensor", mt9m111.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - info("Probing for a mt9m111 sensor"); - - /* Do the preinit */ - for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) { - if (preinit_mt9m111[i][0] == BRIDGE) { - m5602_write_bridge(sd, - preinit_mt9m111[i][1], - preinit_mt9m111[i][2]); - } else { - data[0] = preinit_mt9m111[i][2]; - data[1] = preinit_mt9m111[i][3]; - mt9m111_write_sensor(sd, - preinit_mt9m111[i][1], data, 2); - } - } - - if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) - return -ENODEV; - - if ((data[0] == 0x14) && (data[1] == 0x3a)) { - info("Detected a mt9m111 sensor"); - goto sensor_found; - } - - return -ENODEV; - -sensor_found: - sd->gspca_dev.cam.cam_mode = mt9m111.modes; - sd->gspca_dev.cam.nmodes = mt9m111.nmodes; - sd->desc->ctrls = mt9m111.ctrls; - sd->desc->nctrls = mt9m111.nctrls; - return 0; -} - -int mt9m111_init(struct sd *sd) -{ - int i, err = 0; - - /* Init the sensor */ - for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) { - u8 data[2]; - - if (init_mt9m111[i][0] == BRIDGE) { - err = m5602_write_bridge(sd, - init_mt9m111[i][1], - init_mt9m111[i][2]); - } else { - data[0] = init_mt9m111[i][2]; - data[1] = init_mt9m111[i][3]; - err = mt9m111_write_sensor(sd, - init_mt9m111[i][1], data, 2); - } - } - - if (dump_sensor) - mt9m111_dump_registers(sd); - - return (err < 0) ? err : 0; -} - -int mt9m111_power_down(struct sd *sd) -{ - return 0; -} - -int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - - err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - *val = data[0] & MT9M111_RMB_MIRROR_ROWS; - PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); - - return (err < 0) ? err : 0; -} - -int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); - - /* Set the correct page map */ - err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - goto out; - - err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - if (err < 0) - goto out; - - data[0] = (data[0] & 0xfe) | val; - err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); -out: - return (err < 0) ? err : 0; -} - -int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - - err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - *val = data[0] & MT9M111_RMB_MIRROR_COLS; - PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); - - return (err < 0) ? err : 0; -} - -int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); - - /* Set the correct page map */ - err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - goto out; - - err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); - if (err < 0) - goto out; - - data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); - err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); -out: - return (err < 0) ? err : 0; -} - -int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err, tmp; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - - err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); - tmp = ((data[1] << 8) | data[0]); - - *val = ((tmp & (1 << 10)) * 2) | - ((tmp & (1 << 9)) * 2) | - ((tmp & (1 << 8)) * 2) | - (tmp & 0x7f); - - PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); - - return (err < 0) ? err : 0; -} - -int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err, tmp; - u8 data[2] = {0x00, 0x00}; - struct sd *sd = (struct sd *) gspca_dev; - - /* Set the correct page map */ - err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); - if (err < 0) - goto out; - - if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2) - return -EINVAL; - - if ((val >= INITIAL_MAX_GAIN * 2 * 2) && - (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2)) - tmp = (1 << 10) | (val << 9) | - (val << 8) | (val / 8); - else if ((val >= INITIAL_MAX_GAIN * 2) && - (val < INITIAL_MAX_GAIN * 2 * 2)) - tmp = (1 << 9) | (1 << 8) | (val / 4); - else if ((val >= INITIAL_MAX_GAIN) && - (val < INITIAL_MAX_GAIN * 2)) - tmp = (1 << 8) | (val / 2); - else - tmp = val; - - data[1] = (tmp & 0xff00) >> 8; - data[0] = (tmp & 0xff); - PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp, - data[1], data[0]); - - err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, - data, 2); -out: - return (err < 0) ? err : 0; -} - -int mt9m111_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) { - int err, i; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, - sd->sensor->i2c_slave_id); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a); - if (err < 0) - goto out; - - for (i = 0; i < len && !err; i++) { - err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - - PDEBUG(DBG_TRACE, "Reading sensor register " - "0x%x contains 0x%x ", address, *i2c_data); - } -out: - return (err < 0) ? err : 0; -} - -int mt9m111_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - u8 *p; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* No sensor with a data width larger - than 16 bits has yet been seen, nor with 0 :p*/ - if (len > 2 || !len) - return -EINVAL; - - memcpy(buf, sensor_urb_skeleton, - sizeof(sensor_urb_skeleton)); - - buf[11] = sd->sensor->i2c_slave_id; - buf[15] = address; - - p = buf + 16; - - /* Copy a four byte write sequence for each byte to be written to */ - for (i = 0; i < len; i++) { - memcpy(p, sensor_urb_skeleton + 16, 4); - p[3] = i2c_data[i]; - p += 4; - PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", - address, i2c_data[i]); - } - - /* Copy the tailer */ - memcpy(p, sensor_urb_skeleton + 20, 4); - - /* Set the total length */ - p[3] = 0x10 + len; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 20 + len * 4, M5602_URB_MSG_TIMEOUT); - - return (err < 0) ? err : 0; -} - -void mt9m111_dump_registers(struct sd *sd) -{ - u8 address, value[2] = {0x00, 0x00}; - - info("Dumping the mt9m111 register state"); - - info("Dumping the mt9m111 sensor core registers"); - value[1] = MT9M111_SENSOR_CORE; - mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); - for (address = 0; address < 0xff; address++) { - mt9m111_read_sensor(sd, address, value, 2); - info("register 0x%x contains 0x%x%x", - address, value[0], value[1]); - } - - info("Dumping the mt9m111 color pipeline registers"); - value[1] = MT9M111_COLORPIPE; - mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); - for (address = 0; address < 0xff; address++) { - mt9m111_read_sensor(sd, address, value, 2); - info("register 0x%x contains 0x%x%x", - address, value[0], value[1]); - } - - info("Dumping the mt9m111 camera control registers"); - value[1] = MT9M111_CAMERA_CONTROL; - mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); - for (address = 0; address < 0xff; address++) { - mt9m111_read_sensor(sd, address, value, 2); - info("register 0x%x contains 0x%x%x", - address, value[0], value[1]); - } - - info("mt9m111 register state dump complete"); -} diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h deleted file mode 100644 index 79a5d8878190..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * Driver for the mt9m111 sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * Some defines taken from the mt9m111 sensor driver - * Copyright (C) 2008, Robert Jarzmik - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_MT9M111_H_ -#define M5602_MT9M111_H_ - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define MT9M111_SC_CHIPVER 0x00 -#define MT9M111_SC_ROWSTART 0x01 -#define MT9M111_SC_COLSTART 0x02 -#define MT9M111_SC_WINDOW_HEIGHT 0x03 -#define MT9M111_SC_WINDOW_WIDTH 0x04 -#define MT9M111_SC_HBLANK_CONTEXT_B 0x05 -#define MT9M111_SC_VBLANK_CONTEXT_B 0x06 -#define MT9M111_SC_HBLANK_CONTEXT_A 0x07 -#define MT9M111_SC_VBLANK_CONTEXT_A 0x08 -#define MT9M111_SC_SHUTTER_WIDTH 0x09 -#define MT9M111_SC_ROW_SPEED 0x0a - -#define MT9M111_SC_EXTRA_DELAY 0x0b -#define MT9M111_SC_SHUTTER_DELAY 0x0c -#define MT9M111_SC_RESET 0x0d -#define MT9M111_SC_R_MODE_CONTEXT_B 0x20 -#define MT9M111_SC_R_MODE_CONTEXT_A 0x21 -#define MT9M111_SC_FLASH_CONTROL 0x23 -#define MT9M111_SC_GREEN_1_GAIN 0x2b -#define MT9M111_SC_BLUE_GAIN 0x2c -#define MT9M111_SC_RED_GAIN 0x2d -#define MT9M111_SC_GREEN_2_GAIN 0x2e -#define MT9M111_SC_GLOBAL_GAIN 0x2f - -#define MT9M111_RMB_MIRROR_ROWS (1 << 0) -#define MT9M111_RMB_MIRROR_COLS (1 << 1) - -#define MT9M111_CONTEXT_CONTROL 0xc8 -#define MT9M111_PAGE_MAP 0xf0 -#define MT9M111_BYTEWISE_ADDRESS 0xf1 - -#define MT9M111_CP_OPERATING_MODE_CTL 0x06 -#define MT9M111_CP_LUMA_OFFSET 0x34 -#define MT9M111_CP_LUMA_CLIP 0x35 -#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A 0x3a -#define MT9M111_CP_LENS_CORRECTION_1 0x3b -#define MT9M111_CP_DEFECT_CORR_CONTEXT_A 0x4c -#define MT9M111_CP_DEFECT_CORR_CONTEXT_B 0x4d -#define MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B 0x9b -#define MT9M111_CP_GLOBAL_CLK_CONTROL 0xb3 - -#define MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18 0x65 -#define MT9M111_CC_AWB_PARAMETER_7 0x28 - -#define MT9M111_SENSOR_CORE 0x00 -#define MT9M111_COLORPIPE 0x01 -#define MT9M111_CAMERA_CONTROL 0x02 - -#define INITIAL_MAX_GAIN 64 -#define DEFAULT_GAIN 283 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern int dump_sensor; -extern unsigned int m5602_debug; - -int mt9m111_probe(struct sd *sd); -int mt9m111_init(struct sd *sd); -int mt9m111_power_down(struct sd *sd); - -int mt9m111_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -int mt9m111_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -void mt9m111_dump_registers(struct sd *sd); - -int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); - -static struct m5602_sensor mt9m111 = { - .name = "MT9M111", - - .i2c_slave_id = 0xba, - - .probe = mt9m111_probe, - .init = mt9m111_init, - .power_down = mt9m111_power_down, - - .read_sensor = mt9m111_read_sensor, - .write_sensor = mt9m111_write_sensor, - - .nctrls = 3, - .ctrls = { - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = mt9m111_set_vflip, - .get = mt9m111_get_vflip - }, { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = mt9m111_set_hflip, - .get = mt9m111_get_hflip - }, { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0, - .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, - .step = 1, - .default_value = DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = mt9m111_set_hflip, - .get = mt9m111_get_hflip - } - }, - - .nmodes = 1, - .modes = { - { - M5602_DEFAULT_FRAME_WIDTH, - M5602_DEFAULT_FRAME_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, - .bytesperline = M5602_DEFAULT_FRAME_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } -}; - -static const unsigned char preinit_mt9m111[][4] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00} -}; - -static const unsigned char init_mt9m111[][4] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, - {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, - {SENSOR, MT9M111_SC_RESET, 0xff, 0xde}, - {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, - {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, - - {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, - {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, - {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, - {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, - - {SENSOR, 0xcd, 0x00, 0x0e}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, - {SENSOR, 0xd0, 0x00, 0x40}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, - {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {SENSOR, 0x33, 0x03, 0x49}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - - {SENSOR, 0x33, 0x03, 0x49}, - {SENSOR, 0x34, 0xc0, 0x19}, - {SENSOR, 0x3f, 0x20, 0x20}, - {SENSOR, 0x40, 0x20, 0x20}, - {SENSOR, 0x5a, 0xc0, 0x0a}, - {SENSOR, 0x70, 0x7b, 0x0a}, - {SENSOR, 0x71, 0xff, 0x00}, - {SENSOR, 0x72, 0x19, 0x0e}, - {SENSOR, 0x73, 0x18, 0x0f}, - {SENSOR, 0x74, 0x57, 0x32}, - {SENSOR, 0x75, 0x56, 0x34}, - {SENSOR, 0x76, 0x73, 0x35}, - {SENSOR, 0x77, 0x30, 0x12}, - {SENSOR, 0x78, 0x79, 0x02}, - {SENSOR, 0x79, 0x75, 0x06}, - {SENSOR, 0x7a, 0x77, 0x0a}, - {SENSOR, 0x7b, 0x78, 0x09}, - {SENSOR, 0x7c, 0x7d, 0x06}, - {SENSOR, 0x7d, 0x31, 0x10}, - {SENSOR, 0x7e, 0x00, 0x7e}, - {SENSOR, 0x80, 0x59, 0x04}, - {SENSOR, 0x81, 0x59, 0x04}, - {SENSOR, 0x82, 0x57, 0x0a}, - {SENSOR, 0x83, 0x58, 0x0b}, - {SENSOR, 0x84, 0x47, 0x0c}, - {SENSOR, 0x85, 0x48, 0x0e}, - {SENSOR, 0x86, 0x5b, 0x02}, - {SENSOR, 0x87, 0x00, 0x5c}, - {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, - {SENSOR, 0x60, 0x00, 0x80}, - {SENSOR, 0x61, 0x00, 0x00}, - {SENSOR, 0x62, 0x00, 0x00}, - {SENSOR, 0x63, 0x00, 0x00}, - {SENSOR, 0x64, 0x00, 0x00}, - - {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, - {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, - {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, - {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, - {SENSOR, 0x30, 0x04, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, - {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, - {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, - {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, - {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, - {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, - - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, - {SENSOR, 0xcd, 0x00, 0x0e}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, - {SENSOR, 0xd0, 0x00, 0x40}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, - {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {SENSOR, 0x33, 0x03, 0x49}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - - {SENSOR, 0x33, 0x03, 0x49}, - {SENSOR, 0x34, 0xc0, 0x19}, - {SENSOR, 0x3f, 0x20, 0x20}, - {SENSOR, 0x40, 0x20, 0x20}, - {SENSOR, 0x5a, 0xc0, 0x0a}, - {SENSOR, 0x70, 0x7b, 0x0a}, - {SENSOR, 0x71, 0xff, 0x00}, - {SENSOR, 0x72, 0x19, 0x0e}, - {SENSOR, 0x73, 0x18, 0x0f}, - {SENSOR, 0x74, 0x57, 0x32}, - {SENSOR, 0x75, 0x56, 0x34}, - {SENSOR, 0x76, 0x73, 0x35}, - {SENSOR, 0x77, 0x30, 0x12}, - {SENSOR, 0x78, 0x79, 0x02}, - {SENSOR, 0x79, 0x75, 0x06}, - {SENSOR, 0x7a, 0x77, 0x0a}, - {SENSOR, 0x7b, 0x78, 0x09}, - {SENSOR, 0x7c, 0x7d, 0x06}, - {SENSOR, 0x7d, 0x31, 0x10}, - {SENSOR, 0x7e, 0x00, 0x7e}, - {SENSOR, 0x80, 0x59, 0x04}, - {SENSOR, 0x81, 0x59, 0x04}, - {SENSOR, 0x82, 0x57, 0x0a}, - {SENSOR, 0x83, 0x58, 0x0b}, - {SENSOR, 0x84, 0x47, 0x0c}, - {SENSOR, 0x85, 0x48, 0x0e}, - {SENSOR, 0x86, 0x5b, 0x02}, - {SENSOR, 0x87, 0x00, 0x5c}, - {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, - {SENSOR, 0x60, 0x00, 0x80}, - {SENSOR, 0x61, 0x00, 0x00}, - {SENSOR, 0x62, 0x00, 0x00}, - {SENSOR, 0x63, 0x00, 0x00}, - {SENSOR, 0x64, 0x00, 0x00}, - - {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, - {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, - {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, - {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, - {SENSOR, 0x30, 0x04, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, - {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, - {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, - {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, - {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, - {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, - - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, - {SENSOR, 0xcd, 0x00, 0x0e}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, - {SENSOR, 0xd0, 0x00, 0x40}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, - {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {SENSOR, 0x33, 0x03, 0x49}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - - {SENSOR, 0x33, 0x03, 0x49}, - {SENSOR, 0x34, 0xc0, 0x19}, - {SENSOR, 0x3f, 0x20, 0x20}, - {SENSOR, 0x40, 0x20, 0x20}, - {SENSOR, 0x5a, 0xc0, 0x0a}, - {SENSOR, 0x70, 0x7b, 0x0a}, - {SENSOR, 0x71, 0xff, 0x00}, - {SENSOR, 0x72, 0x19, 0x0e}, - {SENSOR, 0x73, 0x18, 0x0f}, - {SENSOR, 0x74, 0x57, 0x32}, - {SENSOR, 0x75, 0x56, 0x34}, - {SENSOR, 0x76, 0x73, 0x35}, - {SENSOR, 0x77, 0x30, 0x12}, - {SENSOR, 0x78, 0x79, 0x02}, - {SENSOR, 0x79, 0x75, 0x06}, - {SENSOR, 0x7a, 0x77, 0x0a}, - {SENSOR, 0x7b, 0x78, 0x09}, - {SENSOR, 0x7c, 0x7d, 0x06}, - {SENSOR, 0x7d, 0x31, 0x10}, - {SENSOR, 0x7e, 0x00, 0x7e}, - {SENSOR, 0x80, 0x59, 0x04}, - {SENSOR, 0x81, 0x59, 0x04}, - {SENSOR, 0x82, 0x57, 0x0a}, - {SENSOR, 0x83, 0x58, 0x0b}, - {SENSOR, 0x84, 0x47, 0x0c}, - {SENSOR, 0x85, 0x48, 0x0e}, - {SENSOR, 0x86, 0x5b, 0x02}, - {SENSOR, 0x87, 0x00, 0x5c}, - {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, - {SENSOR, 0x60, 0x00, 0x80}, - {SENSOR, 0x61, 0x00, 0x00}, - {SENSOR, 0x62, 0x00, 0x00}, - {SENSOR, 0x63, 0x00, 0x00}, - {SENSOR, 0x64, 0x00, 0x00}, - - {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, - {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, - {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, - {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, - {SENSOR, 0x30, 0x04, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, - {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, - {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, - {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, - {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, - - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, 0xcd, 0x00, 0x0e}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, 0xd0, 0x00, 0x40}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, - {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, 0x33, 0x03, 0x49}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - - {SENSOR, 0x33, 0x03, 0x49}, - {SENSOR, 0x34, 0xc0, 0x19}, - {SENSOR, 0x3f, 0x20, 0x20}, - {SENSOR, 0x40, 0x20, 0x20}, - {SENSOR, 0x5a, 0xc0, 0x0a}, - {SENSOR, 0x70, 0x7b, 0x0a}, - {SENSOR, 0x71, 0xff, 0x00}, - {SENSOR, 0x72, 0x19, 0x0e}, - {SENSOR, 0x73, 0x18, 0x0f}, - {SENSOR, 0x74, 0x57, 0x32}, - {SENSOR, 0x75, 0x56, 0x34}, - {SENSOR, 0x76, 0x73, 0x35}, - {SENSOR, 0x77, 0x30, 0x12}, - {SENSOR, 0x78, 0x79, 0x02}, - {SENSOR, 0x79, 0x75, 0x06}, - {SENSOR, 0x7a, 0x77, 0x0a}, - {SENSOR, 0x7b, 0x78, 0x09}, - {SENSOR, 0x7c, 0x7d, 0x06}, - {SENSOR, 0x7d, 0x31, 0x10}, - {SENSOR, 0x7e, 0x00, 0x7e}, - {SENSOR, 0x80, 0x59, 0x04}, - {SENSOR, 0x81, 0x59, 0x04}, - {SENSOR, 0x82, 0x57, 0x0a}, - {SENSOR, 0x83, 0x58, 0x0b}, - {SENSOR, 0x84, 0x47, 0x0c}, - {SENSOR, 0x85, 0x48, 0x0e}, - {SENSOR, 0x86, 0x5b, 0x02}, - {SENSOR, 0x87, 0x00, 0x5c}, - {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, - {SENSOR, 0x60, 0x00, 0x80}, - {SENSOR, 0x61, 0x00, 0x00}, - {SENSOR, 0x62, 0x00, 0x00}, - {SENSOR, 0x63, 0x00, 0x00}, - {SENSOR, 0x64, 0x00, 0x00}, - {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, - {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, - {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, - {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, - {SENSOR, 0x30, 0x04, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, - {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, - {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, - {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, - {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, - {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, - {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, - {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, - - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, 0xcd, 0x00, 0x0e}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, 0xd0, 0x00, 0x40}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, - {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - {SENSOR, 0x33, 0x03, 0x49}, - {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, - {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, - {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, - - {SENSOR, 0x33, 0x03, 0x49}, - {SENSOR, 0x34, 0xc0, 0x19}, - {SENSOR, 0x3f, 0x20, 0x20}, - {SENSOR, 0x40, 0x20, 0x20}, - {SENSOR, 0x5a, 0xc0, 0x0a}, - {SENSOR, 0x70, 0x7b, 0x0a}, - {SENSOR, 0x71, 0xff, 0x00}, - {SENSOR, 0x72, 0x19, 0x0e}, - {SENSOR, 0x73, 0x18, 0x0f}, - {SENSOR, 0x74, 0x57, 0x32}, - {SENSOR, 0x75, 0x56, 0x34}, - {SENSOR, 0x76, 0x73, 0x35}, - {SENSOR, 0x77, 0x30, 0x12}, - {SENSOR, 0x78, 0x79, 0x02}, - {SENSOR, 0x79, 0x75, 0x06}, - {SENSOR, 0x7a, 0x77, 0x0a}, - {SENSOR, 0x7b, 0x78, 0x09}, - {SENSOR, 0x7c, 0x7d, 0x06}, - {SENSOR, 0x7d, 0x31, 0x10}, - {SENSOR, 0x7e, 0x00, 0x7e}, - {SENSOR, 0x80, 0x59, 0x04}, - {SENSOR, 0x81, 0x59, 0x04}, - {SENSOR, 0x82, 0x57, 0x0a}, - {SENSOR, 0x83, 0x58, 0x0b}, - {SENSOR, 0x84, 0x47, 0x0c}, - {SENSOR, 0x85, 0x48, 0x0e}, - {SENSOR, 0x86, 0x5b, 0x02}, - {SENSOR, 0x87, 0x00, 0x5c}, - {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, - {SENSOR, 0x60, 0x00, 0x80}, - {SENSOR, 0x61, 0x00, 0x00}, - {SENSOR, 0x62, 0x00, 0x00}, - {SENSOR, 0x63, 0x00, 0x00}, - {SENSOR, 0x64, 0x00, 0x00}, - - {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, - {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, - {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, - {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, - {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, - {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, - {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, - {SENSOR, 0x30, 0x04, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, - /* Set number of blank rows chosen to 400 */ - {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, - /* Set the global gain to 283 (of 512) */ - {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63} -}; - -#endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c deleted file mode 100644 index 31c5896250e7..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Driver for the ov9650 sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include "m5602_ov9650.h" - -int ov9650_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - - /* The ov9650 registers have a max depth of one byte */ - if (len > 1 || !len) - return -EINVAL; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - - m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, - ov9650.i2c_slave_id); - m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); - m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); - m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); - - for (i = 0; i < len; i++) { - err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - - PDEBUG(DBG_TRACE, "Reading sensor register " - "0x%x containing 0x%x ", address, *i2c_data); - } - return (err < 0) ? err : 0; -} - -int ov9650_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - u8 *p; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* The ov9650 only supports one byte writes */ - if (len > 1 || !len) - return -EINVAL; - - memcpy(buf, sensor_urb_skeleton, - sizeof(sensor_urb_skeleton)); - - buf[11] = sd->sensor->i2c_slave_id; - buf[15] = address; - - /* Special case larger sensor writes */ - p = buf + 16; - - /* Copy a four byte write sequence for each byte to be written to */ - for (i = 0; i < len; i++) { - memcpy(p, sensor_urb_skeleton + 16, 4); - p[3] = i2c_data[i]; - p += 4; - PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", - address, i2c_data[i]); - } - - /* Copy the tailer */ - memcpy(p, sensor_urb_skeleton + 20, 4); - - /* Set the total length */ - p[3] = 0x10 + len; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 20 + len * 4, M5602_URB_MSG_TIMEOUT); - - return (err < 0) ? err : 0; -} - -int ov9650_probe(struct sd *sd) -{ - u8 prod_id = 0, ver_id = 0, i; - - if (force_sensor) { - if (force_sensor == OV9650_SENSOR) { - info("Forcing an %s sensor", ov9650.name); - goto sensor_found; - } - /* If we want to force another sensor, - don't try to probe this one */ - return -ENODEV; - } - - info("Probing for an ov9650 sensor"); - - /* Run the pre-init to actually probe the unit */ - for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) { - u8 data = preinit_ov9650[i][2]; - if (preinit_ov9650[i][0] == SENSOR) - ov9650_write_sensor(sd, - preinit_ov9650[i][1], &data, 1); - else - m5602_write_bridge(sd, preinit_ov9650[i][1], data); - } - - if (ov9650_read_sensor(sd, OV9650_PID, &prod_id, 1)) - return -ENODEV; - - if (ov9650_read_sensor(sd, OV9650_VER, &ver_id, 1)) - return -ENODEV; - - if ((prod_id == 0x96) && (ver_id == 0x52)) { - info("Detected an ov9650 sensor"); - goto sensor_found; - } - - return -ENODEV; - -sensor_found: - sd->gspca_dev.cam.cam_mode = ov9650.modes; - sd->gspca_dev.cam.nmodes = ov9650.nmodes; - sd->desc->ctrls = ov9650.ctrls; - sd->desc->nctrls = ov9650.nctrls; - return 0; -} - -int ov9650_init(struct sd *sd) -{ - int i, err = 0; - u8 data; - - if (dump_sensor) - ov9650_dump_registers(sd); - - for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { - data = init_ov9650[i][2]; - if (init_ov9650[i][0] == SENSOR) - err = ov9650_write_sensor(sd, init_ov9650[i][1], - &data, 1); - else - err = m5602_write_bridge(sd, init_ov9650[i][1], data); - } - - if (!err && dmi_check_system(ov9650_flip_dmi_table)) { - info("vflip quirk active"); - data = 0x30; - err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1); - } - - return (err < 0) ? err : 0; -} - -int ov9650_power_down(struct sd *sd) -{ - int i; - for (i = 0; i < ARRAY_SIZE(power_down_ov9650); i++) { - u8 data = power_down_ov9650[i][2]; - if (power_down_ov9650[i][0] == SENSOR) - ov9650_write_sensor(sd, - power_down_ov9650[i][1], &data, 1); - else - m5602_write_bridge(sd, power_down_ov9650[i][1], data); - } - - return 0; -} - -int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = ov9650_read_sensor(sd, OV9650_COM1, &i2c_data, 1); - if (err < 0) - goto out; - *val = i2c_data & 0x03; - - err = ov9650_read_sensor(sd, OV9650_AECH, &i2c_data, 1); - if (err < 0) - goto out; - *val |= (i2c_data << 2); - - err = ov9650_read_sensor(sd, OV9650_AECHM, &i2c_data, 1); - if (err < 0) - goto out; - *val |= (i2c_data & 0x3f) << 10; - - PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val); -out: - return (err < 0) ? err : 0; -} - -int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - PDEBUG(DBG_V4L2_CID, "Set exposure to %d", - val & 0xffff); - - /* The 6 MSBs */ - i2c_data = (val >> 10) & 0x3f; - err = ov9650_write_sensor(sd, OV9650_AECHM, - &i2c_data, 1); - if (err < 0) - goto out; - - /* The 8 middle bits */ - i2c_data = (val >> 2) & 0xff; - err = ov9650_write_sensor(sd, OV9650_AECH, - &i2c_data, 1); - if (err < 0) - goto out; - - /* The 2 LSBs */ - i2c_data = val & 0x03; - err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1); - -out: - return (err < 0) ? err : 0; -} - -int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); - *val = (i2c_data & 0x03) << 8; - - err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); - *val |= i2c_data; - PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); - return (err < 0) ? err : 0; -} - -int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - /* The 2 MSB */ - /* Read the OV9650_VREF register first to avoid - corrupting the VREF high and low bits */ - ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); - /* Mask away all uninteresting bits */ - i2c_data = ((val & 0x0300) >> 2) | - (i2c_data & 0x3F); - err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); - - /* The 8 LSBs */ - i2c_data = val & 0xff; - err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); - return (err < 0) ? err : 0; -} - -int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); - *val = i2c_data; - - PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val); - - return (err < 0) ? err : 0; -} - -int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set red gain to %d", - val & 0xff); - - i2c_data = val & 0xff; - err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1); - - return (err < 0) ? err : 0; -} - -int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); - *val = i2c_data; - - PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val); - - return (err < 0) ? err : 0; -} - -int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set blue gain to %d", - val & 0xff); - - i2c_data = val & 0xff; - err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); - - return (err < 0) ? err : 0; -} - -int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); - if (dmi_check_system(ov9650_flip_dmi_table)) - *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; - else - *val = (i2c_data & OV9650_HFLIP) >> 5; - PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); - - return (err < 0) ? err : 0; -} - -int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val); - err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); - if (err < 0) - goto out; - - if (dmi_check_system(ov9650_flip_dmi_table)) - i2c_data = ((i2c_data & 0xdf) | - (((val ? 0 : 1) & 0x01) << 5)); - else - i2c_data = ((i2c_data & 0xdf) | - ((val & 0x01) << 5)); - - err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); -out: - return (err < 0) ? err : 0; -} - -int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); - if (dmi_check_system(ov9650_flip_dmi_table)) - *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; - else - *val = (i2c_data & 0x10) >> 4; - PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); - - return (err < 0) ? err : 0; -} - -int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); - err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); - if (err < 0) - goto out; - - if (dmi_check_system(ov9650_flip_dmi_table)) - i2c_data = ((i2c_data & 0xef) | - (((val ? 0 : 1) & 0x01) << 4)); - else - i2c_data = ((i2c_data & 0xef) | - ((val & 0x01) << 4)); - - err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); -out: - return (err < 0) ? err : 0; -} - -int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); - if (err < 0) - goto out; - *val = (i2c_data & 0x03) << 8; - - err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); - *val |= i2c_data; - PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); -out: - return (err < 0) ? err : 0; -} - -int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff); - - /* Read the OV9650_VREF register first to avoid - corrupting the VREF high and low bits */ - err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); - if (err < 0) - goto out; - - /* Mask away all uninteresting bits */ - i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); - err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); - if (err < 0) - goto out; - - /* The 8 LSBs */ - i2c_data = val & 0xff; - err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); - -out: - return (err < 0) ? err : 0; -} - -int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - *val = (i2c_data & OV9650_AWB_EN) >> 1; - PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val); - - return (err < 0) ? err : 0; -} - -int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val); - err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - if (err < 0) - goto out; - - i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); - err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); -out: - return (err < 0) ? err : 0; -} - -int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - *val = (i2c_data & OV9650_AGC_EN) >> 2; - PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val); - - return (err < 0) ? err : 0; -} - -int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 i2c_data; - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val); - err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); - if (err < 0) - goto out; - - i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); - err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); -out: - return (err < 0) ? err : 0; -} - -void ov9650_dump_registers(struct sd *sd) -{ - int address; - info("Dumping the ov9650 register state"); - for (address = 0; address < 0xa9; address++) { - u8 value; - ov9650_read_sensor(sd, address, &value, 1); - info("register 0x%x contains 0x%x", - address, value); - } - - info("ov9650 register state dump complete"); - - info("Probing for which registers that are read/write"); - for (address = 0; address < 0xff; address++) { - u8 old_value, ctrl_value; - u8 test_value[2] = {0xff, 0xff}; - - ov9650_read_sensor(sd, address, &old_value, 1); - ov9650_write_sensor(sd, address, test_value, 1); - ov9650_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value[0]) - info("register 0x%x is writeable", address); - else - info("register 0x%x is read only", address); - - /* Restore original value */ - ov9650_write_sensor(sd, address, &old_value, 1); - } -} diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h deleted file mode 100644 index 2f29cb056f30..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Driver for the ov9650 sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_OV9650_H_ -#define M5602_OV9650_H_ - -#include - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define OV9650_GAIN 0x00 -#define OV9650_BLUE 0x01 -#define OV9650_RED 0x02 -#define OV9650_VREF 0x03 -#define OV9650_COM1 0x04 -#define OV9650_BAVE 0x05 -#define OV9650_GEAVE 0x06 -#define OV9650_RSVD7 0x07 -#define OV9650_PID 0x0a -#define OV9650_VER 0x0b -#define OV9650_COM3 0x0c -#define OV9650_COM5 0x0e -#define OV9650_COM6 0x0f -#define OV9650_AECH 0x10 -#define OV9650_CLKRC 0x11 -#define OV9650_COM7 0x12 -#define OV9650_COM8 0x13 -#define OV9650_COM9 0x14 -#define OV9650_COM10 0x15 -#define OV9650_RSVD16 0x16 -#define OV9650_HSTART 0x17 -#define OV9650_HSTOP 0x18 -#define OV9650_VSTRT 0x19 -#define OV9650_VSTOP 0x1a -#define OV9650_PSHFT 0x1b -#define OV9650_MVFP 0x1e -#define OV9650_AEW 0x24 -#define OV9650_AEB 0x25 -#define OV9650_VPT 0x26 -#define OV9650_BBIAS 0x27 -#define OV9650_GbBIAS 0x28 -#define OV9650_Gr_COM 0x29 -#define OV9650_RBIAS 0x2c -#define OV9650_HREF 0x32 -#define OV9650_CHLF 0x33 -#define OV9650_ARBLM 0x34 -#define OV9650_RSVD35 0x35 -#define OV9650_RSVD36 0x36 -#define OV9650_ADC 0x37 -#define OV9650_ACOM38 0x38 -#define OV9650_OFON 0x39 -#define OV9650_TSLB 0x3a -#define OV9650_COM12 0x3c -#define OV9650_COM13 0x3d -#define OV9650_COM15 0x40 -#define OV9650_COM16 0x41 -#define OV9650_LCC1 0x62 -#define OV9650_LCC2 0x63 -#define OV9650_LCC3 0x64 -#define OV9650_LCC4 0x65 -#define OV9650_LCC5 0x66 -#define OV9650_HV 0x69 -#define OV9650_DBLV 0x6b -#define OV9650_COM21 0x8b -#define OV9650_COM22 0x8c -#define OV9650_COM24 0x8e -#define OV9650_DBLC1 0x8f -#define OV9650_RSVD94 0x94 -#define OV9650_RSVD95 0x95 -#define OV9650_RSVD96 0x96 -#define OV9650_LCCFB 0x9d -#define OV9650_LCCFR 0x9e -#define OV9650_AECHM 0xa1 -#define OV9650_COM26 0xa5 -#define OV9650_ACOMA8 0xa8 -#define OV9650_ACOMA9 0xa9 - -#define OV9650_REGISTER_RESET (1 << 7) -#define OV9650_VGA_SELECT (1 << 6) -#define OV9650_RGB_SELECT (1 << 2) -#define OV9650_RAW_RGB_SELECT (1 << 0) - -#define OV9650_FAST_AGC_AEC (1 << 7) -#define OV9650_AEC_UNLIM_STEP_SIZE (1 << 6) -#define OV9650_BANDING (1 << 5) -#define OV9650_AGC_EN (1 << 2) -#define OV9650_AWB_EN (1 << 1) -#define OV9650_AEC_EN (1 << 0) - -#define OV9650_VARIOPIXEL (1 << 2) -#define OV9650_SYSTEM_CLK_SEL (1 << 7) -#define OV9650_SLAM_MODE (1 << 4) - -#define OV9650_VFLIP (1 << 4) -#define OV9650_HFLIP (1 << 5) - -#define GAIN_DEFAULT 0x14 -#define RED_GAIN_DEFAULT 0x70 -#define BLUE_GAIN_DEFAULT 0x20 -#define EXPOSURE_DEFAULT 0x5003 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern int dump_sensor; -extern unsigned int m5602_debug; - -int ov9650_probe(struct sd *sd); -int ov9650_init(struct sd *sd); -int ov9650_power_down(struct sd *sd); - -int ov9650_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); -int ov9650_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -void ov9650_dump_registers(struct sd *sd); - -int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val); -int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); -int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); - -static struct m5602_sensor ov9650 = { - .name = "OV9650", - .i2c_slave_id = 0x60, - .probe = ov9650_probe, - .init = ov9650_init, - .power_down = ov9650_power_down, - .read_sensor = ov9650_read_sensor, - .write_sensor = ov9650_write_sensor, - - .nctrls = 8, - .ctrls = { - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0xffff, - .step = 0x1, - .default_value = EXPOSURE_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_exposure, - .get = ov9650_get_exposure - }, { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0x3ff, - .step = 0x1, - .default_value = GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_gain, - .get = ov9650_get_gain - }, { - { - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_red_balance, - .get = ov9650_get_red_balance - }, { - { - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = ov9650_set_blue_balance, - .get = ov9650_get_blue_balance - }, { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_hflip, - .get = ov9650_get_hflip - }, { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_vflip, - .get = ov9650_get_vflip - }, { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto white balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_auto_white_balance, - .get = ov9650_get_auto_white_balance - }, { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "auto gain control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = ov9650_set_auto_gain, - .get = ov9650_get_auto_gain - } - }, - - .nmodes = 1, - .modes = { - { - M5602_DEFAULT_FRAME_WIDTH, - M5602_DEFAULT_FRAME_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, - .bytesperline = M5602_DEFAULT_FRAME_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } -}; - -static const unsigned char preinit_ov9650[][3] = -{ - /* [INITCAM] */ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, - /* Reset chip */ - {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, - /* Enable double clock */ - {SENSOR, OV9650_CLKRC, 0x80}, - /* Do something out of spec with the power */ - {SENSOR, OV9650_OFON, 0x40} -}; - -static const unsigned char init_ov9650[][3] = -{ - /* [INITCAM] */ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, - /* Reset chip */ - {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, - /* Enable double clock */ - {SENSOR, OV9650_CLKRC, 0x80}, - /* Do something out of spec with the power */ - {SENSOR, OV9650_OFON, 0x40}, - - /* Set QQVGA */ - {SENSOR, OV9650_COM1, 0x20}, - /* Set fast AGC/AEC algorithm with unlimited step size */ - {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | - OV9650_AEC_UNLIM_STEP_SIZE | - OV9650_AWB_EN | OV9650_AGC_EN}, - - {SENSOR, OV9650_CHLF, 0x10}, - {SENSOR, OV9650_ARBLM, 0xbf}, - {SENSOR, OV9650_ACOM38, 0x81}, - /* Turn off color matrix coefficient double option */ - {SENSOR, OV9650_COM16, 0x00}, - /* Enable color matrix for RGB/YUV, Delay Y channel, - set output Y/UV delay to 1 */ - {SENSOR, OV9650_COM13, 0x19}, - /* Enable digital BLC, Set output mode to U Y V Y */ - {SENSOR, OV9650_TSLB, 0x0c}, - /* Limit the AGC/AEC stable upper region */ - {SENSOR, OV9650_COM24, 0x00}, - /* Enable HREF and some out of spec things */ - {SENSOR, OV9650_COM12, 0x73}, - /* Set all DBLC offset signs to positive and - do some out of spec stuff */ - {SENSOR, OV9650_DBLC1, 0xdf}, - {SENSOR, OV9650_COM21, 0x06}, - {SENSOR, OV9650_RSVD35, 0x91}, - /* Necessary, no camera stream without it */ - {SENSOR, OV9650_RSVD16, 0x06}, - {SENSOR, OV9650_RSVD94, 0x99}, - {SENSOR, OV9650_RSVD95, 0x99}, - {SENSOR, OV9650_RSVD96, 0x04}, - /* Enable full range output */ - {SENSOR, OV9650_COM15, 0x0}, - /* Enable HREF at optical black, enable ADBLC bias, - enable ADBLC, reset timings at format change */ - {SENSOR, OV9650_COM6, 0x4b}, - /* Subtract 32 from the B channel bias */ - {SENSOR, OV9650_BBIAS, 0xa0}, - /* Subtract 32 from the Gb channel bias */ - {SENSOR, OV9650_GbBIAS, 0xa0}, - /* Do not bypass the analog BLC and to some out of spec stuff */ - {SENSOR, OV9650_Gr_COM, 0x00}, - /* Subtract 32 from the R channel bias */ - {SENSOR, OV9650_RBIAS, 0xa0}, - /* Subtract 32 from the R channel bias */ - {SENSOR, OV9650_RBIAS, 0x0}, - {SENSOR, OV9650_COM26, 0x80}, - {SENSOR, OV9650_ACOMA9, 0x98}, - /* Set the AGC/AEC stable region upper limit */ - {SENSOR, OV9650_AEW, 0x68}, - /* Set the AGC/AEC stable region lower limit */ - {SENSOR, OV9650_AEB, 0x5c}, - /* Set the high and low limit nibbles to 3 */ - {SENSOR, OV9650_VPT, 0xc3}, - /* Set the Automatic Gain Ceiling (AGC) to 128x, - drop VSYNC at frame drop, - limit exposure timing, - drop frame when the AEC step is larger than the exposure gap */ - {SENSOR, OV9650_COM9, 0x6e}, - /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync) - and set PWDN to SLVS (slave mode vertical sync) */ - {SENSOR, OV9650_COM10, 0x42}, - /* Set horizontal column start high to default value */ - {SENSOR, OV9650_HSTART, 0x1a}, - /* Set horizontal column end */ - {SENSOR, OV9650_HSTOP, 0xbf}, - /* Complementing register to the two writes above */ - {SENSOR, OV9650_HREF, 0xb2}, - /* Set vertical row start high bits */ - {SENSOR, OV9650_VSTRT, 0x02}, - /* Set vertical row end low bits */ - {SENSOR, OV9650_VSTOP, 0x7e}, - /* Set complementing vertical frame control */ - {SENSOR, OV9650_VREF, 0x10}, - /* Set raw RGB output format with VGA resolution */ - {SENSOR, OV9650_COM7, OV9650_VGA_SELECT | - OV9650_RGB_SELECT | - OV9650_RAW_RGB_SELECT}, - {SENSOR, OV9650_ADC, 0x04}, - {SENSOR, OV9650_HV, 0x40}, - /* Enable denoise, and white-pixel erase */ - {SENSOR, OV9650_COM22, 0x23}, - - /* Set the high bits of the exposure value */ - {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)}, - - /* Set the low bits of the exposure value */ - {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)}, - {SENSOR, OV9650_GAIN, GAIN_DEFAULT}, - {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT}, - {SENSOR, OV9650_RED, RED_GAIN_DEFAULT}, - - {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, - {SENSOR, OV9650_COM5, OV9650_SYSTEM_CLK_SEL}, - - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, - {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x09}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x5e}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0xde} -}; - -static const unsigned char power_down_ov9650[][3] = -{ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {SENSOR, OV9650_COM7, 0x80}, - {SENSOR, OV9650_OFON, 0xf4}, - {SENSOR, OV9650_MVFP, 0x80}, - {SENSOR, OV9650_DBLV, 0x3f}, - {SENSOR, OV9650_RSVD36, 0x49}, - {SENSOR, OV9650_COM7, 0x05}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} -}; - -/* Vertically and horizontally flips the image if matched, needed for machines - where the sensor is mounted upside down */ -static - const - struct dmi_system_id ov9650_flip_dmi_table[] = { - { - .ident = "ASUS A6VC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") - } - }, - { - .ident = "ASUS A6VM", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") - } - }, - { - .ident = "ASUS A6JC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") - } - }, - { - .ident = "ASUS A6Kt", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") - } - }, - { } -}; - -#endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c b/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c deleted file mode 100644 index 08c015bde115..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Driver for the po1030 sensor - * - * Copyright (c) 2008 Erik Andren - * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (c) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include "m5602_po1030.h" - -int po1030_probe(struct sd *sd) -{ - u8 prod_id = 0, ver_id = 0, i; - - if (force_sensor) { - if (force_sensor == PO1030_SENSOR) { - info("Forcing a %s sensor", po1030.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - info("Probing for a po1030 sensor"); - - /* Run the pre-init to actually probe the unit */ - for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { - u8 data = preinit_po1030[i][2]; - if (preinit_po1030[i][0] == SENSOR) - po1030_write_sensor(sd, - preinit_po1030[i][1], &data, 1); - else - m5602_write_bridge(sd, preinit_po1030[i][1], data); - } - - if (po1030_read_sensor(sd, 0x3, &prod_id, 1)) - return -ENODEV; - - if (po1030_read_sensor(sd, 0x4, &ver_id, 1)) - return -ENODEV; - - if ((prod_id == 0x02) && (ver_id == 0xef)) { - info("Detected a po1030 sensor"); - goto sensor_found; - } - return -ENODEV; - -sensor_found: - sd->gspca_dev.cam.cam_mode = po1030.modes; - sd->gspca_dev.cam.nmodes = po1030.nmodes; - sd->desc->ctrls = po1030.ctrls; - sd->desc->nctrls = po1030.nctrls; - return 0; -} - -int po1030_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - - m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, - sd->sensor->i2c_slave_id); - m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); - m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); - m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); - - for (i = 0; i < len; i++) { - err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - - PDEBUG(DBG_TRACE, "Reading sensor register " - "0x%x containing 0x%x ", address, *i2c_data); - } - return (err < 0) ? err : 0; -} - -int po1030_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - u8 *p; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* The po1030 only supports one byte writes */ - if (len > 1 || !len) - return -EINVAL; - - memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton)); - - buf[11] = sd->sensor->i2c_slave_id; - buf[15] = address; - - p = buf + 16; - - /* Copy a four byte write sequence for each byte to be written to */ - for (i = 0; i < len; i++) { - memcpy(p, sensor_urb_skeleton + 16, 4); - p[3] = i2c_data[i]; - p += 4; - PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", - address, i2c_data[i]); - } - - /* Copy the footer */ - memcpy(p, sensor_urb_skeleton + 20, 4); - - /* Set the total length */ - p[3] = 0x10 + len; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 20 + len * 4, M5602_URB_MSG_TIMEOUT); - - return (err < 0) ? err : 0; -} - -int po1030_init(struct sd *sd) -{ - int i, err = 0; - - /* Init the sensor */ - for (i = 0; i < ARRAY_SIZE(init_po1030); i++) { - u8 data[2] = {0x00, 0x00}; - - switch (init_po1030[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - init_po1030[i][1], - init_po1030[i][2]); - break; - - case SENSOR: - data[0] = init_po1030[i][2]; - err = po1030_write_sensor(sd, - init_po1030[i][1], data, 1); - break; - - case SENSOR_LONG: - data[0] = init_po1030[i][2]; - data[1] = init_po1030[i][3]; - err = po1030_write_sensor(sd, - init_po1030[i][1], data, 2); - break; - default: - info("Invalid stream command, exiting init"); - return -EINVAL; - } - } - - if (dump_sensor) - po1030_dump_registers(sd); - - return (err < 0) ? err : 0; -} - -int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H, - &i2c_data, 1); - if (err < 0) - goto out; - *val = (i2c_data << 8); - - err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M, - &i2c_data, 1); - *val |= i2c_data; - - PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val); -out: - return (err < 0) ? err : 0; -} - -int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff); - - i2c_data = ((val & 0xff00) >> 8); - PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x", - i2c_data); - - err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, - &i2c_data, 1); - if (err < 0) - goto out; - - i2c_data = (val & 0xff); - PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x", - i2c_data); - err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, - &i2c_data, 1); - -out: - return (err < 0) ? err : 0; -} - -int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, - &i2c_data, 1); - *val = i2c_data; - PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val); - - return (err < 0) ? err : 0; -} - -int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - i2c_data = val & 0xff; - PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data); - err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, - &i2c_data, 1); - return (err < 0) ? err : 0; -} - -int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, - &i2c_data, 1); - *val = i2c_data; - PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val); - return (err < 0) ? err : 0; -} - -int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - i2c_data = val & 0xff; - PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data); - err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, - &i2c_data, 1); - return (err < 0) ? err : 0; -} - -int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - - err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, - &i2c_data, 1); - *val = i2c_data; - PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val); - - return (err < 0) ? err : 0; -} - -int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 i2c_data; - int err; - i2c_data = val & 0xff; - PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data); - err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, - &i2c_data, 1); - - return (err < 0) ? err : 0; -} - -int po1030_power_down(struct sd *sd) -{ - return 0; -} - -void po1030_dump_registers(struct sd *sd) -{ - int address; - u8 value = 0; - - info("Dumping the po1030 sensor core registers"); - for (address = 0; address < 0x7f; address++) { - po1030_read_sensor(sd, address, &value, 1); - info("register 0x%x contains 0x%x", - address, value); - } - - info("po1030 register state dump complete"); - - info("Probing for which registers that are read/write"); - for (address = 0; address < 0xff; address++) { - u8 old_value, ctrl_value; - u8 test_value[2] = {0xff, 0xff}; - - po1030_read_sensor(sd, address, &old_value, 1); - po1030_write_sensor(sd, address, test_value, 1); - po1030_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value[0]) - info("register 0x%x is writeable", address); - else - info("register 0x%x is read only", address); - - /* Restore original value */ - po1030_write_sensor(sd, address, &old_value, 1); - } -} diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h b/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h deleted file mode 100644 index 68f34c97bf44..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_po1030.h +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Driver for the po1030 sensor. - * This is probably a pixel plus sensor but we haven't identified it yet - * - * Copyright (c) 2008 Erik Andren - * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (c) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * Register defines taken from Pascal Stangs Proxycon Armlib - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_PO1030_H_ -#define M5602_PO1030_H_ - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define PO1030_REG_DEVID_H 0x00 -#define PO1030_REG_DEVID_L 0x01 -#define PO1030_REG_FRAMEWIDTH_H 0x04 -#define PO1030_REG_FRAMEWIDTH_L 0x05 -#define PO1030_REG_FRAMEHEIGHT_H 0x06 -#define PO1030_REG_FRAMEHEIGHT_L 0x07 -#define PO1030_REG_WINDOWX_H 0x08 -#define PO1030_REG_WINDOWX_L 0x09 -#define PO1030_REG_WINDOWY_H 0x0a -#define PO1030_REG_WINDOWY_L 0x0b -#define PO1030_REG_WINDOWWIDTH_H 0x0c -#define PO1030_REG_WINDOWWIDTH_L 0x0d -#define PO1030_REG_WINDOWHEIGHT_H 0x0e -#define PO1030_REG_WINDOWHEIGHT_L 0x0f - -#define PO1030_REG_GLOBALIBIAS 0x12 -#define PO1030_REG_PIXELIBIAS 0x13 - -#define PO1030_REG_GLOBALGAIN 0x15 -#define PO1030_REG_RED_GAIN 0x16 -#define PO1030_REG_GREEN_1_GAIN 0x17 -#define PO1030_REG_BLUE_GAIN 0x18 -#define PO1030_REG_GREEN_2_GAIN 0x19 - -#define PO1030_REG_INTEGLINES_H 0x1a -#define PO1030_REG_INTEGLINES_M 0x1b -#define PO1030_REG_INTEGLINES_L 0x1c - -#define PO1030_REG_CONTROL1 0x1d -#define PO1030_REG_CONTROL2 0x1e -#define PO1030_REG_CONTROL3 0x1f -#define PO1030_REG_CONTROL4 0x20 - -#define PO1030_REG_PERIOD50_H 0x23 -#define PO1030_REG_PERIOD50_L 0x24 -#define PO1030_REG_PERIOD60_H 0x25 -#define PO1030_REG_PERIOD60_L 0x26 -#define PO1030_REG_REGCLK167 0x27 -#define PO1030_REG_DELTA50 0x28 -#define PO1030_REG_DELTA60 0x29 - -#define PO1030_REG_ADCOFFSET 0x2c - -/* Gamma Correction Coeffs */ -#define PO1030_REG_GC0 0x2d -#define PO1030_REG_GC1 0x2e -#define PO1030_REG_GC2 0x2f -#define PO1030_REG_GC3 0x30 -#define PO1030_REG_GC4 0x31 -#define PO1030_REG_GC5 0x32 -#define PO1030_REG_GC6 0x33 -#define PO1030_REG_GC7 0x34 - -/* Color Transform Matrix */ -#define PO1030_REG_CT0 0x35 -#define PO1030_REG_CT1 0x36 -#define PO1030_REG_CT2 0x37 -#define PO1030_REG_CT3 0x38 -#define PO1030_REG_CT4 0x39 -#define PO1030_REG_CT5 0x3a -#define PO1030_REG_CT6 0x3b -#define PO1030_REG_CT7 0x3c -#define PO1030_REG_CT8 0x3d - -#define PO1030_REG_AUTOCTRL1 0x3e -#define PO1030_REG_AUTOCTRL2 0x3f - -#define PO1030_REG_YTARGET 0x40 -#define PO1030_REG_GLOBALGAINMIN 0x41 -#define PO1030_REG_GLOBALGAINMAX 0x42 - -/* Output format control */ -#define PO1030_REG_OUTFORMCTRL1 0x5a -#define PO1030_REG_OUTFORMCTRL2 0x5b -#define PO1030_REG_OUTFORMCTRL3 0x5c -#define PO1030_REG_OUTFORMCTRL4 0x5d -#define PO1030_REG_OUTFORMCTRL5 0x5e - -/* Imaging coefficients */ -#define PO1030_REG_YBRIGHT 0x73 -#define PO1030_REG_YCONTRAST 0x74 -#define PO1030_REG_YSATURATION 0x75 - -/*****************************************************************************/ - -#define PO1030_GLOBAL_GAIN_DEFAULT 0x12 -#define PO1030_EXPOSURE_DEFAULT 0xf0ff -#define PO1030_BLUE_GAIN_DEFAULT 0x40 -#define PO1030_RED_GAIN_DEFAULT 0x40 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern int dump_sensor; -extern unsigned int m5602_debug; - -int po1030_probe(struct sd *sd); -int po1030_init(struct sd *sd); -int po1030_power_down(struct sd *sd); - -void po1030_dump_registers(struct sd *sd); - -int po1030_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); -int po1030_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); -int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); -int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); -int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); -int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); - -static struct m5602_sensor po1030 = { - .name = "PO1030", - - .i2c_slave_id = 0xdc, - - .probe = po1030_probe, - .init = po1030_init, - .power_down = po1030_power_down, - - .nctrls = 4, - .ctrls = { - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_GLOBAL_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_gain, - .get = po1030_get_gain - }, { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0xffff, - .step = 0x1, - .default_value = PO1030_EXPOSURE_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_exposure, - .get = po1030_get_exposure - }, { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "red balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_RED_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_red_balance, - .get = po1030_get_red_balance - }, { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "blue balance", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = PO1030_BLUE_GAIN_DEFAULT, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = po1030_set_blue_balance, - .get = po1030_get_blue_balance - } - }, - .nmodes = 1, - .modes = { - { - M5602_DEFAULT_FRAME_WIDTH, - M5602_DEFAULT_FRAME_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, - .bytesperline = M5602_DEFAULT_FRAME_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } -}; - -static const unsigned char preinit_po1030[][3] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - - {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, - {BRIDGE, M5602_XB_SIG_INI, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - - {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00} -}; - -static const unsigned char init_po1030[][4] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, - /*sequence 1*/ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, - - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - /*end of sequence 1*/ - - /*sequence 2 (same as stop sequence)*/ - {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - /*end of sequence 2*/ - - /*sequence 5*/ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, - {BRIDGE, M5602_XB_SIG_INI, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - /*end of sequence 5*/ - - /*sequence 2 stop */ - {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - /*end of sequence 2 stop */ - -/* --------------------------------- - * end of init - begin of start - * --------------------------------- */ - - /*sequence 3*/ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - /*end of sequence 3*/ - /*sequence 4*/ - {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, - - {SENSOR, PO1030_REG_AUTOCTRL2, 0x04}, - - /* Set the width to 751 */ - {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, - {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}, - - /* Set the height to 540 */ - {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02}, - {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c}, - - /* Set the x window to 1 */ - {SENSOR, PO1030_REG_WINDOWX_H, 0x00}, - {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, - - /* Set the y window to 1 */ - {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, - {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, - - {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, - {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, - {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01}, - {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3}, - - {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, - {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, - {SENSOR, PO1030_REG_AUTOCTRL1, 0x08}, - {SENSOR, PO1030_REG_CONTROL2, 0x03}, - {SENSOR, 0x21, 0x90}, - {SENSOR, PO1030_REG_YTARGET, 0x60}, - {SENSOR, 0x59, 0x13}, - {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40}, - {SENSOR, 0x5f, 0x00}, - {SENSOR, 0x60, 0x80}, - {SENSOR, 0x78, 0x14}, - {SENSOR, 0x6f, 0x01}, - {SENSOR, PO1030_REG_CONTROL1, 0x18}, - {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14}, - {SENSOR, 0x63, 0x38}, - {SENSOR, 0x64, 0x38}, - {SENSOR, PO1030_REG_CONTROL1, 0x58}, - {SENSOR, PO1030_REG_RED_GAIN, 0x30}, - {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30}, - {SENSOR, PO1030_REG_BLUE_GAIN, 0x30}, - {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30}, - {SENSOR, PO1030_REG_GC0, 0x10}, - {SENSOR, PO1030_REG_GC1, 0x20}, - {SENSOR, PO1030_REG_GC2, 0x40}, - {SENSOR, PO1030_REG_GC3, 0x60}, - {SENSOR, PO1030_REG_GC4, 0x80}, - {SENSOR, PO1030_REG_GC5, 0xa0}, - {SENSOR, PO1030_REG_GC6, 0xc0}, - {SENSOR, PO1030_REG_GC7, 0xff}, - /*end of sequence 4*/ - /*sequence 5*/ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, - {BRIDGE, M5602_XB_SIG_INI, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e}, - {BRIDGE, M5602_XB_SIG_INI, 0x00}, - /*end of sequence 5*/ - - /*sequence 6*/ - /* Changing 40 in f0 the image becomes green in bayer mode and red in - * rgb mode */ - {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT}, - /* in changing 40 in f0 the image becomes green in bayer mode and red in - * rgb mode */ - {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT}, - - /* with a very low lighted environment increase the exposure but - * decrease the FPS (Frame Per Second) */ - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, - - /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in - * low lighted environment (f0 is more than ff ?)*/ - {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2) - & 0xff)}, - - /* Controls middle exposure, use only in high lighted environment */ - {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff}, - - /* Controls clarity (not sure) */ - {SENSOR, PO1030_REG_INTEGLINES_L, 0x00}, - /* Controls gain (the image is more lighted) */ - {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT}, - - /* Sets the width */ - {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, - {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef} - /*end of sequence 6*/ -}; - -#endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c deleted file mode 100644 index 68202565325d..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Driver for the s5k4aa sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include "m5602_s5k4aa.h" - -int s5k4aa_probe(struct sd *sd) -{ - u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; - int i, err = 0; - - if (force_sensor) { - if (force_sensor == S5K4AA_SENSOR) { - info("Forcing a %s sensor", s5k4aa.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - info("Probing for a s5k4aa sensor"); - - /* Preinit the sensor */ - for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (preinit_s5k4aa[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - preinit_s5k4aa[i][1], - preinit_s5k4aa[i][2]); - break; - - case SENSOR: - data[0] = preinit_s5k4aa[i][2]; - err = s5k4aa_write_sensor(sd, - preinit_s5k4aa[i][1], - data, 1); - break; - - case SENSOR_LONG: - data[0] = preinit_s5k4aa[i][2]; - data[1] = preinit_s5k4aa[i][3]; - err = s5k4aa_write_sensor(sd, - preinit_s5k4aa[i][1], - data, 2); - break; - default: - info("Invalid stream command, exiting init"); - return -EINVAL; - } - } - - /* Test some registers, but we don't know their exact meaning yet */ - if (s5k4aa_read_sensor(sd, 0x00, prod_id, sizeof(prod_id))) - return -ENODEV; - - if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) - return -ENODEV; - else - info("Detected a s5k4aa sensor"); -sensor_found: - sd->gspca_dev.cam.cam_mode = s5k4aa.modes; - sd->gspca_dev.cam.nmodes = s5k4aa.nmodes; - sd->desc->ctrls = s5k4aa.ctrls; - sd->desc->nctrls = s5k4aa.nctrls; - - return 0; -} - -int s5k4aa_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, - sd->sensor->i2c_slave_id); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); - if (err < 0) - goto out; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - if (err < 0) - goto out; - - for (i = 0; (i < len) & !err; i++) { - err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - - PDEBUG(DBG_TRACE, "Reading sensor register " - "0x%x containing 0x%x ", address, *i2c_data); - } -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - u8 *p; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* No sensor with a data width larger than 16 bits has yet been seen */ - if (len > 2 || !len) - return -EINVAL; - - memcpy(buf, sensor_urb_skeleton, - sizeof(sensor_urb_skeleton)); - - buf[11] = sd->sensor->i2c_slave_id; - buf[15] = address; - - /* Special case larger sensor writes */ - p = buf + 16; - - /* Copy a four byte write sequence for each byte to be written to */ - for (i = 0; i < len; i++) { - memcpy(p, sensor_urb_skeleton + 16, 4); - p[3] = i2c_data[i]; - p += 4; - PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", - address, i2c_data[i]); - } - - /* Copy the tailer */ - memcpy(p, sensor_urb_skeleton + 20, 4); - - /* Set the total length */ - p[3] = 0x10 + len; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 20 + len * 4, M5602_URB_MSG_TIMEOUT); - - return (err < 0) ? err : 0; -} - -int s5k4aa_init(struct sd *sd) -{ - int i, err = 0; - - for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (init_s5k4aa[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - init_s5k4aa[i][1], - init_s5k4aa[i][2]); - break; - - case SENSOR: - data[0] = init_s5k4aa[i][2]; - err = s5k4aa_write_sensor(sd, - init_s5k4aa[i][1], data, 1); - break; - - case SENSOR_LONG: - data[0] = init_s5k4aa[i][2]; - data[1] = init_s5k4aa[i][3]; - err = s5k4aa_write_sensor(sd, - init_s5k4aa[i][1], data, 2); - break; - default: - info("Invalid stream command, exiting init"); - return -EINVAL; - } - } - - if (dump_sensor) - s5k4aa_dump_registers(sd); - - if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { - u8 data = 0x02; - info("vertical flip quirk active"); - s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - s5k4aa_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); - data |= S5K4AA_RM_V_FLIP; - data &= ~S5K4AA_RM_H_FLIP; - s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - - /* Decrement COLSTART to preserve color order (BGGR) */ - s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - data--; - s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - - /* Increment ROWSTART to preserve color order (BGGR) */ - s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - data++; - s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - } - - return (err < 0) ? err : 0; -} - -int s5k4aa_power_down(struct sd *sd) -{ - return 0; -} - -int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - - err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); - if (err < 0) - goto out; - - *val = data << 8; - err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); - *val |= data; - PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val); -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val); - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - data = (val >> 8) & 0xff; - err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); - if (err < 0) - goto out; - data = val & 0xff; - err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - - err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - *val = (data & S5K4AA_RM_V_FLIP) >> 7; - PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val); - -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val); - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - goto out; - data = ((data & ~S5K4AA_RM_V_FLIP) - | ((val & 0x01) << 7)); - err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - goto out; - - if (val) { - err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - if (err < 0) - goto out; - - data++; - err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - } else { - err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - if (err < 0) - goto out; - - data--; - err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); - } -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - - err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - *val = (data & S5K4AA_RM_H_FLIP) >> 6; - PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val); -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", - val); - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - goto out; - - data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); - err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); - if (err < 0) - goto out; - - if (val) { - err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - if (err < 0) - goto out; - data++; - err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - if (err < 0) - goto out; - } else { - err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - if (err < 0) - goto out; - data--; - err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); - } -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - - err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); - *val = data; - PDEBUG(DBG_V4L2_CID, "Read gain %d", *val); - -out: - return (err < 0) ? err : 0; -} - -int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - u8 data = S5K4AA_PAGE_MAP_2; - int err; - - PDEBUG(DBG_V4L2_CID, "Set gain to %d", val); - err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); - if (err < 0) - goto out; - - data = val & 0xff; - err = s5k4aa_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); - -out: - return (err < 0) ? err : 0; -} - -void s5k4aa_dump_registers(struct sd *sd) -{ - int address; - u8 page, old_page; - s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); - for (page = 0; page < 16; page++) { - s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); - info("Dumping the s5k4aa register state for page 0x%x", page); - for (address = 0; address <= 0xff; address++) { - u8 value = 0; - s5k4aa_read_sensor(sd, address, &value, 1); - info("register 0x%x contains 0x%x", - address, value); - } - } - info("s5k4aa register state dump complete"); - - for (page = 0; page < 16; page++) { - s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); - info("Probing for which registers that are " - "read/write for page 0x%x", page); - for (address = 0; address <= 0xff; address++) { - u8 old_value, ctrl_value, test_value = 0xff; - - s5k4aa_read_sensor(sd, address, &old_value, 1); - s5k4aa_write_sensor(sd, address, &test_value, 1); - s5k4aa_read_sensor(sd, address, &ctrl_value, 1); - - if (ctrl_value == test_value) - info("register 0x%x is writeable", address); - else - info("register 0x%x is read only", address); - - /* Restore original value */ - s5k4aa_write_sensor(sd, address, &old_value, 1); - } - } - info("Read/write register probing complete"); - s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); -} diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h deleted file mode 100644 index bb7f7e3e90af..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Driver for the s5k4aa sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_S5K4AA_H_ -#define M5602_S5K4AA_H_ - -#include - -#include "m5602_sensor.h" - -/*****************************************************************************/ - -#define S5K4AA_PAGE_MAP 0xec - -#define S5K4AA_PAGE_MAP_0 0x00 -#define S5K4AA_PAGE_MAP_1 0x01 -#define S5K4AA_PAGE_MAP_2 0x02 - -/* Sensor register definitions for page 0x02 */ -#define S5K4AA_READ_MODE 0x03 -#define S5K4AA_ROWSTART_HI 0x04 -#define S5K4AA_ROWSTART_LO 0x05 -#define S5K4AA_COLSTART_HI 0x06 -#define S5K4AA_COLSTART_LO 0x07 -#define S5K4AA_WINDOW_HEIGHT_HI 0x08 -#define S5K4AA_WINDOW_HEIGHT_LO 0x09 -#define S5K4AA_WINDOW_WIDTH_HI 0x0a -#define S5K4AA_WINDOW_WIDTH_LO 0x0b -#define S5K4AA_GLOBAL_GAIN__ 0x0f /* Only a guess ATM !!! */ -#define S5K4AA_H_BLANK_HI__ 0x1d /* Only a guess ATM !!! sync lost - if too low, reduces frame rate - if too high */ -#define S5K4AA_H_BLANK_LO__ 0x1e /* Only a guess ATM !!! */ -#define S5K4AA_EXPOSURE_HI 0x17 -#define S5K4AA_EXPOSURE_LO 0x18 -#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ -#define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ - -#define S5K4AA_RM_ROW_SKIP_4X 0x08 -#define S5K4AA_RM_ROW_SKIP_2X 0x04 -#define S5K4AA_RM_COL_SKIP_4X 0x02 -#define S5K4AA_RM_COL_SKIP_2X 0x01 -#define S5K4AA_RM_H_FLIP 0x40 -#define S5K4AA_RM_V_FLIP 0x80 - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern int dump_sensor; -extern unsigned int m5602_debug; - -int s5k4aa_probe(struct sd *sd); -int s5k4aa_init(struct sd *sd); -int s5k4aa_power_down(struct sd *sd); - -void s5k4aa_dump_registers(struct sd *sd); - -int s5k4aa_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); -int s5k4aa_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); -int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); -int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); - -static struct m5602_sensor s5k4aa = { - .name = "S5K4AA", - .probe = s5k4aa_probe, - .init = s5k4aa_init, - .power_down = s5k4aa_power_down, - .read_sensor = s5k4aa_read_sensor, - .write_sensor = s5k4aa_write_sensor, - .i2c_slave_id = 0x5a, - .nctrls = 4, - .ctrls = { - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k4aa_set_vflip, - .get = s5k4aa_get_vflip - - }, { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k4aa_set_hflip, - .get = s5k4aa_get_hflip - - }, { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = 0xa0, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k4aa_set_gain, - .get = s5k4aa_get_gain - }, { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 13, - .maximum = 0xfff, - .step = 1, - .default_value = 0x100, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k4aa_set_exposure, - .get = s5k4aa_get_exposure - } - }, - - .nmodes = 1, - .modes = { - { - M5602_DEFAULT_FRAME_WIDTH, - M5602_DEFAULT_FRAME_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, - .bytesperline = M5602_DEFAULT_FRAME_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } -}; - -static const unsigned char preinit_s5k4aa[][4] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00} -}; - -static const unsigned char init_s5k4aa[][4] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K4AA_PAGE_MAP, 0x07, 0x00}, - {SENSOR, 0x36, 0x01, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00}, - {SENSOR, 0x7b, 0xff, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, 0x0c, 0x05, 0x00}, - {SENSOR, 0x02, 0x0e, 0x00}, - {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00}, - {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00}, - {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00}, - {SENSOR, 0x11, 0x00, 0x00}, - {SENSOR, 0x12, 0x00, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, - {SENSOR, 0x37, 0x00, 0x00}, - {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, - {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00}, - {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, - {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00}, - {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, - {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00}, - {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, - {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00}, - {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00}, - {SENSOR, 0x11, 0x04, 0x00}, - {SENSOR, 0x12, 0xc3, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ - - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X - | S5K4AA_RM_COL_SKIP_2X, 0x00}, - /* 0x37 : Fix image stability when light is too bright and improves - * image quality in 640x480, but worsens it in 1280x1024 */ - {SENSOR, 0x37, 0x01, 0x00}, - /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ - {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, - {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, - {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, - /* window_height_hi, window_height_lo : 960 = 0x03c0 */ - {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, - {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00}, - /* window_width_hi, window_width_lo : 1280 = 0x0500 */ - {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, - {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, - {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, - {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ - {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, - {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, - {SENSOR, 0x11, 0x04, 0x00}, - {SENSOR, 0x12, 0xc3, 0x00}, - {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, - {SENSOR, 0x02, 0x0e, 0x00}, - {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, - {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, - {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} -}; - -static - const - struct dmi_system_id s5k4aa_vflip_dmi_table[] = { - { - .ident = "Fujitsu-Siemens Amilo Xa 2528", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528") - } - }, - { - .ident = "Fujitsu-Siemens Amilo Xi 2550", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550") - } - }, - { - .ident = "MSI GX700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "GX700"), - DMI_MATCH(DMI_BIOS_DATE, "07/26/2007") - } - }, - { } -}; - -#endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c deleted file mode 100644 index b4b33c2d0499..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Driver for the s5k83a sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include "m5602_s5k83a.h" - -int s5k83a_probe(struct sd *sd) -{ - u8 prod_id = 0, ver_id = 0; - int i, err = 0; - - if (force_sensor) { - if (force_sensor == S5K83A_SENSOR) { - info("Forcing a %s sensor", s5k83a.name); - goto sensor_found; - } - /* If we want to force another sensor, don't try to probe this - * one */ - return -ENODEV; - } - - info("Probing for a s5k83a sensor"); - - /* Preinit the sensor */ - for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { - u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]}; - if (preinit_s5k83a[i][0] == SENSOR) - err = s5k83a_write_sensor(sd, preinit_s5k83a[i][1], - data, 2); - else - err = m5602_write_bridge(sd, preinit_s5k83a[i][1], - data[0]); - } - - /* We don't know what register (if any) that contain the product id - * Just pick the first addresses that seem to produce the same results - * on multiple machines */ - if (s5k83a_read_sensor(sd, 0x00, &prod_id, 1)) - return -ENODEV; - - if (s5k83a_read_sensor(sd, 0x01, &ver_id, 1)) - return -ENODEV; - - if ((prod_id == 0xff) || (ver_id == 0xff)) - return -ENODEV; - else - info("Detected a s5k83a sensor"); - -sensor_found: - sd->gspca_dev.cam.cam_mode = s5k83a.modes; - sd->gspca_dev.cam.nmodes = s5k83a.nmodes; - sd->desc->ctrls = s5k83a.ctrls; - sd->desc->nctrls = s5k83a.nctrls; - return 0; -} - -int s5k83a_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, - sd->sensor->i2c_slave_id); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); - if (err < 0) - goto out; - - err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); - if (err < 0) - goto out; - - do { - err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); - } while ((*i2c_data & I2C_BUSY) && !err); - - if (err < 0) - goto out; - for (i = 0; i < len && !len; i++) { - err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); - - PDEBUG(DBG_TRACE, "Reading sensor register " - "0x%x containing 0x%x ", address, *i2c_data); - } - -out: - return (err < 0) ? err : 0; -} - -int s5k83a_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len) -{ - int err, i; - u8 *p; - struct usb_device *udev = sd->gspca_dev.dev; - __u8 *buf = sd->gspca_dev.usb_buf; - - /* No sensor with a data width larger than 16 bits has yet been seen */ - if (len > 2 || !len) - return -EINVAL; - - memcpy(buf, sensor_urb_skeleton, - sizeof(sensor_urb_skeleton)); - - buf[11] = sd->sensor->i2c_slave_id; - buf[15] = address; - - /* Special case larger sensor writes */ - p = buf + 16; - - /* Copy a four byte write sequence for each byte to be written to */ - for (i = 0; i < len; i++) { - memcpy(p, sensor_urb_skeleton + 16, 4); - p[3] = i2c_data[i]; - p += 4; - PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x", - address, i2c_data[i]); - } - - /* Copy the tailer */ - memcpy(p, sensor_urb_skeleton + 20, 4); - - /* Set the total length */ - p[3] = 0x10 + len; - - err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x04, 0x40, 0x19, - 0x0000, buf, - 20 + len * 4, M5602_URB_MSG_TIMEOUT); - - return (err < 0) ? err : 0; -} - -int s5k83a_init(struct sd *sd) -{ - int i, err = 0; - - for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { - u8 data[2] = {0x00, 0x00}; - - switch (init_s5k83a[i][0]) { - case BRIDGE: - err = m5602_write_bridge(sd, - init_s5k83a[i][1], - init_s5k83a[i][2]); - break; - - case SENSOR: - data[0] = init_s5k83a[i][2]; - err = s5k83a_write_sensor(sd, - init_s5k83a[i][1], data, 1); - break; - - case SENSOR_LONG: - data[0] = init_s5k83a[i][2]; - data[1] = init_s5k83a[i][3]; - err = s5k83a_write_sensor(sd, - init_s5k83a[i][1], data, 2); - break; - default: - info("Invalid stream command, exiting init"); - return -EINVAL; - } - } - - if (dump_sensor) - s5k83a_dump_registers(sd); - - return (err < 0) ? err : 0; -} - -int s5k83a_power_down(struct sd *sd) -{ - return 0; -} - -void s5k83a_dump_registers(struct sd *sd) -{ - int address; - u8 page, old_page; - s5k83a_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); - - for (page = 0; page < 16; page++) { - s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); - info("Dumping the s5k83a register state for page 0x%x", page); - for (address = 0; address <= 0xff; address++) { - u8 val = 0; - s5k83a_read_sensor(sd, address, &val, 1); - info("register 0x%x contains 0x%x", - address, val); - } - } - info("s5k83a register state dump complete"); - - for (page = 0; page < 16; page++) { - s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); - info("Probing for which registers that are read/write " - "for page 0x%x", page); - for (address = 0; address <= 0xff; address++) { - u8 old_val, ctrl_val, test_val = 0xff; - - s5k83a_read_sensor(sd, address, &old_val, 1); - s5k83a_write_sensor(sd, address, &test_val, 1); - s5k83a_read_sensor(sd, address, &ctrl_val, 1); - - if (ctrl_val == test_val) - info("register 0x%x is writeable", address); - else - info("register 0x%x is read only", address); - - /* Restore original val */ - s5k83a_write_sensor(sd, address, &old_val, 1); - } - } - info("Read/write register probing complete"); - s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); -} - -int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - - err = s5k83a_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); - data[1] = data[1] << 1; - *val = data[1]; - - return (err < 0) ? err : 0; -} - -int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0x00; - data[1] = 0x20; - err = s5k83a_write_sensor(sd, 0x14, data, 2); - if (err < 0) - return err; - - data[0] = 0x01; - data[1] = 0x00; - err = s5k83a_write_sensor(sd, 0x0d, data, 2); - if (err < 0) - return err; - - /* FIXME: This is not sane, we need to figure out the composition - of these registers */ - data[0] = val >> 3; /* brightness, high 5 bits */ - data[1] = val >> 1; /* brightness, high 7 bits */ - err = s5k83a_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); - - return (err < 0) ? err : 0; -} - -int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data; - struct sd *sd = (struct sd *) gspca_dev; - - err = s5k83a_read_sensor(sd, S5K83A_WHITENESS, &data, 1); - - *val = data; - return (err < 0) ? err : 0; -} - -int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = val; - err = s5k83a_write_sensor(sd, S5K83A_WHITENESS, data, 1); - - return (err < 0) ? err : 0; -} - -int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - - err = s5k83a_read_sensor(sd, S5K83A_GAIN, data, 2); - - data[1] = data[1] & 0x3f; - if (data[1] > S5K83A_MAXIMUM_GAIN) - data[1] = S5K83A_MAXIMUM_GAIN; - - *val = data[1]; - - return (err < 0) ? err : 0; -} - -int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[2]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0; - data[1] = val; - err = s5k83a_write_sensor(sd, S5K83A_GAIN, data, 2); - - return (err < 0) ? err : 0; -} - -int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0x05; - err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); - if (err < 0) - return err; - - err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); - *val = (data[0] | 0x40) ? 1 : 0; - - return (err < 0) ? err : 0; -} - -int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0x05; - err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); - if (err < 0) - return err; - - err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); - if (err < 0) - return err; - - /* set or zero six bit, seven is hflip */ - data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK - : (data[0] & 0x80) | S5K83A_FLIP_MASK; - err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); - if (err < 0) - return err; - - data[0] = (val) ? 0x0b : 0x0a; - err = s5k83a_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); - - return (err < 0) ? err : 0; -} - -int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0x05; - err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); - if (err < 0) - return err; - - err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); - *val = (data[0] | 0x80) ? 1 : 0; - - return (err < 0) ? err : 0; -} - -int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - u8 data[1]; - struct sd *sd = (struct sd *) gspca_dev; - - data[0] = 0x05; - err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); - if (err < 0) - return err; - - err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); - if (err < 0) - return err; - - /* set or zero seven bit, six is vflip */ - data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK - : (data[0] & 0x40) | S5K83A_FLIP_MASK; - err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); - if (err < 0) - return err; - - data[0] = (val) ? 0x0a : 0x0b; - err = s5k83a_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); - - return (err < 0) ? err : 0; -} diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h deleted file mode 100644 index 833708eb5a42..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Driver for the s5k83a sensor - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_S5K83A_H_ -#define M5602_S5K83A_H_ - -#include "m5602_sensor.h" - -#define S5K83A_FLIP 0x01 -#define S5K83A_HFLIP_TUNE 0x03 -#define S5K83A_VFLIP_TUNE 0x05 -#define S5K83A_WHITENESS 0x0a -#define S5K83A_GAIN 0x18 -#define S5K83A_BRIGHTNESS 0x1b -#define S5K83A_PAGE_MAP 0xec - -#define S5K83A_DEFAULT_BRIGHTNESS 0x71 -#define S5K83A_DEFAULT_WHITENESS 0x7e -#define S5K83A_DEFAULT_GAIN 0x00 -#define S5K83A_MAXIMUM_GAIN 0x3c -#define S5K83A_FLIP_MASK 0x10 - - -/*****************************************************************************/ - -/* Kernel module parameters */ -extern int force_sensor; -extern int dump_sensor; -extern unsigned int m5602_debug; - - -int s5k83a_probe(struct sd *sd); -int s5k83a_init(struct sd *sd); -int s5k83a_power_down(struct sd *sd); - -void s5k83a_dump_registers(struct sd *sd); - -int s5k83a_read_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); -int s5k83a_write_sensor(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - -int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); -int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); -int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val); -int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); -int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); -int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); -int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); -int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); - - -static struct m5602_sensor s5k83a = { - .name = "S5K83A", - .probe = s5k83a_probe, - .init = s5k83a_init, - .power_down = s5k83a_power_down, - .read_sensor = s5k83a_read_sensor, - .write_sensor = s5k83a_write_sensor, - .i2c_slave_id = 0x5a, - .nctrls = 5, - .ctrls = { - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = S5K83A_DEFAULT_BRIGHTNESS, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_brightness, - .get = s5k83a_get_brightness - - }, { - { - .id = V4L2_CID_WHITENESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "whiteness", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x01, - .default_value = S5K83A_DEFAULT_WHITENESS, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_whiteness, - .get = s5k83a_get_whiteness, - }, { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = S5K83A_MAXIMUM_GAIN, - .step = 0x01, - .default_value = S5K83A_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = s5k83a_set_gain, - .get = s5k83a_get_gain - }, { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k83a_set_hflip, - .get = s5k83a_get_hflip - }, { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = s5k83a_set_vflip, - .get = s5k83a_get_vflip - } - }, - .nmodes = 1, - .modes = { - { - M5602_DEFAULT_FRAME_WIDTH, - M5602_DEFAULT_FRAME_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, - .bytesperline = M5602_DEFAULT_FRAME_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } - } -}; - -static const unsigned char preinit_s5k83a[][4] = -{ - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, - {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, - - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00} -}; - -/* This could probably be considerably shortened. - I don't have the hardware to experiment with it, patches welcome -*/ -static const unsigned char init_s5k83a[][4] = -{ - {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, - {SENSOR, 0xaf, 0x01, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, - {SENSOR, 0x7b, 0xff, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x01, 0x50, 0x00}, - {SENSOR, 0x12, 0x20, 0x00}, - {SENSOR, 0x17, 0x40, 0x00}, - {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, - {SENSOR, 0x1c, 0x00, 0x00}, - {SENSOR, 0x02, 0x70, 0x00}, - {SENSOR, 0x03, 0x0b, 0x00}, - {SENSOR, 0x04, 0xf0, 0x00}, - {SENSOR, 0x05, 0x0b, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x06, 0x71, 0x00}, - {SENSOR, 0x07, 0xe8, 0x00}, - {SENSOR, 0x08, 0x02, 0x00}, - {SENSOR, 0x09, 0x88, 0x00}, - {SENSOR, 0x14, 0x00, 0x00}, - {SENSOR, 0x15, 0x20, 0x00}, - {SENSOR, 0x19, 0x00, 0x00}, - {SENSOR, 0x1a, 0x98, 0x00}, - {SENSOR, 0x0f, 0x02, 0x00}, - {SENSOR, 0x10, 0xe5, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR_LONG, 0x14, 0x00, 0x20}, - {SENSOR_LONG, 0x0d, 0x00, 0x7d}, - {SENSOR_LONG, 0x1b, 0x0d, 0x05}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, - - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, - {SENSOR, 0xaf, 0x01, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - /* ff ( init value )is very dark) || 71 and f0 better */ - {SENSOR, 0x7b, 0xff, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x01, 0x50, 0x00}, - {SENSOR, 0x12, 0x20, 0x00}, - {SENSOR, 0x17, 0x40, 0x00}, - {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, - {SENSOR, 0x1c, 0x00, 0x00}, - {SENSOR, 0x02, 0x70, 0x00}, - /* some values like 0x10 give a blue-purple image */ - {SENSOR, 0x03, 0x0b, 0x00}, - {SENSOR, 0x04, 0xf0, 0x00}, - {SENSOR, 0x05, 0x0b, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - /* under 80 don't work, highter depend on value */ - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, - - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x06, 0x71, 0x00}, - {SENSOR, 0x07, 0xe8, 0x00}, - {SENSOR, 0x08, 0x02, 0x00}, - {SENSOR, 0x09, 0x88, 0x00}, - {SENSOR, 0x14, 0x00, 0x00}, - {SENSOR, 0x15, 0x20, 0x00}, - {SENSOR, 0x19, 0x00, 0x00}, - {SENSOR, 0x1a, 0x98, 0x00}, - {SENSOR, 0x0f, 0x02, 0x00}, - {SENSOR, 0x10, 0xe5, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR_LONG, 0x14, 0x00, 0x20}, - {SENSOR_LONG, 0x0d, 0x00, 0x7d}, - {SENSOR_LONG, 0x1b, 0x0d, 0x05}, - - /* The following sequence is useless after a clean boot - but is necessary after resume from suspend */ - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, - {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, - {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, - {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, - {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, - {SENSOR, 0xaf, 0x01, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, - {SENSOR, 0x7b, 0xff, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x01, 0x50, 0x00}, - {SENSOR, 0x12, 0x20, 0x00}, - {SENSOR, 0x17, 0x40, 0x00}, - {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, - {SENSOR, 0x1c, 0x00, 0x00}, - {SENSOR, 0x02, 0x70, 0x00}, - {SENSOR, 0x03, 0x0b, 0x00}, - {SENSOR, 0x04, 0xf0, 0x00}, - {SENSOR, 0x05, 0x0b, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, - {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, - {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, - {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, - {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, - {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, - {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, - - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, 0x06, 0x71, 0x00}, - {SENSOR, 0x07, 0xe8, 0x00}, - {SENSOR, 0x08, 0x02, 0x00}, - {SENSOR, 0x09, 0x88, 0x00}, - {SENSOR, 0x14, 0x00, 0x00}, - {SENSOR, 0x15, 0x20, 0x00}, - {SENSOR, 0x19, 0x00, 0x00}, - {SENSOR, 0x1a, 0x98, 0x00}, - {SENSOR, 0x0f, 0x02, 0x00}, - - {SENSOR, 0x10, 0xe5, 0x00}, - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR_LONG, 0x14, 0x00, 0x20}, - {SENSOR_LONG, 0x0d, 0x00, 0x7d}, - {SENSOR_LONG, 0x1b, 0x0d, 0x05}, - - /* normal colors - (this is value after boot, but after tries can be different) */ - {SENSOR, 0x00, 0x06, 0x00}, - - /* set default brightness */ - {SENSOR_LONG, 0x14, 0x00, 0x20}, - {SENSOR_LONG, 0x0d, 0x01, 0x00}, - {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3, - S5K83A_DEFAULT_BRIGHTNESS >> 1}, - - /* set default whiteness */ - {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00}, - - /* set default gain */ - {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN}, - - /* set default flip */ - {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, - {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00}, - {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00}, - {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00} - -}; - -#endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h b/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h deleted file mode 100644 index 930fcaab4416..000000000000 --- a/trunk/drivers/media/video/gspca/m5602/m5602_sensor.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * USB Driver for ALi m5602 based webcams - * - * Copyright (C) 2008 Erik Andren - * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. - * Copyright (C) 2005 m5603x Linux Driver Project - * - * Portions of code to USB interface and ALi driver software, - * Copyright (c) 2006 Willem Duinker - * v4l2 interface modeled after the V4L2 driver - * for SN9C10x PC Camera Controllers - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef M5602_SENSOR_H_ -#define M5602_SENSOR_H_ - -#include "m5602_bridge.h" - -#define M5602_DEFAULT_FRAME_WIDTH 640 -#define M5602_DEFAULT_FRAME_HEIGHT 480 - -#define M5602_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10) - -/* Enumerates all supported sensors */ -enum sensors { - OV9650_SENSOR = 1, - S5K83A_SENSOR = 2, - S5K4AA_SENSOR = 3, - MT9M111_SENSOR = 4, - PO1030_SENSOR = 5 -}; - -/* Enumerates all possible instruction types */ -enum instruction { - BRIDGE, - SENSOR, - SENSOR_LONG -}; - -struct m5602_sensor { - /* Defines the name of a sensor */ - char name[32]; - - /* What i2c address the sensor is connected to */ - u8 i2c_slave_id; - - /* Probes if the sensor is connected */ - int (*probe)(struct sd *sd); - - /* Performs a initialization sequence */ - int (*init)(struct sd *sd); - - /* Performs a power down sequence */ - int (*power_down)(struct sd *sd); - - /* Reads a sensor register */ - int (*read_sensor)(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - - /* Writes to a sensor register */ - int (*write_sensor)(struct sd *sd, const u8 address, - u8 *i2c_data, const u8 len); - - int nctrls; - struct ctrl ctrls[M5602_MAX_CTRLS]; - - char nmodes; - struct v4l2_pix_format modes[]; -}; - -#endif diff --git a/trunk/drivers/media/video/gspca/mars.c b/trunk/drivers/media/video/gspca/mars.c index 277ca34a8817..4d5db47ba8cb 100644 --- a/trunk/drivers/media/video/gspca/mars.c +++ b/trunk/drivers/media/video/gspca/mars.c @@ -134,7 +134,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { int err_code; __u8 *data; @@ -143,10 +143,9 @@ static int sd_start(struct gspca_dev *gspca_dev) int intpipe; PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); - err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8); - if (err_code < 0) { + if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) { PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); - return err_code; + return; } data = gspca_dev->usb_buf; @@ -155,7 +154,7 @@ static int sd_start(struct gspca_dev *gspca_dev) err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) - return err_code; + return; /* Initialize the MR97113 chip register @@ -181,14 +180,14 @@ static int sd_start(struct gspca_dev *gspca_dev) err_code = reg_w(gspca_dev, data[0], 11); if (err_code < 0) - return err_code; + return; data[0] = 0x23; /* address */ data[1] = 0x09; /* reg 35, append frame header */ err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) - return err_code; + return; data[0] = 0x3c; /* address */ /* if (gspca_dev->width == 1280) */ @@ -199,7 +198,7 @@ static int sd_start(struct gspca_dev *gspca_dev) * (unit: 4KB) 200KB */ err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) - return err_code; + return; if (0) { /* fixed dark-gain */ data[1] = 0; /* reg 94, Y Gain (1.75) */ @@ -241,13 +240,13 @@ static int sd_start(struct gspca_dev *gspca_dev) err_code = reg_w(gspca_dev, data[0], 6); if (err_code < 0) - return err_code; + return; data[0] = 0x67; data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) - return err_code; + return; /* * initialize the value of MI sensor... @@ -327,7 +326,6 @@ static int sd_start(struct gspca_dev *gspca_dev) data[0] = 0x00; data[1] = 0x4d; /* ISOC transfering enable... */ reg_w(gspca_dev, data[0], 2); - return err_code; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/ov519.c b/trunk/drivers/media/video/gspca/ov519.c index ca671194679e..4df4eec9f7e7 100644 --- a/trunk/drivers/media/video/gspca/ov519.c +++ b/trunk/drivers/media/video/gspca/ov519.c @@ -1854,7 +1854,7 @@ static int set_ov_sensor_window(struct sd *sd) } /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int ret; @@ -1871,10 +1871,9 @@ static int sd_start(struct gspca_dev *gspca_dev) goto out; PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); ov51x_led_control(sd, 1); - return 0; + return; out: PDEBUG(D_ERR, "camera start error:%d", ret); - return ret; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/pac207.c b/trunk/drivers/media/video/gspca/pac207.c index 0b0c573d06da..83b5f740c947 100644 --- a/trunk/drivers/media/video/gspca/pac207.c +++ b/trunk/drivers/media/video/gspca/pac207.c @@ -281,7 +281,7 @@ static int sd_init(struct gspca_dev *gspca_dev) } /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 mode; @@ -323,7 +323,6 @@ static int sd_start(struct gspca_dev *gspca_dev) sd->sof_read = 0; sd->autogain_ignore_frames = 0; atomic_set(&sd->avg_lum, -1); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -535,7 +534,6 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2470)}, {USB_DEVICE(0x093a, 0x2471)}, {USB_DEVICE(0x093a, 0x2472)}, - {USB_DEVICE(0x093a, 0x2476)}, {USB_DEVICE(0x2001, 0xf115)}, {} }; diff --git a/trunk/drivers/media/video/gspca/pac7311.c b/trunk/drivers/media/video/gspca/pac7311.c index e5ff9a6199ef..ba865b7f1ed8 100644 --- a/trunk/drivers/media/video/gspca/pac7311.c +++ b/trunk/drivers/media/video/gspca/pac7311.c @@ -675,7 +675,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -724,7 +724,6 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x78, 0x01); else reg_w(gspca_dev, 0x78, 0x05); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/sonixb.c b/trunk/drivers/media/video/gspca/sonixb.c index 6c69bc7778fc..12b81ae526b7 100644 --- a/trunk/drivers/media/video/gspca/sonixb.c +++ b/trunk/drivers/media/video/gspca/sonixb.c @@ -490,7 +490,7 @@ static const __u8 tas5130_sensor_init[][8] = { {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, }; -static struct sensor_data sensor_data[] = { +struct sensor_data sensor_data[] = { SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, @@ -892,7 +892,7 @@ static int sd_init(struct gspca_dev *gspca_dev) } /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam = &gspca_dev->cam; @@ -976,7 +976,6 @@ static int sd_start(struct gspca_dev *gspca_dev) sd->frames_to_drop = 0; sd->autogain_ignore_frames = 0; atomic_set(&sd->avg_lum, -1); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/sonixj.c b/trunk/drivers/media/video/gspca/sonixj.c index 53cb82d9e7c6..572b0f363b64 100644 --- a/trunk/drivers/media/video/gspca/sonixj.c +++ b/trunk/drivers/media/video/gspca/sonixj.c @@ -39,7 +39,6 @@ struct sd { unsigned char contrast; unsigned char colors; unsigned char autogain; - __u8 vflip; /* ov7630 only */ signed char ag_cnt; #define AG_CNT_START 13 @@ -71,8 +70,6 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -134,22 +131,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, -/* ov7630 only */ -#define VFLIP_IDX 4 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vflip", - .minimum = 0, - .maximum = 1, - .step = 1, -#define VFLIP_DEF 1 - .default_value = VFLIP_DEF, - }, - .set = sd_setvflip, - .get = sd_getvflip, - }, }; static struct v4l2_pix_format vga_mode[] = { @@ -267,12 +248,10 @@ static const __u8 gamma_def[] = { 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; -/* color matrix and offsets */ static const __u8 reg84[] = { - 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */ - 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */ - 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ - 0x00, 0x00, 0x00 /* YUV offsets */ + 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, + 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, + 0xf7, 0x0f, 0x00, 0x00, 0x00 }; static const __u8 hv7131r_sensor_init[][8] = { {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, @@ -455,8 +434,7 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, /*fixme: + 0x12, 0x04*/ -/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN - * set by setvflip */ + {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, @@ -971,8 +949,6 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX); break; } - if (sd->sensor != SENSOR_OV7630) - gspca_dev->ctrl_dis |= (1 << VFLIP_IDX); return 0; } @@ -1104,17 +1080,20 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, static void setbrightcont(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int val; + unsigned val; __u8 reg84_full[0x15]; - memcpy(reg84_full, reg84, sizeof reg84_full); - val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */ - reg84_full[0] = (val + 1) / 2; /* red */ - reg84_full[2] = val; /* green */ - reg84_full[4] = (val + 1) / 5; /* blue */ - val = (sd->brightness - BRIGHTNESS_DEF) * 0x10 + memset(reg84_full, 0, sizeof reg84_full); + val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */ + reg84_full[2] = val; + reg84_full[0] = (val + 1) / 2; + reg84_full[4] = (val + 1) / 5; + if (val > BRIGHTNESS_DEF) + val = (sd->brightness - BRIGHTNESS_DEF) * 0x20 / BRIGHTNESS_MAX; - reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */ + else + val = 0; + reg84_full[0x12] = val; /* 00..1f */ reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full); } @@ -1193,16 +1172,8 @@ static void setautogain(struct gspca_dev *gspca_dev) sd->ag_cnt = -1; } -static void setvflip(struct sd *sd) -{ - if (sd->sensor != SENSOR_OV7630) - return; - i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ - sd->vflip ? 0x82 : 0x02); -} - /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; @@ -1292,7 +1263,6 @@ static int sd_start(struct gspca_dev *gspca_dev) break; case SENSOR_OV7630: ov7630_InitSensor(gspca_dev); - setvflip(sd); reg17 = 0xe2; reg1 = 0x44; break; @@ -1350,16 +1320,12 @@ static int sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); setcontrast(gspca_dev); break; - case SENSOR_OV7630: - setvflip(sd); - /* fall thru */ default: /* OV76xx */ setbrightcont(gspca_dev); break; } setautogain(gspca_dev); reg_w1(gspca_dev, 0x01, reg1); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -1580,24 +1546,6 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->vflip = val; - if (gspca_dev->streaming) - setvflip(sd); - return 0; -} - -static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->vflip; - return 0; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1619,7 +1567,6 @@ static const struct sd_desc sd_desc = { static const __devinitdata struct usb_device_id device_table[] = { #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, - {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, @@ -1641,9 +1588,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE - {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, -#endif +/* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ diff --git a/trunk/drivers/media/video/gspca/spca500.c b/trunk/drivers/media/video/gspca/spca500.c index bca106c153fa..6e733901fcca 100644 --- a/trunk/drivers/media/video/gspca/spca500.c +++ b/trunk/drivers/media/video/gspca/spca500.c @@ -660,7 +660,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int err; @@ -867,7 +867,6 @@ static int sd_start(struct gspca_dev *gspca_dev) write_vector(gspca_dev, Clicksmart510_defaults); break; } - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/spca501.c b/trunk/drivers/media/video/gspca/spca501.c index b742f260c7ca..e9eb59bae4fb 100644 --- a/trunk/drivers/media/video/gspca/spca501.c +++ b/trunk/drivers/media/video/gspca/spca501.c @@ -1980,7 +1980,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; int mode; @@ -2012,7 +2012,6 @@ static int sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); setcontrast(gspca_dev); setcolors(gspca_dev); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/spca505.c b/trunk/drivers/media/video/gspca/spca505.c index b345749213cf..f601daf19ebe 100644 --- a/trunk/drivers/media/video/gspca/spca505.c +++ b/trunk/drivers/media/video/gspca/spca505.c @@ -688,7 +688,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; int ret; @@ -733,7 +733,6 @@ static int sd_start(struct gspca_dev *gspca_dev) /* reg_write(dev, 0x5, 0x0, 0x0); */ /* reg_write(dev, 0x5, 0x0, 0x1); */ /* reg_write(dev, 0x5, 0x11, 0x2); */ - return ret; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/spca506.c b/trunk/drivers/media/video/gspca/spca506.c index 645ee9d44d02..195dce96ef06 100644 --- a/trunk/drivers/media/video/gspca/spca506.c +++ b/trunk/drivers/media/video/gspca/spca506.c @@ -422,7 +422,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; __u16 norme; @@ -549,7 +549,6 @@ static int sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "webcam started"); spca506_GetNormeInput(gspca_dev, &norme, &channel); spca506_SetNormeInput(gspca_dev, norme, channel); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/spca508.c b/trunk/drivers/media/video/gspca/spca508.c index 63ec902c895d..281ce02103a3 100644 --- a/trunk/drivers/media/video/gspca/spca508.c +++ b/trunk/drivers/media/video/gspca/spca508.c @@ -1528,7 +1528,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { int mode; @@ -1546,7 +1546,6 @@ static int sd_start(struct gspca_dev *gspca_dev) break; } reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/spca561.c b/trunk/drivers/media/video/gspca/spca561.c index 020a03c466c1..95fcfcb9e31b 100644 --- a/trunk/drivers/media/video/gspca/spca561.c +++ b/trunk/drivers/media/video/gspca/spca561.c @@ -152,7 +152,7 @@ static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value) ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); if (ret < 0) @@ -699,7 +699,7 @@ static void setautogain(struct gspca_dev *gspca_dev) sd->ag_cnt = -1; } -static int sd_start_12a(struct gspca_dev *gspca_dev) +static void sd_start_12a(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */ @@ -725,9 +725,8 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) setwhite(gspca_dev); setautogain(gspca_dev); setexposure(gspca_dev); - return 0; } -static int sd_start_72a(struct gspca_dev *gspca_dev) +static void sd_start_72a(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; int Clck; @@ -751,7 +750,6 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ reg_w_val(dev, 0x8112, 0x10 | 0x20); setautogain(gspca_dev); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -1066,7 +1064,7 @@ static struct ctrl sd_ctrls_12a[] = { { .id = V4L2_CID_DO_WHITE_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "White Balance", + .name = "While Balance", .minimum = WHITE_MIN, .maximum = WHITE_MAX, .step = 1, diff --git a/trunk/drivers/media/video/gspca/stk014.c b/trunk/drivers/media/video/gspca/stk014.c index d9d64911f22a..2f2de429e273 100644 --- a/trunk/drivers/media/video/gspca/stk014.c +++ b/trunk/drivers/media/video/gspca/stk014.c @@ -324,7 +324,7 @@ static int sd_init(struct gspca_dev *gspca_dev) } /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { int ret, value; @@ -374,10 +374,9 @@ static int sd_start(struct gspca_dev *gspca_dev) set_par(gspca_dev, 0x01000000); set_par(gspca_dev, 0x01000000); PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); - return 0; + return; out: PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret); - return ret; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/sunplus.c b/trunk/drivers/media/video/gspca/sunplus.c index bd9288665a80..1cfcc6c49558 100644 --- a/trunk/drivers/media/video/gspca/sunplus.c +++ b/trunk/drivers/media/video/gspca/sunplus.c @@ -961,7 +961,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; @@ -1042,7 +1042,6 @@ static int sd_start(struct gspca_dev *gspca_dev) break; } sp5xx_initContBrigHueRegisters(gspca_dev); - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/t613.c b/trunk/drivers/media/video/gspca/t613.c index b561f7c4f066..f034c748fc7e 100644 --- a/trunk/drivers/media/video/gspca/t613.c +++ b/trunk/drivers/media/video/gspca/t613.c @@ -28,6 +28,8 @@ #include "gspca.h" +#define MAX_GAMMA 0x10 /* 0 to 15 */ + #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) MODULE_AUTHOR("Leandro Costantino "); @@ -47,10 +49,6 @@ struct sd { unsigned char whitebalance; unsigned char mirror; unsigned char effect; - - __u8 sensor; -#define SENSOR_TAS5130A 0 -#define SENSOR_OTHER 1 }; /* V4L2 controls supported by the driver */ @@ -85,9 +83,9 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, - .maximum = 14, + .maximum = 0x0f, .step = 1, - .default_value = 8, + .default_value = 0x09, }, .set = sd_setbrightness, .get = sd_getbrightness, @@ -120,17 +118,16 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcolors, .get = sd_getcolors, }, -#define GAMMA_MAX 16 -#define GAMMA_DEF 10 +#define SD_GAMMA 3 { { .id = V4L2_CID_GAMMA, /* (gamma on win) */ .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", + .name = "Gamma (Untested)", .minimum = 0, - .maximum = GAMMA_MAX - 1, + .maximum = MAX_GAMMA, .step = 1, - .default_value = GAMMA_DEF, + .default_value = 0x09, }, .set = sd_setgamma, .get = sd_getgamma, @@ -200,7 +197,7 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Sharpness", .minimum = 0, - .maximum = 15, + .maximum = MAX_GAMMA, /* 0 to 16 */ .step = 1, .default_value = 0x06, }, @@ -261,6 +258,7 @@ static struct v4l2_pix_format vga_mode_t16[] = { .priv = 0}, }; +#define T16_OFFSET_DATA 631 #define MAX_EFFECTS 7 /* easily done by soft, this table could be removed, * i keep it here just in case */ @@ -274,87 +272,87 @@ static const __u8 effects_table[MAX_EFFECTS][6] = { {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ }; -static const __u8 gamma_table[GAMMA_MAX][34] = { - {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */ +static const __u8 gamma_table[MAX_GAMMA][34] = { + {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */ - 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad, - 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4, - 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7, + {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75, + 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD, + 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4, + 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */ - 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6, - 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0, - 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6, + {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B, + 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6, + 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0, + 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */ - 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e, - 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb, - 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5, + {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, + 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E, + 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB, + 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */ + {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55, 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, - 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6, - 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4, + 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6, + 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */ + {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48, 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, - 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe, - 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3, + 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE, + 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */ + {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */ - 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70, - 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0, - 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0, + {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, + 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70, + 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0, + 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */ - 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79, - 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6, - 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0, + {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, + 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79, + 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6, + 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */ + {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */ - 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e, - 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4, - 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0, + {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44, + 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E, + 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4, + 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */ - 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B, - 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb, - 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5, + {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52, + 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B, + 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB, + 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */ - 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8, - 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3, - 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6, + {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E, + 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8, + 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3, + 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6, + 0xA0, 0xFF}, + {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83, + 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7, + 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC, + 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */ - 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7, - 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc, - 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9, + {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A, + 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6, + 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3, + 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA, 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */ - 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6, - 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3, - 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa, - 0xa0, 0xff}, - {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */ - 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8, - 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed, - 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc, - 0xa0, 0xff} + {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7, + 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8, + 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED, + 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC, + 0xA0, 0xFF} }; static const __u8 tas5130a_sensor_init[][8] = { @@ -366,7 +364,7 @@ static const __u8 tas5130a_sensor_init[][8] = { }; /* read 1 byte */ -static int reg_r(struct gspca_dev *gspca_dev, +static int reg_r_1(struct gspca_dev *gspca_dev, __u16 index) { usb_control_msg(gspca_dev->dev, @@ -380,26 +378,26 @@ static int reg_r(struct gspca_dev *gspca_dev, } static void reg_w(struct gspca_dev *gspca_dev, - __u16 index) -{ - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, index, - NULL, 0, 500); -} - -static void i2c_w(struct gspca_dev *gspca_dev, - const __u8 *buffer, __u16 len) + __u16 value, + __u16 index, + const __u8 *buffer, __u16 len) { + if (buffer == NULL) { + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, index, + NULL, 0, 500); + return; + } if (len <= USB_BUF_SZ) { memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x01, 0, + value, index, gspca_dev->usb_buf, len, 500); } else { __u8 *tmpbuf; @@ -410,56 +408,12 @@ static void i2c_w(struct gspca_dev *gspca_dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x01, 0, + value, index, tmpbuf, len, 500); kfree(tmpbuf); } } -static void other_sensor_init(struct gspca_dev *gspca_dev) -{ - int i; - const __u8 *p; - __u8 byte; - __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; - static const __u8 sensor_init[] = { - 0xdf, 0x6d, - 0xdd, 0x18, - 0x5a, 0xe0, - 0x5c, 0x07, - 0x5d, 0xb0, - 0x5e, 0x1e, - 0x60, 0x71, - 0xef, 0x00, - 0xe9, 0x00, - 0xea, 0x00, - 0x90, 0x24, - 0x91, 0xb2, - 0x82, 0x32, - 0xfd, 0x00, - 0xfd, 0x01, - 0xfd, 0x41, - 0x00 /* table end */ - }; - - p = sensor_init; - while (*p != 0) { - val[1] = *p++; - val[3] = *p++; - if (*p == 0) - reg_w(gspca_dev, 0x3c80); - i2c_w(gspca_dev, val, sizeof val); - i = 4; - while (--i >= 0) { - msleep(15); - byte = reg_r(gspca_dev, 0x60); - if (!(byte & 0x01)) - break; - } - } - reg_w(gspca_dev, 0x3c80); -} - /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) @@ -476,7 +430,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; - sd->gamma = GAMMA_DEF; + sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value; sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; @@ -485,37 +439,27 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } -static void setgamma(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - PDEBUG(D_CONF, "Gamma: %d", sd->gamma); - i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) +static int init_default_parameters(struct gspca_dev *gspca_dev) { /* some of this registers are not really neded, because * they are overriden by setbrigthness, setcontrast, etc, * but wont hurt anyway, and can help someone with similar webcam * to see the initial parameters.*/ - struct sd *sd = (struct sd *) gspca_dev; - int i; - __u8 byte, test_byte; + int i = 0; + __u8 test_byte; static const __u8 read_indexs[] = { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; - static const __u8 n1[] = + static const __u8 n1[6] = {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; - static const __u8 n2[] = + static const __u8 n2[2] = {0x08, 0x00}; - static const __u8 nset[] = - { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; - static const __u8 n3[] = + static const __u8 nset[6] = + { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; + static const __u8 n3[6] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; - static const __u8 n4[] = + static const __u8 n4[0x46] = {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, @@ -525,26 +469,33 @@ static int sd_init(struct gspca_dev *gspca_dev) 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; - static const __u8 nset4[] = { + static const __u8 nset4[18] = { 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, 0xe8, 0xe0 }; /* ojo puede ser 0xe6 en vez de 0xe9 */ - static const __u8 nset2[] = { + static const __u8 nset2[20] = { 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, 0xd8, 0xc8, 0xd9, 0xfc }; - static const __u8 missing[] = + static const __u8 missing[8] = { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; - static const __u8 nset3[] = { + static const __u8 nset3[18] = { 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, 0xcf, 0xe0 }; - static const __u8 nset5[] = - { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ + static const __u8 nset5[4] = + { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ + static const __u8 nset6[34] = { + 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54, + 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, + 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca, + 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2, + 0xa0, 0xff + }; /* Gamma */ static const __u8 nset7[4] = { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ static const __u8 nset9[4] = @@ -554,111 +505,95 @@ static int sd_init(struct gspca_dev *gspca_dev) static const __u8 nset10[6] = { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; - byte = reg_r(gspca_dev, 0x06); - test_byte = reg_r(gspca_dev, 0x07); - if (byte == 0x08 && test_byte == 0x07) { - PDEBUG(D_CONF, "other sensor"); - sd->sensor = SENSOR_OTHER; - } else { - PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte); - sd->sensor = SENSOR_TAS5130A; - } - - i2c_w(gspca_dev, n1, sizeof n1); - test_byte = 0; - i = 5; - while (--i >= 0) { - i2c_w(gspca_dev, nset, sizeof nset); - msleep(5); - test_byte = reg_r(gspca_dev, 0x0063); - msleep(100); - if (test_byte == 0x17) - break; /* OK */ - } - if (i < 0) { - err("Bad sensor reset %02x", test_byte); -/* return -EIO; */ -/*fixme: test - continue */ - } - i2c_w(gspca_dev, n2, sizeof n2); + reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06); + reg_r_1(gspca_dev, 0x0063); + reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02); - i = 0; while (read_indexs[i] != 0x00) { - test_byte = reg_r(gspca_dev, read_indexs[i]); - PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i], + test_byte = reg_r_1(gspca_dev, read_indexs[i]); + PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i], test_byte); i++; } - i2c_w(gspca_dev, n3, sizeof n3); - i2c_w(gspca_dev, n4, sizeof n4); - reg_r(gspca_dev, 0x0080); - reg_w(gspca_dev, 0x2c80); - i2c_w(gspca_dev, nset2, sizeof nset2); - i2c_w(gspca_dev, nset3, sizeof nset3); - i2c_w(gspca_dev, nset4, sizeof nset4); - reg_w(gspca_dev, 0x3880); - reg_w(gspca_dev, 0x3880); - reg_w(gspca_dev, 0x338e); - i2c_w(gspca_dev, nset5, sizeof nset5); - reg_w(gspca_dev, 0x00a9); - setgamma(gspca_dev); - reg_w(gspca_dev, 0x86bb); - reg_w(gspca_dev, 0x4aa6); - - i2c_w(gspca_dev, missing, sizeof missing); - - reg_w(gspca_dev, 0x2087); - reg_w(gspca_dev, 0x2088); - reg_w(gspca_dev, 0x2089); - - i2c_w(gspca_dev, nset7, sizeof nset7); - i2c_w(gspca_dev, nset10, sizeof nset10); - i2c_w(gspca_dev, nset8, sizeof nset8); - i2c_w(gspca_dev, nset9, sizeof nset9); - - reg_w(gspca_dev, 0x2880); - i2c_w(gspca_dev, nset2, sizeof nset2); - i2c_w(gspca_dev, nset3, sizeof nset3); - i2c_w(gspca_dev, nset4, sizeof nset4); + reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46); + reg_r_1(gspca_dev, 0x0080); + reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); + reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); + reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); + reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); + reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); + reg_w(gspca_dev, 0x00, 0x338e, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04); + reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22); + reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0); + reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); + + reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08); + + reg_w(gspca_dev, 0x00, 0x2087, NULL, 0); + reg_w(gspca_dev, 0x00, 0x2088, NULL, 0); + reg_w(gspca_dev, 0x00, 0x2089, NULL, 0); + + reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04); + reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04); + + reg_w(gspca_dev, 0x00, 0x2880, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); + reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); + reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); return 0; } +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + init_default_parameters(gspca_dev); + return 0; +} + static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int brightness; - __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 }; - + __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; brightness = sd->brightness; + if (brightness < 7) { - set6[3] = 0x70 - brightness * 0x10; + set6[3] = 0x70 - (brightness * 0xa); } else { set6[1] = 0x24; - set6[3] = 0x00 + ((brightness - 7) * 0x10); + set6[3] = 0x00 + ((brightness - 7) * 0xa); } - i2c_w(gspca_dev, set6, sizeof set6); + reg_w(gspca_dev, 0x01, 0x0000, set6, 4); } static void setflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + __u8 flipcmd[8] = - {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; + { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; - if (sd->mirror) + if (sd->mirror == 1) flipcmd[3] = 0x01; - i2c_w(gspca_dev, flipcmd, sizeof flipcmd); + reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8); } static void seteffect(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]); + reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); if (sd->effect == 1 || sd->effect == 5) { PDEBUG(D_CONF, "This effect have been disabled for webcam \"safety\""); @@ -666,9 +601,9 @@ static void seteffect(struct gspca_dev *gspca_dev) } if (sd->effect == 1 || sd->effect == 4) - reg_w(gspca_dev, 0x4aa6); + reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); else - reg_w(gspca_dev, 0xfaa6); + reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0); } static void setwhitebalance(struct gspca_dev *gspca_dev) @@ -681,7 +616,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) if (sd->whitebalance == 1) white_balance[7] = 0x3c; - i2c_w(gspca_dev, white_balance, sizeof white_balance); + reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8); } static void setlightfreq(struct gspca_dev *gspca_dev) @@ -692,21 +627,21 @@ static void setlightfreq(struct gspca_dev *gspca_dev) if (sd->freq == 2) /* 60hz */ freq[1] = 0x00; - i2c_w(gspca_dev, freq, sizeof freq); + reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4); } static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int contrast = sd->contrast; - __u16 reg_to_write; + __u16 reg_to_write = 0x00; if (contrast < 7) reg_to_write = 0x8ea9 - (0x200 * contrast); else reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); - reg_w(gspca_dev, reg_to_write); + reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); } static void setcolors(struct gspca_dev *gspca_dev) @@ -715,109 +650,21 @@ static void setcolors(struct gspca_dev *gspca_dev) __u16 reg_to_write; reg_to_write = 0xc0bb + sd->colors * 0x100; - reg_w(gspca_dev, reg_to_write); + reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); } -static void setsharpness(struct gspca_dev *gspca_dev) +static void setgamma(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - __u16 reg_to_write; - - reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; - - reg_w(gspca_dev, reg_to_write); } -static int sd_start(struct gspca_dev *gspca_dev) +static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int i, mode; - static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; - __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; - static const __u8 t3[] = - { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, - 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; - static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; - - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; - switch (mode) { - case 1: /* 352x288 */ - t2[1] = 0x40; - break; - case 2: /* 320x240 */ - t2[1] = 0x10; - break; - case 3: /* 176x144 */ - t2[1] = 0x50; - break; - case 4: /* 160x120 */ - t2[1] = 0x20; - break; - default: /* 640x480 (0x00) */ - break; - } - - if (sd->sensor == SENSOR_TAS5130A) { - i = 0; - while (tas5130a_sensor_init[i][0] != 0) { - i2c_w(gspca_dev, tas5130a_sensor_init[i], - sizeof tas5130a_sensor_init[0]); - i++; - } - reg_w(gspca_dev, 0x3c80); - /* just in case and to keep sync with logs (for mine) */ - i2c_w(gspca_dev, tas5130a_sensor_init[3], - sizeof tas5130a_sensor_init[0]); - reg_w(gspca_dev, 0x3c80); - } else { - other_sensor_init(gspca_dev); - } - /* just in case and to keep sync with logs (for mine) */ - i2c_w(gspca_dev, t1, sizeof t1); - i2c_w(gspca_dev, t2, sizeof t2); - reg_r(gspca_dev, 0x0012); - i2c_w(gspca_dev, t3, sizeof t3); - reg_w(gspca_dev, 0x0013); - i2c_w(gspca_dev, t4, sizeof t4); - /* restart on each start, just in case, sometimes regs goes wrong - * when using controls from app */ - setbrightness(gspca_dev); - setcontrast(gspca_dev); - setcolors(gspca_dev); - return 0; -} - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - static __u8 ffd9[] = { 0xff, 0xd9 }; + __u16 reg_to_write; - if (data[0] == 0x5a) { - /* Control Packet, after this came the header again, - * but extra bytes came in the packet before this, - * sometimes an EOF arrives, sometimes not... */ - return; - } - data += 2; - len -= 2; - if (data[0] == 0xff && data[1] == 0xd8) { - /* extra bytes....., could be processed too but would be - * a waste of time, right now leave the application and - * libjpeg do it for ourserlves.. */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - ffd9, 2); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); - return; - } + reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; - if (data[len - 2] == 0xff && data[len - 1] == 0xd9) { - /* Just in case, i have seen packets with the marker, - * other's do not include it... */ - len -= 2; - } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) @@ -941,7 +788,6 @@ static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - *val = sd->gamma; return 0; } @@ -989,9 +835,9 @@ static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) sd->autogain = val; if (val != 0) - reg_w(gspca_dev, 0xf48e); + reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0); else - reg_w(gspca_dev, 0xb48e); + reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0); return 0; } @@ -1003,6 +849,99 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static void sd_start(struct gspca_dev *gspca_dev) +{ + int mode; + + static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; + __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; + static const __u8 t3[] = + { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, + 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; + static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; + switch (mode) { + case 1: /* 352x288 */ + t2[1] = 0x40; + break; + case 2: /* 320x240 */ + t2[1] = 0x10; + break; + case 3: /* 176x144 */ + t2[1] = 0x50; + break; + case 4: /* 160x120 */ + t2[1] = 0x20; + break; + default: /* 640x480 (0x00) */ + break; + } + + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); + reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0); + /* just in case and to keep sync with logs (for mine) */ + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); + reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0); + /* just in case and to keep sync with logs (for mine) */ + reg_w(gspca_dev, 0x01, 0x0000, t1, 4); + reg_w(gspca_dev, 0x01, 0x0000, t2, 6); + reg_r_1(gspca_dev, 0x0012); + reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10); + reg_w(gspca_dev, 0x00, 0x0013, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4); + /* restart on each start, just in case, sometimes regs goes wrong + * when using controls from app */ + setbrightness(gspca_dev); + setcontrast(gspca_dev); + setcolors(gspca_dev); +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + int sof = 0; + static __u8 ffd9[] = { 0xff, 0xd9 }; + + if (data[0] == 0x5a) { + /* Control Packet, after this came the header again, + * but extra bytes came in the packet before this, + * sometimes an EOF arrives, sometimes not... */ + return; + } + + if (data[len - 1] == 0xff && data[len] == 0xd9) { + /* Just in case, i have seen packets with the marker, + * other's do not include it... */ + data += 2; + len -= 4; + } else if (data[2] == 0xff && data[3] == 0xd8) { + sof = 1; + data += 2; + len -= 2; + } else { + data += 2; + len -= 2; + } + + if (sof) { + /* extra bytes....., could be processed too but would be + * a waste of time, right now leave the application and + * libjpeg do it for ourserlves.. */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + ffd9, 2); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + return; + } + + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { diff --git a/trunk/drivers/media/video/gspca/tv8532.c b/trunk/drivers/media/video/gspca/tv8532.c index 968a5911704f..084af05302a0 100644 --- a/trunk/drivers/media/video/gspca/tv8532.c +++ b/trunk/drivers/media/video/gspca/tv8532.c @@ -390,7 +390,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) } /* -- start the camera -- */ -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); @@ -443,7 +443,6 @@ static int sd_start(struct gspca_dev *gspca_dev) /************************************************/ tv_8532_PollReg(gspca_dev); reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/vc032x.c b/trunk/drivers/media/video/gspca/vc032x.c index be46d9232540..bd4c226c9a07 100644 --- a/trunk/drivers/media/video/gspca/vc032x.c +++ b/trunk/drivers/media/video/gspca/vc032x.c @@ -80,6 +80,7 @@ static struct ctrl sd_ctrls[] = { .step = 1, #define FREQ_DEF 1 .default_value = FREQ_DEF, + .default_value = 1, }, .set = sd_setfreq, .get = sd_getfreq, @@ -1501,7 +1502,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev) usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; const __u8 *GammaT = NULL; @@ -1585,7 +1586,7 @@ static int sd_start(struct gspca_dev *gspca_dev) break; default: PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); - return -EMEDIUMTYPE; + return; } if (GammaT && MatrixT) { put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); @@ -1621,7 +1622,6 @@ static int sd_start(struct gspca_dev *gspca_dev) setautogain(gspca_dev); setlightfreq(gspca_dev); } - return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/gspca/zc3xx.c b/trunk/drivers/media/video/gspca/zc3xx.c index d0a4451dc46f..d61ef727e0c2 100644 --- a/trunk/drivers/media/video/gspca/zc3xx.c +++ b/trunk/drivers/media/video/gspca/zc3xx.c @@ -7178,7 +7178,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; @@ -7331,7 +7331,6 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(dev, 0x02, 0x0008); break; } - return 0; } static void sd_stop0(struct gspca_dev *gspca_dev) diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c index efe849981ab7..a30254bed311 100644 --- a/trunk/drivers/media/video/ir-kbd-i2c.c +++ b/trunk/drivers/media/video/ir-kbd-i2c.c @@ -12,10 +12,6 @@ * Markus Rechberger * modified for DViCO Fusion HDTV 5 RT GOLD by * Chaogui Zhang - * modified for MSI TV@nywhere Plus by - * Henry Wong - * Mark Schultz - * Brian Rogers * * 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 @@ -69,7 +65,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, int size, int offset) { unsigned char buf[6]; - int start, range, toggle, dev, code, ircode; + int start, range, toggle, dev, code; /* poll IR chip */ if (size != i2c_master_recv(&ir->c,buf,size)) @@ -89,24 +85,6 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, if (!start) /* no key pressed */ return 0; - /* - * Hauppauge remotes (black/silver) always use - * specific device ids. If we do not filter the - * device ids then messages destined for devices - * such as TVs (id=0) will get through causing - * mis-fired events. - * - * We also filter out invalid key presses which - * produce annoying debug log entries. - */ - ircode= (start << 12) | (toggle << 11) | (dev << 6) | code; - if ((ircode & 0x1fff)==0x1fff) - /* invalid key press */ - return 0; - - if (dev!=0x1e && dev!=0x1f) - /* not a hauppauge remote */ - return 0; if (!range) code += 64; @@ -116,7 +94,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, /* return key */ *ir_key = code; - *ir_raw = ircode; + *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code; return 1; } @@ -246,15 +224,9 @@ static void ir_timer(unsigned long data) static void ir_work(struct work_struct *work) { struct IR_i2c *ir = container_of(work, struct IR_i2c, work); - int polling_interval = 100; - - /* MSI TV@nywhere Plus requires more frequent polling - otherwise it will miss some keypresses */ - if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30) - polling_interval = 50; ir_key_poll(ir); - mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval)); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100)); } /* ----------------------------------------------------------------------- */ @@ -493,37 +465,9 @@ static int ir_probe(struct i2c_adapter *adap) (1 == rc) ? "yes" : "no"); if (1 == rc) { ir_attach(adap, probe[i], 0, 0); - return 0; + break; } } - - /* Special case for MSI TV@nywhere Plus remote */ - if (adap->id == I2C_HW_SAA7134) { - u8 temp; - - /* MSI TV@nywhere Plus controller doesn't seem to - respond to probes unless we read something from - an existing device. Weird... */ - - msg.addr = 0x50; - rc = i2c_transfer(adap, &msg, 1); - dprintk(1, "probe 0x%02x @ %s: %s\n", - msg.addr, adap->name, - (1 == rc) ? "yes" : "no"); - - /* Now do the probe. The controller does not respond - to 0-byte reads, so we use a 1-byte read instead. */ - msg.addr = 0x30; - msg.len = 1; - msg.buf = &temp; - rc = i2c_transfer(adap, &msg, 1); - dprintk(1, "probe 0x%02x @ %s: %s\n", - msg.addr, adap->name, - (1 == rc) ? "yes" : "no"); - if (1 == rc) - ir_attach(adap, msg.addr, 0, 0); - } - return 0; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-cards.h b/trunk/drivers/media/video/ivtv/ivtv-cards.h index 0b8fe85fb697..381af1bceef8 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-cards.h +++ b/trunk/drivers/media/video/ivtv/ivtv-cards.h @@ -154,7 +154,7 @@ #define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ V4L2_CAP_SLICED_VBI_CAPTURE) -#define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \ +#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) struct ivtv_card_video_input { diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.c b/trunk/drivers/media/video/ivtv/ivtv-driver.c index aeaa13f6cb36..4afc7ea07e86 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.c +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.c @@ -61,14 +61,14 @@ #include "tuner-xc2028.h" /* var to keep track of the number of array elements in use */ -int ivtv_cards_active; +int ivtv_cards_active = 0; /* If you have already X v4l cards, then set this to X. This way the device numbers stay matched. Example: you have a WinTV card without radio and a PVR-350 with. Normally this would give a video1 device together with a radio0 device for the PVR. By setting this to 1 you ensure that radio0 is now also radio1. */ -int ivtv_first_minor; +int ivtv_first_minor = 0; /* Master variable for all ivtv info */ struct ivtv *ivtv_cards[IVTV_MAX_CARDS]; @@ -251,7 +251,7 @@ MODULE_PARM_DESC(newi2c, "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" "\t\t\tDefault is autodetect"); -MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card"); +MODULE_PARM_DESC(ivtv_first_minor, "Set minor assigned to first card"); MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); MODULE_DESCRIPTION("CX23415/CX23416 driver"); @@ -655,9 +655,9 @@ static void ivtv_process_options(struct ivtv *itv) if (itv->card == NULL) { itv->card = ivtv_get_card(IVTV_CARD_PVR_150); - IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n", + IVTV_ERR("Unknown card: vendor/device: %04x/%04x\n", itv->dev->vendor, itv->dev->device); - IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n", + IVTV_ERR(" subsystem vendor/device: %04x/%04x\n", itv->dev->subsystem_vendor, itv->dev->subsystem_device); IVTV_ERR(" %s based\n", chipname); IVTV_ERR("Defaulting to %s card\n", itv->card->name); @@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) itv->speed = 1000; /* VBI */ - itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; + itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; /* Init the sg table for osd/yuv output */ diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.h b/trunk/drivers/media/video/ivtv/ivtv-driver.h index bc29436e8a3c..2ceb5227637c 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.h +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.h @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -506,8 +507,6 @@ struct yuv_playback_info struct v4l2_rect main_rect; u32 v4l2_src_w; u32 v4l2_src_h; - - u8 running; /* Have any frames been displayed */ }; #define IVTV_VBI_FRAMES 32 @@ -752,12 +751,6 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); /* First-open initialization: load firmware, init cx25840, etc. */ int ivtv_init_on_first_open(struct ivtv *itv); -/* Test if the current VBI mode is raw (1) or sliced (0) */ -static inline int ivtv_raw_vbi(const struct ivtv *itv) -{ - return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; -} - /* This is a PCI post thing, where if the pci register is not read, then the write doesn't always take effect right away. By reading back the register any pending PCI writes will be performed (in order), and so diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index b7457fc60ba5..7ec5c99f9ad1 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -39,7 +39,7 @@ associated VBI streams are also automatically claimed. Possible error returns: -EBUSY if someone else has claimed the stream or 0 on success. */ -static int ivtv_claim_stream(struct ivtv_open_id *id, int type) +int ivtv_claim_stream(struct ivtv_open_id *id, int type) { struct ivtv *itv = id->itv; struct ivtv_stream *s = &itv->streams[type]; @@ -78,7 +78,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) if (type == IVTV_DEC_STREAM_TYPE_MPG) { vbi_type = IVTV_DEC_STREAM_TYPE_VBI; } else if (type == IVTV_ENC_STREAM_TYPE_MPG && - itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) { + itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) { vbi_type = IVTV_ENC_STREAM_TYPE_VBI; } else { return 0; @@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b if (len > ucount) len = ucount; if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && - !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) { + itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) { const char *start = buf->buf + buf->readpos; const char *p = start + 1; const u8 *q; @@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should arrive one-by-one, so make sure we never output more than one VBI frame at a time */ if (s->type == IVTV_DEC_STREAM_TYPE_VBI || - (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv))) + (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set)) single_frame = 1; for (;;) { diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.h b/trunk/drivers/media/video/ivtv/ivtv-fileops.h index df81e790147f..2c8d5186c9c3 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.h +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.h @@ -38,6 +38,11 @@ void ivtv_unmute(struct ivtv *itv); /* Utilities */ +/* Try to claim a stream for the filehandle. Return 0 on success, + -EBUSY if stream already claimed. Once a stream is claimed, it + remains claimed until the associated filehandle is closed. */ +int ivtv_claim_stream(struct ivtv_open_id *id, int type); + /* Release a previously claimed stream. */ void ivtv_release_stream(struct ivtv_stream *s); diff --git a/trunk/drivers/media/video/ivtv/ivtv-gpio.c b/trunk/drivers/media/video/ivtv/ivtv-gpio.c index 74a44844ccaf..bc22905ea20f 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-gpio.c +++ b/trunk/drivers/media/video/ivtv/ivtv-gpio.c @@ -124,7 +124,7 @@ void ivtv_reset_ir_gpio(struct ivtv *itv) } /* Xceive tuner reset function */ -int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value) +int ivtv_reset_tuner_gpio(void *dev, int cmd, int value) { struct i2c_algo_bit_data *algo = dev; struct ivtv *itv = algo->data; diff --git a/trunk/drivers/media/video/ivtv/ivtv-gpio.h b/trunk/drivers/media/video/ivtv/ivtv-gpio.h index 48b6291613a2..964a265d91a9 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-gpio.h +++ b/trunk/drivers/media/video/ivtv/ivtv-gpio.h @@ -24,7 +24,7 @@ /* GPIO stuff */ void ivtv_gpio_init(struct ivtv *itv); void ivtv_reset_ir_gpio(struct ivtv *itv); -int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value); +int ivtv_reset_tuner_gpio(void *dev, int cmd, int value); int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg); #endif diff --git a/trunk/drivers/media/video/ivtv/ivtv-i2c.c b/trunk/drivers/media/video/ivtv/ivtv-i2c.c index 24700c211d52..af154238fb9a 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-i2c.c +++ b/trunk/drivers/media/video/ivtv/ivtv-i2c.c @@ -64,6 +64,8 @@ #include "ivtv-gpio.h" #include "ivtv-i2c.h" +#include + /* i2c implementation for cx23415/6 chip, ivtv project. * Author: Kevin Thayer (nufan_wfk at yahoo.com) */ diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index 8696527ab134..61030309d0ad 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -101,15 +101,18 @@ void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } } -static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) +static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { int f, l; + u16 set = 0; for (f = 0; f < 2; f++) { for (l = 0; l < 24; l++) { fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); + set |= fmt->service_lines[f][l]; } } + return set != 0; } u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) @@ -471,7 +474,7 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format int h = fmt->fmt.pix.height; w = min(w, 720); - w = max(w, 2); + w = max(w, 1); h = min(h, itv->is_50hz ? 576 : 480); h = max(h, 2); ivtv_g_fmt_vid_cap(file, fh, fmt); @@ -509,20 +512,27 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv_open_id *id = fh; - struct ivtv *itv = id->itv; - s32 w = fmt->fmt.pix.width; - s32 h = fmt->fmt.pix.height; - int field = fmt->fmt.pix.field; - int ret = ivtv_g_fmt_vid_out(file, fh, fmt); + s32 w, h; + int field; + int ret; - w = min(w, 720); - w = max(w, 2); - h = min(h, itv->is_out_50hz ? 576 : 480); - h = max(h, 2); - if (id->type == IVTV_DEC_STREAM_TYPE_YUV) - fmt->fmt.pix.field = field; + w = fmt->fmt.pix.width; + h = fmt->fmt.pix.height; + field = fmt->fmt.pix.field; + ret = ivtv_g_fmt_vid_out(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; + if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { + fmt->fmt.pix.field = field; + if (fmt->fmt.pix.width < 2) + fmt->fmt.pix.width = 2; + if (fmt->fmt.pix.width > 720) + fmt->fmt.pix.width = 720; + if (fmt->fmt.pix.height < 2) + fmt->fmt.pix.height = 2; + if (fmt->fmt.pix.height > 576) + fmt->fmt.pix.height = 576; + } return ret; } @@ -550,9 +560,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; struct cx2341x_mpeg_params *p = &itv->params; - int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; + int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; @@ -575,11 +585,8 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) - return -EBUSY; itv->vbi.sliced_in->service_set = 0; - itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; - itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); + itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); return ivtv_g_fmt_vbi_cap(file, fh, fmt); } @@ -593,10 +600,10 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) return ret; - check_service_set(vbifmt, itv->is_50hz); - if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) + if (check_service_set(vbifmt, itv->is_50hz) == 0) + return -EINVAL; + if (atomic_read(&itv->capturing) > 0) return -EBUSY; - itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); return 0; @@ -644,6 +651,8 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f itv->dma_data_req_size = 1080 * ((yi->v4l2_src_h + 31) & ~31); + /* Force update of yuv registers */ + yi->yuv_forced_update = 1; return 0; } @@ -752,7 +761,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev)); + strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->capabilities = itv->v4l2_cap; /* capabilities */ return 0; @@ -1361,9 +1370,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; - if (yi->track_osd) - fb->flags |= V4L2_FBUF_FLAG_OVERLAY; - pixfmt &= 7; /* no local alpha for RGB565 or unknown formats */ @@ -1383,6 +1389,8 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) else fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; } + if (yi->track_osd) + fb->flags |= V4L2_FBUF_FLAG_OVERLAY; return 0; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-irq.c b/trunk/drivers/media/video/ivtv/ivtv-irq.c index f5d00ec5da73..34f3ab827858 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-irq.c +++ b/trunk/drivers/media/video/ivtv/ivtv-irq.c @@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) */ unsigned int frame = read_reg(0x28c0) & 1; struct yuv_playback_info *yi = &itv->yuv_info; - int last_dma_frame = atomic_read(&yi->next_dma_frame); + int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame); struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); @@ -772,7 +772,6 @@ static void ivtv_irq_vsync(struct ivtv *itv) next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; atomic_set(&yi->next_dma_frame, next_dma_frame); yi->fields_lapsed = -1; - yi->running = 1; } } } @@ -805,11 +804,9 @@ static void ivtv_irq_vsync(struct ivtv *itv) } /* Check if we need to update the yuv registers */ - if (yi->running && (yi->yuv_forced_update || f->update)) { + if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) { if (!f->update) { - last_dma_frame = - (u8)(atomic_read(&yi->next_dma_frame) - - 1) % IVTV_YUV_BUFFERS; + last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS; f = &yi->new_frame_info[last_dma_frame]; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-streams.c b/trunk/drivers/media/video/ivtv/ivtv-streams.c index 5bbf31e39304..730e85d86fc8 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-streams.c +++ b/trunk/drivers/media/video/ivtv/ivtv-streams.c @@ -75,7 +75,7 @@ static const struct file_operations ivtv_v4l2_dec_fops = { static struct { const char *name; int vfl_type; - int num_offset; + int minor_offset; int dma, pio; enum v4l2_buf_type buf_type; const struct file_operations *fops; @@ -171,8 +171,8 @@ static void ivtv_stream_init(struct ivtv *itv, int type) static int ivtv_prep_dev(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; - int num_offset = ivtv_stream_info[type].num_offset; - int num = itv->num + ivtv_first_minor + num_offset; + int minor_offset = ivtv_stream_info[type].minor_offset; + int minor; /* These four fields are always initialized. If v4l2dev == NULL, then this stream is not in use. In that case no other fields but these @@ -188,6 +188,9 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return 0; + /* card number + user defined offset + device offset */ + minor = itv->num + ivtv_first_minor + minor_offset; + /* User explicitly selected 0 buffers for these streams, so don't create them. */ if (ivtv_stream_info[type].dma != PCI_DMA_NONE && @@ -208,7 +211,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", itv->num, s->name); - s->v4l2dev->num = num; + s->v4l2dev->minor = minor; s->v4l2dev->parent = &itv->dev->dev; s->v4l2dev->fops = ivtv_stream_info[type].fops; s->v4l2dev->release = video_device_release; @@ -247,46 +250,39 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; int vfl_type = ivtv_stream_info[type].vfl_type; - int num; + int minor; if (s->v4l2dev == NULL) return 0; - num = s->v4l2dev->num; - /* card number + user defined offset + device offset */ - if (type != IVTV_ENC_STREAM_TYPE_MPG) { - struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; - - if (s_mpg->v4l2dev) - num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset; - } - + minor = s->v4l2dev->minor; /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, num)) { - IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", - s->name, num); + if (video_register_device(s->v4l2dev, vfl_type, minor) && + video_register_device(s->v4l2dev, vfl_type, -1)) { + IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", + s->name, minor); video_device_release(s->v4l2dev); s->v4l2dev = NULL; return -ENOMEM; } - num = s->v4l2dev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: IVTV_INFO("Registered device video%d for %s (%d kB)\n", - num, s->name, itv->options.kilobytes[type]); + s->v4l2dev->minor, s->name, itv->options.kilobytes[type]); break; case VFL_TYPE_RADIO: IVTV_INFO("Registered device radio%d for %s\n", - num, s->name); + s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); break; case VFL_TYPE_VBI: if (itv->options.kilobytes[type]) IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", - num, s->name, itv->options.kilobytes[type]); + s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, + s->name, itv->options.kilobytes[type]); else IVTV_INFO("Registered device vbi%d for %s\n", - num, s->name); + s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name); break; } return 0; @@ -334,7 +330,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister) static void ivtv_vbi_setup(struct ivtv *itv) { - int raw = ivtv_raw_vbi(itv); + int raw = itv->vbi.sliced_in->service_set == 0; u32 data[CX2341X_MBOX_MAX_DATA]; int lines; int i; diff --git a/trunk/drivers/media/video/ivtv/ivtv-vbi.c b/trunk/drivers/media/video/ivtv/ivtv-vbi.c index 4a37a7d2e69d..1ce9deb1104f 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-vbi.c +++ b/trunk/drivers/media/video/ivtv/ivtv-vbi.c @@ -334,7 +334,7 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, int y; /* Raw VBI data */ - if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) { + if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) { u8 type; ivtv_buf_swap(buf); diff --git a/trunk/drivers/media/video/ivtv/ivtv-yuv.c b/trunk/drivers/media/video/ivtv/ivtv-yuv.c index ee91107376c7..3092ff1d00a0 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-yuv.c +++ b/trunk/drivers/media/video/ivtv/ivtv-yuv.c @@ -1147,7 +1147,6 @@ void ivtv_yuv_close(struct ivtv *itv) IVTV_DEBUG_YUV("ivtv_yuv_close\n"); ivtv_waitq(&itv->vsync_waitq); - yi->running = 0; atomic_set(&yi->next_dma_frame, -1); atomic_set(&yi->next_fill_frame, 0); diff --git a/trunk/drivers/media/video/ivtv/ivtvfb.c b/trunk/drivers/media/video/ivtv/ivtvfb.c index 8a4a150b12fb..bdfda48e56bf 100644 --- a/trunk/drivers/media/video/ivtv/ivtvfb.c +++ b/trunk/drivers/media/video/ivtv/ivtvfb.c @@ -275,6 +275,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, int size_in_bytes) { DEFINE_WAIT(wait); + int ret = 0; int got_sig = 0; mutex_lock(&itv->udma.lock); @@ -315,7 +316,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, return -EINTR; } - return 0; + return ret; } static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, @@ -367,12 +368,11 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, } static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { unsigned long p = *ppos; void *dst; int err = 0; - int dma_err; unsigned long total_size; struct ivtv *itv = (struct ivtv *) info->par; unsigned long dma_offset = @@ -399,6 +399,7 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, if (count + p > total_size) { if (!err) err = -ENOSPC; + count = total_size - p; } @@ -407,34 +408,39 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, if (info->fbops->fb_sync) info->fbops->fb_sync(info); - /* If transfer size > threshold and both src/dst - addresses are aligned, use DMA */ - if (count >= 4096 && - ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { - /* Odd address = can't DMA. Align */ - if ((unsigned long)dst & 3) { - lead = 4 - ((unsigned long)dst & 3); - if (copy_from_user(dst, buf, lead)) - return -EFAULT; - buf += lead; - dst += lead; + if (!access_ok(VERIFY_READ, buf, count)) { + IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", + (unsigned long)buf); + err = -EFAULT; + } + + if (!err) { + /* If transfer size > threshold and both src/dst + addresses are aligned, use DMA */ + if (count >= 4096 && + ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { + /* Odd address = can't DMA. Align */ + if ((unsigned long)dst & 3) { + lead = 4 - ((unsigned long)dst & 3); + memcpy(dst, buf, lead); + buf += lead; + dst += lead; + } + /* DMA resolution is 32 bits */ + if ((count - lead) & 3) + tail = (count - lead) & 3; + /* DMA the data */ + dma_size = count - lead - tail; + err = ivtvfb_prep_dec_dma_to_device(itv, + p + lead + dma_offset, (void *)buf, dma_size); + dst += dma_size; + buf += dma_size; + /* Copy any leftover data */ + if (tail) + memcpy(dst, buf, tail); + } else { + memcpy(dst, buf, count); } - /* DMA resolution is 32 bits */ - if ((count - lead) & 3) - tail = (count - lead) & 3; - /* DMA the data */ - dma_size = count - lead - tail; - dma_err = ivtvfb_prep_dec_dma_to_device(itv, - p + lead + dma_offset, (void __user *)buf, dma_size); - if (dma_err) - return dma_err; - dst += dma_size; - buf += dma_size; - /* Copy any leftover data */ - if (tail && copy_from_user(dst, buf, tail)) - return -EFAULT; - } else if (copy_from_user(dst, buf, count)) { - return -EFAULT; } if (!err) @@ -457,12 +463,9 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC; trace = read_reg(0x028c0) >> 16; - if (itv->is_50hz && trace > 312) - trace -= 312; - else if (itv->is_60hz && trace > 262) - trace -= 262; - if (trace == 1) - vblank.flags |= FB_VBLANK_VSYNCING; + if (itv->is_50hz && trace > 312) trace -= 312; + else if (itv->is_60hz && trace > 262) trace -= 262; + if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; vblank.count = itv->last_vsync_field; vblank.vcount = trace; vblank.hcount = 0; @@ -473,8 +476,7 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar case FBIO_WAITFORVSYNC: prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); - if (!schedule_timeout(msecs_to_jiffies(50))) - rc = -ETIMEDOUT; + if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT; finish_wait(&itv->vsync_waitq, &wait); return rc; diff --git a/trunk/drivers/media/video/meye.c b/trunk/drivers/media/video/meye.c index 6418f4a78f2a..a9ef7802eb5f 100644 --- a/trunk/drivers/media/video/meye.c +++ b/trunk/drivers/media/video/meye.c @@ -843,16 +843,17 @@ static irqreturn_t meye_irq(int irq, void *dev_id) static int meye_open(struct inode *inode, struct file *file) { - int i; + int i, err; - if (test_and_set_bit(0, &meye.in_use)) - return -EBUSY; + err = video_exclusive_open(inode, file); + if (err < 0) + return err; mchip_hic_stop(); if (mchip_dma_alloc()) { printk(KERN_ERR "meye: mchip framebuffer allocation failed\n"); - clear_bit(0, &meye.in_use); + video_exclusive_release(inode, file); return -ENOBUFS; } @@ -867,7 +868,7 @@ static int meye_release(struct inode *inode, struct file *file) { mchip_hic_stop(); mchip_dma_free(); - clear_bit(0, &meye.in_use); + video_exclusive_release(inode, file); return 0; } @@ -1773,7 +1774,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev, goto outnotdev; } - ret = -ENOMEM; meye.mchip_dev = pcidev; meye.video_dev = video_device_alloc(); if (!meye.video_dev) { @@ -1781,6 +1781,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev, goto outnotdev; } + ret = -ENOMEM; meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); if (!meye.grab_temp) { printk(KERN_ERR "meye: grab buffer allocation failed\n"); diff --git a/trunk/drivers/media/video/meye.h b/trunk/drivers/media/video/meye.h index 5f70a106ba2b..d535748df445 100644 --- a/trunk/drivers/media/video/meye.h +++ b/trunk/drivers/media/video/meye.h @@ -311,7 +311,6 @@ struct meye { struct video_device *video_dev; /* video device parameters */ struct video_picture picture; /* video picture parameters */ struct meye_params params; /* additional parameters */ - unsigned long in_use; /* set to 1 if the device is in use */ #ifdef CONFIG_PM u8 pm_mchip_mode; /* old mchip mode */ #endif diff --git a/trunk/drivers/media/video/mt9m001.c b/trunk/drivers/media/video/mt9m001.c index 0c524376b67e..554d2295484e 100644 --- a/trunk/drivers/media/video/mt9m001.c +++ b/trunk/drivers/media/video/mt9m001.c @@ -117,51 +117,24 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9m001_init(struct soc_camera_device *icd) { - struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); - struct soc_camera_link *icl = mt9m001->client->dev.platform_data; int ret; + /* Disable chip, synchronous option update */ dev_dbg(icd->vdev->parent, "%s\n", __func__); - if (icl->power) { - ret = icl->power(&mt9m001->client->dev, 1); - if (ret < 0) { - dev_err(icd->vdev->parent, - "Platform failed to power-on the camera.\n"); - return ret; - } - } - - /* The camera could have been already on, we reset it additionally */ - if (icl->reset) - ret = icl->reset(&mt9m001->client->dev); - else - ret = -ENODEV; - - if (ret < 0) { - /* Either no platform reset, or platform reset failed */ - ret = reg_write(icd, MT9M001_RESET, 1); - if (!ret) - ret = reg_write(icd, MT9M001_RESET, 0); - } - /* Disable chip, synchronous option update */ - if (!ret) + ret = reg_write(icd, MT9M001_RESET, 1); + if (ret >= 0) + ret = reg_write(icd, MT9M001_RESET, 0); + if (ret >= 0) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); - return ret; + return ret >= 0 ? 0 : -EIO; } static int mt9m001_release(struct soc_camera_device *icd) { - struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); - struct soc_camera_link *icl = mt9m001->client->dev.platform_data; - /* Disable the chip */ reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); - - if (icl->power) - icl->power(&mt9m001->client->dev, 0); - return 0; } @@ -294,24 +267,24 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, /* Blanking and start values - default... */ ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); /* The caller provides a supported format, as verified per * call to icd->try_fmt_cap() */ - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9M001_ROW_START, rect->top); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, rect->height + icd->y_skip_top - 1); - if (!ret && mt9m001->autoexposure) { + if (ret >= 0 && mt9m001->autoexposure) { ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, rect->height + icd->y_skip_top + vblank); - if (!ret) { + if (ret >= 0) { const struct v4l2_queryctrl *qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); @@ -322,7 +295,7 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, } } - return ret; + return ret < 0 ? ret : 0; } static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, diff --git a/trunk/drivers/media/video/mt9m111.c b/trunk/drivers/media/video/mt9m111.c deleted file mode 100644 index da0b2d553fd0..000000000000 --- a/trunk/drivers/media/video/mt9m111.c +++ /dev/null @@ -1,973 +0,0 @@ -/* - * Driver for MT9M111 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Robert Jarzmik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * mt9m111 i2c address is 0x5d or 0x48 (depending on SAddr pin) - * The platform has to define i2c_board_info and call i2c_register_board_info() - */ - -/* mt9m111: Sensor register addresses */ -#define MT9M111_CHIP_VERSION 0x000 -#define MT9M111_ROW_START 0x001 -#define MT9M111_COLUMN_START 0x002 -#define MT9M111_WINDOW_HEIGHT 0x003 -#define MT9M111_WINDOW_WIDTH 0x004 -#define MT9M111_HORIZONTAL_BLANKING_B 0x005 -#define MT9M111_VERTICAL_BLANKING_B 0x006 -#define MT9M111_HORIZONTAL_BLANKING_A 0x007 -#define MT9M111_VERTICAL_BLANKING_A 0x008 -#define MT9M111_SHUTTER_WIDTH 0x009 -#define MT9M111_ROW_SPEED 0x00a -#define MT9M111_EXTRA_DELAY 0x00b -#define MT9M111_SHUTTER_DELAY 0x00c -#define MT9M111_RESET 0x00d -#define MT9M111_READ_MODE_B 0x020 -#define MT9M111_READ_MODE_A 0x021 -#define MT9M111_FLASH_CONTROL 0x023 -#define MT9M111_GREEN1_GAIN 0x02b -#define MT9M111_BLUE_GAIN 0x02c -#define MT9M111_RED_GAIN 0x02d -#define MT9M111_GREEN2_GAIN 0x02e -#define MT9M111_GLOBAL_GAIN 0x02f -#define MT9M111_CONTEXT_CONTROL 0x0c8 -#define MT9M111_PAGE_MAP 0x0f0 -#define MT9M111_BYTE_WISE_ADDR 0x0f1 - -#define MT9M111_RESET_SYNC_CHANGES (1 << 15) -#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9) -#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8) -#define MT9M111_RESET_RESET_SOC (1 << 5) -#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4) -#define MT9M111_RESET_CHIP_ENABLE (1 << 3) -#define MT9M111_RESET_ANALOG_STANDBY (1 << 2) -#define MT9M111_RESET_RESTART_FRAME (1 << 1) -#define MT9M111_RESET_RESET_MODE (1 << 0) - -#define MT9M111_RMB_MIRROR_COLS (1 << 1) -#define MT9M111_RMB_MIRROR_ROWS (1 << 0) -#define MT9M111_CTXT_CTRL_RESTART (1 << 15) -#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12) -#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10) -#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9) -#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8) -#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7) -#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3) -#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2) -#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1) -#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0) -/* - * mt9m111: Colorpipe register addresses (0x100..0x1ff) - */ -#define MT9M111_OPER_MODE_CTRL 0x106 -#define MT9M111_OUTPUT_FORMAT_CTRL 0x108 -#define MT9M111_REDUCER_XZOOM_B 0x1a0 -#define MT9M111_REDUCER_XSIZE_B 0x1a1 -#define MT9M111_REDUCER_YZOOM_B 0x1a3 -#define MT9M111_REDUCER_YSIZE_B 0x1a4 -#define MT9M111_REDUCER_XZOOM_A 0x1a6 -#define MT9M111_REDUCER_XSIZE_A 0x1a7 -#define MT9M111_REDUCER_YZOOM_A 0x1a9 -#define MT9M111_REDUCER_YSIZE_A 0x1aa - -#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a -#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b - -#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14) - - -#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14) -#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) -#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) -#define MT9M111_OUTFMT_RGB (1 << 8) -#define MT9M111_OUTFMT_RGB565 (0x0 << 6) -#define MT9M111_OUTFMT_RGB555 (0x1 << 6) -#define MT9M111_OUTFMT_RGB444x (0x2 << 6) -#define MT9M111_OUTFMT_RGBx444 (0x3 << 6) -#define MT9M111_OUTFMT_TST_RAMP_OFF (0x0 << 4) -#define MT9M111_OUTFMT_TST_RAMP_COL (0x1 << 4) -#define MT9M111_OUTFMT_TST_RAMP_ROW (0x2 << 4) -#define MT9M111_OUTFMT_TST_RAMP_FRAME (0x3 << 4) -#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) -#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) -#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) -#define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 << 1) -#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr (1 << 0) -/* - * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) - */ - -#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) -#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) -#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) -#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) - -#define MT9M111_MIN_DARK_ROWS 8 -#define MT9M111_MIN_DARK_COLS 24 -#define MT9M111_MAX_HEIGHT 1024 -#define MT9M111_MAX_WIDTH 1280 - -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } -#define RGB_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) - -static const struct soc_camera_data_format mt9m111_colour_formats[] = { - COL_FMT("YCrYCb 8 bit", 8, V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_JPEG), - RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), - RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), - RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), - RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), -}; - -enum mt9m111_context { - HIGHPOWER = 0, - LOWPOWER, -}; - -struct mt9m111 { - struct i2c_client *client; - struct soc_camera_device icd; - int model; /* V4L2_IDENT_MT9M111* codes from v4l2-chip-ident.h */ - enum mt9m111_context context; - unsigned int left, top, width, height; - u32 pixfmt; - unsigned char autoexposure; - unsigned char datawidth; - unsigned int powered:1; - unsigned int hflip:1; - unsigned int vflip:1; - unsigned int swap_rgb_even_odd:1; - unsigned int swap_rgb_red_blue:1; - unsigned int swap_yuv_y_chromas:1; - unsigned int swap_yuv_cb_cr:1; -}; - -static int reg_page_map_set(struct i2c_client *client, const u16 reg) -{ - int ret; - u16 page; - static int lastpage = -1; /* PageMap cache value */ - - page = (reg >> 8); - if (page == lastpage) - return 0; - if (page > 2) - return -EINVAL; - - ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); - if (!ret) - lastpage = page; - return ret; -} - -static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - struct i2c_client *client = mt9m111->client; - int ret; - - ret = reg_page_map_set(client, reg); - if (!ret) - ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); - - dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); - return ret; -} - -static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, - const u16 data) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - struct i2c_client *client = mt9m111->client; - int ret; - - ret = reg_page_map_set(client, reg); - if (!ret) - ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), - swab16(data)); - dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); - return ret; -} - -static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, - const u16 data) -{ - int ret; - - ret = mt9m111_reg_read(icd, reg); - if (ret >= 0) - ret = mt9m111_reg_write(icd, reg, ret | data); - return ret; -} - -static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, - const u16 data) -{ - int ret; - - ret = mt9m111_reg_read(icd, reg); - return mt9m111_reg_write(icd, reg, ret & ~data); -} - -static int mt9m111_set_context(struct soc_camera_device *icd, - enum mt9m111_context ctxt) -{ - int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B - | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B - | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B - | MT9M111_CTXT_CTRL_VBLANK_SEL_B - | MT9M111_CTXT_CTRL_HBLANK_SEL_B; - int valA = MT9M111_CTXT_CTRL_RESTART; - - if (ctxt == HIGHPOWER) - return reg_write(CONTEXT_CONTROL, valB); - else - return reg_write(CONTEXT_CONTROL, valA); -} - -static int mt9m111_setup_rect(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret, is_raw_format; - int width = mt9m111->width; - int height = mt9m111->height; - - if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) - || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) - is_raw_format = 1; - else - is_raw_format = 0; - - ret = reg_write(COLUMN_START, mt9m111->left); - if (!ret) - ret = reg_write(ROW_START, mt9m111->top); - - if (is_raw_format) { - if (!ret) - ret = reg_write(WINDOW_WIDTH, width); - if (!ret) - ret = reg_write(WINDOW_HEIGHT, height); - } else { - if (!ret) - ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); - if (!ret) - ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); - if (!ret) - ret = reg_write(REDUCER_XSIZE_B, width); - if (!ret) - ret = reg_write(REDUCER_YSIZE_B, height); - if (!ret) - ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); - if (!ret) - ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); - if (!ret) - ret = reg_write(REDUCER_XSIZE_A, width); - if (!ret) - ret = reg_write(REDUCER_YSIZE_A, height); - } - - return ret; -} - -static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) -{ - int ret; - - ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); - if (!ret) - ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); - return ret; -} - -static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) -{ - return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); -} - -static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) -{ - return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); -} - -static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int val = 0; - - if (mt9m111->swap_rgb_red_blue) - val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; - if (mt9m111->swap_rgb_even_odd) - val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; - val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; - - return mt9m111_setup_pixfmt(icd, val); -} - -static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int val = 0; - - if (mt9m111->swap_rgb_red_blue) - val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; - if (mt9m111->swap_rgb_even_odd) - val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; - val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; - - return mt9m111_setup_pixfmt(icd, val); -} - -static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int val = 0; - - if (mt9m111->swap_yuv_cb_cr) - val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; - if (mt9m111->swap_yuv_y_chromas) - val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; - - return mt9m111_setup_pixfmt(icd, val); -} - -static int mt9m111_enable(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - struct soc_camera_link *icl = mt9m111->client->dev.platform_data; - int ret; - - if (icl->power) { - ret = icl->power(&mt9m111->client->dev, 1); - if (ret < 0) { - dev_err(icd->vdev->parent, - "Platform failed to power-on the camera.\n"); - return ret; - } - } - - ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); - if (!ret) - mt9m111->powered = 1; - return ret; -} - -static int mt9m111_disable(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - struct soc_camera_link *icl = mt9m111->client->dev.platform_data; - int ret; - - ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); - if (!ret) - mt9m111->powered = 0; - - if (icl->power) - icl->power(&mt9m111->client->dev, 0); - - return ret; -} - -static int mt9m111_reset(struct soc_camera_device *icd) -{ - int ret; - - ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); - if (!ret) - ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); - if (!ret) - ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE - | MT9M111_RESET_RESET_SOC); - return ret; -} - -static int mt9m111_start_capture(struct soc_camera_device *icd) -{ - return 0; -} - -static int mt9m111_stop_capture(struct soc_camera_device *icd) -{ - return 0; -} - -static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) -{ - return SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | - SOCAM_DATAWIDTH_8; -} - -static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) -{ - return 0; -} - -static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret; - - switch (pixfmt) { - case V4L2_PIX_FMT_SBGGR8: - ret = mt9m111_setfmt_bayer8(icd); - break; - case V4L2_PIX_FMT_SBGGR16: - ret = mt9m111_setfmt_bayer10(icd); - break; - case V4L2_PIX_FMT_RGB555: - ret = mt9m111_setfmt_rgb555(icd); - break; - case V4L2_PIX_FMT_RGB565: - ret = mt9m111_setfmt_rgb565(icd); - break; - case V4L2_PIX_FMT_YUYV: - ret = mt9m111_setfmt_yuv(icd); - break; - default: - dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); - ret = -EINVAL; - } - - if (!ret) - mt9m111->pixfmt = pixfmt; - - return ret; -} - -static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, - __u32 pixfmt, struct v4l2_rect *rect) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret; - - mt9m111->left = rect->left; - mt9m111->top = rect->top; - mt9m111->width = rect->width; - mt9m111->height = rect->height; - - dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", - __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, - mt9m111->height); - - ret = mt9m111_setup_rect(icd); - if (!ret) - ret = mt9m111_set_pixfmt(icd, pixfmt); - return ret; -} - -static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - if (f->fmt.pix.height > MT9M111_MAX_HEIGHT) - f->fmt.pix.height = MT9M111_MAX_HEIGHT; - if (f->fmt.pix.width > MT9M111_MAX_WIDTH) - f->fmt.pix.width = MT9M111_MAX_WIDTH; - - return 0; -} - -static int mt9m111_get_chip_id(struct soc_camera_device *icd, - struct v4l2_chip_ident *id) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - - if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match_chip != mt9m111->client->addr) - return -ENODEV; - - id->ident = mt9m111->model; - id->revision = 0; - - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int mt9m111_get_register(struct soc_camera_device *icd, - struct v4l2_register *reg) -{ - int val; - - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) - return -EINVAL; - if (reg->match_chip != mt9m111->client->addr) - return -ENODEV; - - val = mt9m111_reg_read(icd, reg->reg); - reg->val = (u64)val; - - if (reg->val > 0xffff) - return -EIO; - - return 0; -} - -static int mt9m111_set_register(struct soc_camera_device *icd, - struct v4l2_register *reg) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - - if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) - return -EINVAL; - - if (reg->match_chip != mt9m111->client->addr) - return -ENODEV; - - if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) - return -EIO; - - return 0; -} -#endif - -static const struct v4l2_queryctrl mt9m111_controls[] = { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Verticaly", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Horizontaly", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { /* gain = 1/32*val (=>gain=1 if val==32) */ - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 63 * 2 * 2, - .step = 1, - .default_value = 32, - .flags = V4L2_CTRL_FLAG_SLIDER, - }, { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - } -}; - -static int mt9m111_video_probe(struct soc_camera_device *); -static void mt9m111_video_remove(struct soc_camera_device *); -static int mt9m111_get_control(struct soc_camera_device *, - struct v4l2_control *); -static int mt9m111_set_control(struct soc_camera_device *, - struct v4l2_control *); -static int mt9m111_resume(struct soc_camera_device *icd); -static int mt9m111_init(struct soc_camera_device *icd); -static int mt9m111_release(struct soc_camera_device *icd); - -static struct soc_camera_ops mt9m111_ops = { - .owner = THIS_MODULE, - .probe = mt9m111_video_probe, - .remove = mt9m111_video_remove, - .init = mt9m111_init, - .resume = mt9m111_resume, - .release = mt9m111_release, - .start_capture = mt9m111_start_capture, - .stop_capture = mt9m111_stop_capture, - .set_fmt_cap = mt9m111_set_fmt_cap, - .try_fmt_cap = mt9m111_try_fmt_cap, - .query_bus_param = mt9m111_query_bus_param, - .set_bus_param = mt9m111_set_bus_param, - .controls = mt9m111_controls, - .num_controls = ARRAY_SIZE(mt9m111_controls), - .get_control = mt9m111_get_control, - .set_control = mt9m111_set_control, - .get_chip_id = mt9m111_get_chip_id, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .get_register = mt9m111_get_register, - .set_register = mt9m111_set_register, -#endif -}; - -static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret; - - if (mt9m111->context == HIGHPOWER) { - if (flip) - ret = reg_set(READ_MODE_B, mask); - else - ret = reg_clear(READ_MODE_B, mask); - } else { - if (flip) - ret = reg_set(READ_MODE_A, mask); - else - ret = reg_clear(READ_MODE_A, mask); - } - - return ret; -} - -static int mt9m111_get_global_gain(struct soc_camera_device *icd) -{ - unsigned int data, gain; - - data = reg_read(GLOBAL_GAIN); - if (data >= 0) - gain = ((data & (1 << 10)) * 2) - | ((data & (1 << 9)) * 2) - | (data & 0x2f); - else - gain = data; - - return gain; -} -static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) -{ - u16 val; - - if (gain > 63 * 2 * 2) - return -EINVAL; - - icd->gain = gain; - if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) - val = (1 << 10) | (1 << 9) | (gain / 4); - else if ((gain >= 64) && (gain < 64 * 2)) - val = (1 << 9) | (gain / 2); - else - val = gain; - - return reg_write(GLOBAL_GAIN, val); -} - -static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret; - - if (on) - ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); - else - ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); - - if (!ret) - mt9m111->autoexposure = on; - - return ret; -} -static int mt9m111_get_control(struct soc_camera_device *icd, - struct v4l2_control *ctrl) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int data; - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - if (mt9m111->context == HIGHPOWER) - data = reg_read(READ_MODE_B); - else - data = reg_read(READ_MODE_A); - - if (data < 0) - return -EIO; - ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS); - break; - case V4L2_CID_HFLIP: - if (mt9m111->context == HIGHPOWER) - data = reg_read(READ_MODE_B); - else - data = reg_read(READ_MODE_A); - - if (data < 0) - return -EIO; - ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); - break; - case V4L2_CID_GAIN: - data = mt9m111_get_global_gain(icd); - if (data < 0) - return data; - ctrl->value = data; - break; - case V4L2_CID_EXPOSURE_AUTO: - ctrl->value = mt9m111->autoexposure; - break; - } - return 0; -} - -static int mt9m111_set_control(struct soc_camera_device *icd, - struct v4l2_control *ctrl) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - const struct v4l2_queryctrl *qctrl; - int ret; - - qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); - - if (!qctrl) - return -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - mt9m111->vflip = ctrl->value; - ret = mt9m111_set_flip(icd, ctrl->value, - MT9M111_RMB_MIRROR_ROWS); - break; - case V4L2_CID_HFLIP: - mt9m111->hflip = ctrl->value; - ret = mt9m111_set_flip(icd, ctrl->value, - MT9M111_RMB_MIRROR_COLS); - break; - case V4L2_CID_GAIN: - ret = mt9m111_set_global_gain(icd, ctrl->value); - break; - case V4L2_CID_EXPOSURE_AUTO: - ret = mt9m111_set_autoexposure(icd, ctrl->value); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int mt9m111_restore_state(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - - mt9m111_set_context(icd, mt9m111->context); - mt9m111_set_pixfmt(icd, mt9m111->pixfmt); - mt9m111_setup_rect(icd); - mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); - mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); - mt9m111_set_global_gain(icd, icd->gain); - mt9m111_set_autoexposure(icd, mt9m111->autoexposure); - return 0; -} - -static int mt9m111_resume(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; - - if (mt9m111->powered) { - ret = mt9m111_enable(icd); - if (!ret) - ret = mt9m111_reset(icd); - if (!ret) - ret = mt9m111_restore_state(icd); - } - return ret; -} - -static int mt9m111_init(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret; - - mt9m111->context = HIGHPOWER; - ret = mt9m111_enable(icd); - if (!ret) - ret = mt9m111_reset(icd); - if (!ret) - ret = mt9m111_set_context(icd, mt9m111->context); - if (!ret) - ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); - if (ret) - dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); - return ret; -} - -static int mt9m111_release(struct soc_camera_device *icd) -{ - int ret; - - ret = mt9m111_disable(icd); - if (ret < 0) - dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); - - return ret; -} - -/* - * Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one - */ -static int mt9m111_video_probe(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - s32 data; - int ret; - - /* - * We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. - */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - ret = mt9m111_enable(icd); - if (ret) - goto ei2c; - ret = mt9m111_reset(icd); - if (ret) - goto ei2c; - - data = reg_read(CHIP_VERSION); - - switch (data) { - case 0x143a: - mt9m111->model = V4L2_IDENT_MT9M111; - icd->formats = mt9m111_colour_formats; - icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); - break; - default: - ret = -ENODEV; - dev_err(&icd->dev, - "No MT9M111 chip detected, register read %x\n", data); - goto ei2c; - } - - dev_info(&icd->dev, "Detected a MT9M111 chip ID 0x143a\n"); - - ret = soc_camera_video_start(icd); - if (ret) - goto eisis; - - mt9m111->autoexposure = 1; - - mt9m111->swap_rgb_even_odd = 1; - mt9m111->swap_rgb_red_blue = 1; - - return 0; -eisis: -ei2c: - return ret; -} - -static void mt9m111_video_remove(struct soc_camera_device *icd) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - - dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, - mt9m111->icd.dev.parent, mt9m111->icd.vdev); - soc_camera_video_stop(&mt9m111->icd); -} - -static int mt9m111_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct mt9m111 *mt9m111; - struct soc_camera_device *icd; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl = client->dev.platform_data; - int ret; - - if (!icl) { - dev_err(&client->dev, "MT9M111 driver needs platform data\n"); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); - return -EIO; - } - - mt9m111 = kzalloc(sizeof(struct mt9m111), GFP_KERNEL); - if (!mt9m111) - return -ENOMEM; - - mt9m111->client = client; - i2c_set_clientdata(client, mt9m111); - - /* Second stage probe - when a capture adapter is there */ - icd = &mt9m111->icd; - icd->ops = &mt9m111_ops; - icd->control = &client->dev; - icd->x_min = MT9M111_MIN_DARK_COLS; - icd->y_min = MT9M111_MIN_DARK_ROWS; - icd->x_current = icd->x_min; - icd->y_current = icd->y_min; - icd->width_min = MT9M111_MIN_DARK_ROWS; - icd->width_max = MT9M111_MAX_WIDTH; - icd->height_min = MT9M111_MIN_DARK_COLS; - icd->height_max = MT9M111_MAX_HEIGHT; - icd->y_skip_top = 0; - icd->iface = icl->bus_id; - - ret = soc_camera_device_register(icd); - if (ret) - goto eisdr; - return 0; - -eisdr: - kfree(mt9m111); - return ret; -} - -static int mt9m111_remove(struct i2c_client *client) -{ - struct mt9m111 *mt9m111 = i2c_get_clientdata(client); - soc_camera_device_unregister(&mt9m111->icd); - kfree(mt9m111); - - return 0; -} - -static const struct i2c_device_id mt9m111_id[] = { - { "mt9m111", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, mt9m111_id); - -static struct i2c_driver mt9m111_i2c_driver = { - .driver = { - .name = "mt9m111", - }, - .probe = mt9m111_probe, - .remove = mt9m111_remove, - .id_table = mt9m111_id, -}; - -static int __init mt9m111_mod_init(void) -{ - return i2c_add_driver(&mt9m111_i2c_driver); -} - -static void __exit mt9m111_mod_exit(void) -{ - i2c_del_driver(&mt9m111_i2c_driver); -} - -module_init(mt9m111_mod_init); -module_exit(mt9m111_mod_exit); - -MODULE_DESCRIPTION("Micron MT9M111 Camera driver"); -MODULE_AUTHOR("Robert Jarzmik"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/mt9v022.c b/trunk/drivers/media/video/mt9v022.c index 2584201059d8..56808cd2f8a9 100644 --- a/trunk/drivers/media/video/mt9v022.c +++ b/trunk/drivers/media/video/mt9v022.c @@ -134,56 +134,34 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9v022_init(struct soc_camera_device *icd) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - struct soc_camera_link *icl = mt9v022->client->dev.platform_data; int ret; - if (icl->power) { - ret = icl->power(&mt9v022->client->dev, 1); - if (ret < 0) { - dev_err(icd->vdev->parent, - "Platform failed to power-on the camera.\n"); - return ret; - } - } - - /* - * The camera could have been already on, we hard-reset it additionally, - * if available. Soft reset is done in video_probe(). - */ - if (icl->reset) - icl->reset(&mt9v022->client->dev); - /* Almost the default mode: master, parallel, simultaneous, and an * undocumented bit 0x200, which is present in table 7, but not in 8, * plus snapshot mode to disable scan for now */ mt9v022->chip_control |= 0x10; ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); - if (!ret) - ret = reg_write(icd, MT9V022_READ_MODE, 0x300); + if (ret >= 0) + reg_write(icd, MT9V022_READ_MODE, 0x300); /* All defaults */ - if (!ret) + if (ret >= 0) /* AEC, AGC on */ ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); - if (!ret) + if (ret >= 0) /* default - auto */ ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); - return ret; + return ret >= 0 ? 0 : -EIO; } static int mt9v022_release(struct soc_camera_device *icd) { - struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - struct soc_camera_link *icl = mt9v022->client->dev.platform_data; - - if (icl->power) - icl->power(&mt9v022->client->dev, 0); - + /* Nothing? */ return 0; } @@ -374,21 +352,21 @@ static int mt9v022_set_fmt_cap(struct soc_camera_device *icd, rect->height + icd->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_ROW_START, rect->top); - if (!ret) + if (ret >= 0) /* Default 94, Phytec driver says: * "width + horizontal blank >= 660" */ ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, rect->width > 660 - 43 ? 43 : 660 - rect->width); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); - if (!ret) + if (ret >= 0) ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, rect->height + icd->y_skip_top); @@ -739,7 +717,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) icd->num_formats = 1; } - if (!ret) + if (ret >= 0) ret = soc_camera_video_start(icd); if (ret < 0) goto eisis; diff --git a/trunk/drivers/media/video/mxb.c b/trunk/drivers/media/video/mxb.c index 7f130284b5c7..8ef578caba3b 100644 --- a/trunk/drivers/media/video/mxb.c +++ b/trunk/drivers/media/video/mxb.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "mxb.h" #include "tea6415c.h" @@ -123,8 +122,6 @@ static struct saa7146_extension_ioctls ioctls[] = { { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, - { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE }, - { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE }, { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */ { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */ { 0, 0 } @@ -137,12 +134,12 @@ struct mxb struct i2c_adapter i2c_adapter; - struct i2c_client *saa7111a; - struct i2c_client *tda9840; - struct i2c_client *tea6415c; - struct i2c_client *tuner; - struct i2c_client *tea6420_1; - struct i2c_client *tea6420_2; + struct i2c_client* saa7111a; + struct i2c_client* tda9840; + struct i2c_client* tea6415c; + struct i2c_client* tuner; + struct i2c_client* tea6420_1; + struct i2c_client* tea6420_2; int cur_mode; /* current audio mode (mono, stereo, ...) */ int cur_input; /* current input */ @@ -154,23 +151,23 @@ static struct saa7146_extension extension; static int mxb_check_clients(struct device *dev, void *data) { - struct mxb *mxb = data; + struct mxb* mxb = data; struct i2c_client *client = i2c_verify_client(dev); - if (!client) + if( !client ) return 0; - if (I2C_ADDR_TEA6420_1 == client->addr) + if( I2C_ADDR_TEA6420_1 == client->addr ) mxb->tea6420_1 = client; - if (I2C_ADDR_TEA6420_2 == client->addr) + if( I2C_ADDR_TEA6420_2 == client->addr ) mxb->tea6420_2 = client; - if (I2C_TEA6415C_2 == client->addr) + if( I2C_TEA6415C_2 == client->addr ) mxb->tea6415c = client; - if (I2C_ADDR_TDA9840 == client->addr) + if( I2C_ADDR_TDA9840 == client->addr ) mxb->tda9840 = client; - if (I2C_SAA7111 == client->addr) + if( I2C_SAA7111 == client->addr ) mxb->saa7111a = client; - if (0x60 == client->addr) + if( 0x60 == client->addr ) mxb->tuner = client; return 0; @@ -181,28 +178,23 @@ static int mxb_probe(struct saa7146_dev* dev) struct mxb* mxb = NULL; int result; - result = request_module("saa7115"); - if (result < 0) { + if ((result = request_module("saa7111")) < 0) { printk("mxb: saa7111 i2c module not available.\n"); return -ENODEV; } - result = request_module("tea6420"); - if (result < 0) { + if ((result = request_module("tea6420")) < 0) { printk("mxb: tea6420 i2c module not available.\n"); return -ENODEV; } - result = request_module("tea6415c"); - if (result < 0) { + if ((result = request_module("tea6415c")) < 0) { printk("mxb: tea6415c i2c module not available.\n"); return -ENODEV; } - result = request_module("tda9840"); - if (result < 0) { + if ((result = request_module("tda9840")) < 0) { printk("mxb: tda9840 i2c module not available.\n"); return -ENODEV; } - result = request_module("tuner"); - if (result < 0) { + if ((result = request_module("tuner")) < 0) { printk("mxb: tuner i2c module not available.\n"); return -ENODEV; } @@ -215,10 +207,9 @@ static int mxb_probe(struct saa7146_dev* dev) mxb->i2c_adapter = (struct i2c_adapter) { .class = I2C_CLASS_TV_ANALOG, + .name = "mxb", }; - snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); - saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); if(i2c_add_adapter(&mxb->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); @@ -299,7 +290,38 @@ static struct { { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } }, { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } }, { 3, { 0x80, 0xb3, 0x0a } }, - {-1, { 0 } } + {-1, { 0} } +}; + +static const unsigned char mxb_saa7111_init[] = { + 0x00, 0x00, /* 00 - ID byte */ + 0x01, 0x00, /* 01 - reserved */ + + /*front end */ + 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */ + 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ + 0x04, 0x00, /* 04 - GAI1=256 */ + 0x05, 0x00, /* 05 - GAI2=256 */ + + /* decoder */ + 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */ + 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */ + 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */ + 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */ + 0x0a, 0x80, /* 0a - BRIG=128 */ + 0x0b, 0x47, /* 0b - CONT=1.109 */ + 0x0c, 0x40, /* 0c - SATN=1.0 */ + 0x0d, 0x00, /* 0d - HUE=0 */ + 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */ + 0x0f, 0x00, /* 0f - reserved */ + 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */ + 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */ + 0x12, 0x80, /* 12 - xx output control 2 */ + 0x13, 0x30, /* 13 - xx output control 3 */ + 0x14, 0x00, /* 14 - reserved */ + 0x15, 0x15, /* 15 - VBI */ + 0x16, 0x04, /* 16 - VBI */ + 0x17, 0x00, /* 17 - VBI */ }; /* bring hardware to a sane state. this has to be done, just in case someone @@ -309,28 +331,37 @@ static struct { static int mxb_init_done(struct saa7146_dev* dev) { struct mxb* mxb = (struct mxb*)dev->ext_priv; + struct video_decoder_init init; struct i2c_msg msg; struct tuner_setup tun_setup; v4l2_std_id std = V4L2_STD_PAL_BG; - struct v4l2_routing route; int i = 0, err = 0; - struct tea6415c_multiplex vm; + struct tea6415c_multiplex vm; /* select video mode in saa7111a */ - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std); + i = VIDEO_MODE_PAL; + /* fixme: currently pointless: gets overwritten by configuration below */ + mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i); + + /* write configuration to saa7111a */ + init.data = mxb_saa7111_init; + init.len = sizeof(mxb_saa7111_init); + mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init); /* select tuner-output on saa7111a */ i = 0; - route.input = SAA7115_COMPOSITE0; - route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS; - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route); + mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i); + + /* enable vbi bypass */ + i = 1; + mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i); /* select a tuner type */ tun_setup.mode_mask = T_ANALOG_TV; tun_setup.addr = ADDR_UNSET; tun_setup.type = TUNER_PHILIPS_PAL; - mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup); + mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup); /* tune in some frequency on tuner */ mxb->cur_freq.tuner = 0; mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV; @@ -342,26 +373,27 @@ static int mxb_init_done(struct saa7146_dev* dev) mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); /* mute audio on tea6420s */ - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]); - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]); + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]); + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]); /* switch to tuner-channel on tea6415c*/ vm.out = 17; vm.in = 3; - mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm); + mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm); /* select tuner-output on multicable on tea6415c*/ vm.in = 3; vm.out = 13; - mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm); + mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm); /* the rest for mxb */ mxb->cur_input = 0; mxb->cur_mute = 1; mxb->cur_mode = V4L2_TUNER_MODE_STEREO; + mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode); /* check if the saa7740 (aka 'sound arena module') is present on the mxb. if so, we must initialize it. due to lack of @@ -372,22 +404,21 @@ static int mxb_init_done(struct saa7146_dev* dev) msg.len = mxb_saa7740_init[0].length; msg.buf = &mxb_saa7740_init[0].data[0]; - err = i2c_transfer(&mxb->i2c_adapter, &msg, 1); - if (err == 1) { + if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) { /* the sound arena module is a pos, that's probably the reason philips refuses to hand out a datasheet for the saa7740... it seems to screw up the i2c bus, so we disable fast irq based i2c transactions here and rely on the slow and safe polling method ... */ extension.flags &= ~SAA7146_USE_I2C_IRQ; - for (i = 1; ; i++) { - if (-1 == mxb_saa7740_init[i].length) + for(i = 1;;i++) { + if( -1 == mxb_saa7740_init[i].length ) { break; + } msg.len = mxb_saa7740_init[i].length; msg.buf = &mxb_saa7740_init[i].data[0]; - err = i2c_transfer(&mxb->i2c_adapter, &msg, 1); - if (err != 1) { + if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) { DEB_D(("failed to initialize 'sound arena module'.\n")); goto err; } @@ -401,8 +432,7 @@ static int mxb_init_done(struct saa7146_dev* dev) /* ext->saa has been filled by the core driver */ /* some stuff is done via variables */ - saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, - input_port_selection[mxb->cur_input].hps_sync); + saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync); /* some stuff is done via direct write to the registers */ @@ -427,24 +457,24 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask) static struct saa7146_ext_vv vv_data; /* this function only gets called when the probing was successful */ -static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) +static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { - struct mxb *mxb = (struct mxb *)dev->ext_priv; + struct mxb* mxb = (struct mxb*)dev->ext_priv; - DEB_EE(("dev:%p\n", dev)); + DEB_EE(("dev:%p\n",dev)); /* checking for i2c-devices can be omitted here, because we already did this in "mxb_vl42_probe" */ - saa7146_vv_init(dev, &vv_data); - if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { + saa7146_vv_init(dev,&vv_data); + if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { ERR(("cannot register capture v4l2 device. skipping.\n")); return -1; } /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if (MXB_BOARD_CAN_DO_VBI(dev)) { - if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { + if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { + if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { ERR(("cannot register vbi v4l2 device. skipping.\n")); } } @@ -456,18 +486,18 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data i2c_use_client(mxb->saa7111a); i2c_use_client(mxb->tuner); - printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num); + printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num); mxb_num++; mxb_init_done(dev); return 0; } -static int mxb_detach(struct saa7146_dev *dev) +static int mxb_detach(struct saa7146_dev* dev) { - struct mxb *mxb = (struct mxb *)dev->ext_priv; + struct mxb* mxb = (struct mxb*)dev->ext_priv; - DEB_EE(("dev:%p\n", dev)); + DEB_EE(("dev:%p\n",dev)); i2c_release_client(mxb->tea6420_1); i2c_release_client(mxb->tea6420_2); @@ -477,8 +507,9 @@ static int mxb_detach(struct saa7146_dev *dev) i2c_release_client(mxb->tuner); saa7146_unregister_device(&mxb->video_dev,dev); - if (MXB_BOARD_CAN_DO_VBI(dev)) - saa7146_unregister_device(&mxb->vbi_dev, dev); + if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) { + saa7146_unregister_device(&mxb->vbi_dev,dev); + } saa7146_vv_release(dev); mxb_num--; @@ -492,7 +523,7 @@ static int mxb_detach(struct saa7146_dev *dev) static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct saa7146_dev *dev = fh->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; + struct mxb* mxb = (struct mxb*)dev->ext_priv; struct saa7146_vv *vv = dev->vv_data; switch(cmd) { @@ -501,9 +532,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) struct v4l2_input *i = arg; DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); - if (i->index < 0 || i->index >= MXB_INPUTS) + if( i->index < 0 || i->index >= MXB_INPUTS) { return -EINVAL; + } memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); + return 0; } /* the saa7146 provides some controls (brightness, contrast, saturation) @@ -517,7 +550,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) for (i = MAXCONTROLS - 1; i >= 0; i--) { if (mxb_controls[i].id == qc->id) { *qc = mxb_controls[i]; - DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id)); + DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id)); return 0; } } @@ -529,51 +562,56 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) int i; for (i = MAXCONTROLS - 1; i >= 0; i--) { - if (mxb_controls[i].id == vc->id) + if (mxb_controls[i].id == vc->id) { break; + } } - if (i < 0) + if( i < 0 ) { return -EAGAIN; + } - if (vc->id == V4L2_CID_AUDIO_MUTE) { - vc->value = mxb->cur_mute; - DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); - return 0; + switch (vc->id ) { + case V4L2_CID_AUDIO_MUTE: { + vc->value = mxb->cur_mute; + DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value)); + return 0; + } } - DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); + DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value)); return 0; } case VIDIOC_S_CTRL: { - struct v4l2_control *vc = arg; + struct v4l2_control *vc = arg; int i = 0; for (i = MAXCONTROLS - 1; i >= 0; i--) { - if (mxb_controls[i].id == vc->id) + if (mxb_controls[i].id == vc->id) { break; + } } - if (i < 0) + if( i < 0 ) { return -EAGAIN; + } - if (vc->id == V4L2_CID_AUDIO_MUTE) { - mxb->cur_mute = vc->value; - if (!vc->value) { - /* switch the audio-source */ - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, - &TEA6420_line[video_audio_connect[mxb->cur_input]][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, - &TEA6420_line[video_audio_connect[mxb->cur_input]][1]); - } else { - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, - &TEA6420_line[6][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, - &TEA6420_line[6][1]); + switch (vc->id ) { + case V4L2_CID_AUDIO_MUTE: { + mxb->cur_mute = vc->value; + if( 0 == vc->value ) { + /* switch the audio-source */ + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]); + } else { + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]); + } + DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value)); + break; } - DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value)); } return 0; } @@ -582,84 +620,106 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) int *input = (int *)arg; *input = mxb->cur_input; - DEB_EE(("VIDIOC_G_INPUT %d.\n", *input)); + DEB_EE(("VIDIOC_G_INPUT %d.\n",*input)); return 0; } case VIDIOC_S_INPUT: { int input = *(int *)arg; - struct tea6415c_multiplex vm; - struct v4l2_routing route; + struct tea6415c_multiplex vm; int i = 0; - DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); + DEB_EE(("VIDIOC_S_INPUT %d.\n",input)); - if (input < 0 || input >= MXB_INPUTS) + if (input < 0 || input >= MXB_INPUTS) { return -EINVAL; + } + + /* fixme: locke das setzen des inputs mit hilfe des mutexes + mutex_lock(&dev->lock); + video_mux(dev,*i); + mutex_unlock(&dev->lock); + */ + + /* fixme: check if streaming capture + if ( 0 != dev->streaming ) { + DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n")); + return -EPERM; + } + */ mxb->cur_input = input; - saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, - input_port_selection[input].hps_sync); + saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); /* prepare switching of tea6415c and saa7111a; have a look at the 'background'-file for further informations */ - switch (input) { - case TUNER: - i = SAA7115_COMPOSITE0; - vm.in = 3; - vm.out = 17; - - if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { - printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n"); - return -EFAULT; + switch( input ) { + + case TUNER: + { + i = 0; + vm.in = 3; + vm.out = 17; + + if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) { + printk("VIDIOC_S_INPUT: could not address tea6415c #1\n"); + return -EFAULT; + } + /* connect tuner-output always to multicable */ + vm.in = 3; + vm.out = 13; + break; + } + case AUX3_YC: + { + /* nothing to be done here. aux3_yc is + directly connected to the saa711a */ + i = 5; + break; + } + case AUX3: + { + /* nothing to be done here. aux3 is + directly connected to the saa711a */ + i = 1; + break; + } + case AUX1: + { + i = 0; + vm.in = 1; + vm.out = 17; + break; } - /* connect tuner-output always to multicable */ - vm.in = 3; - vm.out = 13; - break; - case AUX3_YC: - /* nothing to be done here. aux3_yc is - directly connected to the saa711a */ - i = SAA7115_SVIDEO1; - break; - case AUX3: - /* nothing to be done here. aux3 is - directly connected to the saa711a */ - i = SAA7115_COMPOSITE1; - break; - case AUX1: - i = SAA7115_COMPOSITE0; - vm.in = 1; - vm.out = 17; - break; } /* switch video in tea6415c only if necessary */ - switch (input) { - case TUNER: - case AUX1: - if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { - printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n"); - return -EFAULT; + switch( input ) { + case TUNER: + case AUX1: + { + if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) { + printk("VIDIOC_S_INPUT: could not address tea6415c #3\n"); + return -EFAULT; + } + break; + } + default: + { + break; } - break; - default: - break; } /* switch video in saa7111a */ - route.input = i; - route.output = 0; - if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route)) + if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) { printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n"); + } /* switch the audio-source only if necessary */ if( 0 == mxb->cur_mute ) { - mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, - &TEA6420_line[video_audio_connect[input]][0]); - mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, - &TEA6420_line[video_audio_connect[input]][1]); + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]); } return 0; @@ -667,44 +727,114 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) case VIDIOC_G_TUNER: { struct v4l2_tuner *t = arg; + int byte = 0; - if (t->index) { + if( 0 != t->index ) { DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index)); return -EINVAL; } DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); - memset(t, 0, sizeof(*t)); - i2c_clients_command(&mxb->i2c_adapter, cmd, arg); + memset(t,0,sizeof(*t)); + strcpy(t->name, "Television"); - strlcpy(t->name, "TV Tuner", sizeof(t->name)); t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \ - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ + t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ + /* FIXME: add the real signal strength here */ + t->signal = 0xffff; + t->afc = 0; + + mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte); t->audmode = mxb->cur_mode; + + if( byte < 0 ) { + t->rxsubchans = V4L2_TUNER_SUB_MONO; + } else { + switch(byte) { + case TDA9840_MONO_DETECT: { + t->rxsubchans = V4L2_TUNER_SUB_MONO; + DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n")); + break; + } + case TDA9840_DUAL_DETECT: { + t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n")); + break; + } + case TDA9840_STEREO_DETECT: { + t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; + DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n")); + break; + } + default: { /* TDA9840_INCORRECT_DETECT */ + t->rxsubchans = V4L2_TUNER_MODE_MONO; + DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n")); + break; + } + } + } + return 0; } case VIDIOC_S_TUNER: { struct v4l2_tuner *t = arg; + int result = 0; + int byte = 0; - if (t->index) { + if( 0 != t->index ) { DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); return -EINVAL; } - mxb->cur_mode = t->audmode; - i2c_clients_command(&mxb->i2c_adapter, cmd, arg); + switch(t->audmode) { + case V4L2_TUNER_MODE_STEREO: { + mxb->cur_mode = V4L2_TUNER_MODE_STEREO; + byte = TDA9840_SET_STEREO; + DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n")); + break; + } + case V4L2_TUNER_MODE_LANG1_LANG2: { + mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2; + byte = TDA9840_SET_BOTH; + DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n")); + break; + } + case V4L2_TUNER_MODE_LANG1: { + mxb->cur_mode = V4L2_TUNER_MODE_LANG1; + byte = TDA9840_SET_LANG1; + DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n")); + break; + } + case V4L2_TUNER_MODE_LANG2: { + mxb->cur_mode = V4L2_TUNER_MODE_LANG2; + byte = TDA9840_SET_LANG2; + DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n")); + break; + } + default: { /* case V4L2_TUNER_MODE_MONO: {*/ + mxb->cur_mode = V4L2_TUNER_MODE_MONO; + byte = TDA9840_SET_MONO; + DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n")); + break; + } + } + + if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) { + printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte); + } + return 0; } case VIDIOC_G_FREQUENCY: { struct v4l2_frequency *f = arg; - if (mxb->cur_input) { - DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n", - mxb->cur_input)); + if(0 != mxb->cur_input) { + DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input)); return -EINVAL; } @@ -717,14 +847,14 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct v4l2_frequency *f = arg; - if (f->tuner) + if (0 != f->tuner) return -EINVAL; if (V4L2_TUNER_ANALOG_TV != f->type) return -EINVAL; - if (mxb->cur_input) { - DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input)); + if(0 != mxb->cur_input) { + DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input)); return -EINVAL; } @@ -745,7 +875,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { int i = *(int*)arg; - if (i < 0 || i >= MXB_AUDIOS) { + if( i < 0 || i >= MXB_AUDIOS ) { DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); return -EINVAL; } @@ -761,7 +891,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { int i = *(int*)arg; - if (i < 0 || i >= MXB_AUDIOS) { + if( i < 0 || i >= MXB_AUDIOS ) { DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); return -EINVAL; } @@ -776,12 +906,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { struct v4l2_audio *a = arg; - if (a->index < 0 || a->index > MXB_INPUTS) { - DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); + if( a->index < 0 || a->index > MXB_INPUTS ) { + DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index)); return -EINVAL; } - DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index)); + DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index)); memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); return 0; @@ -789,16 +919,9 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) case VIDIOC_S_AUDIO: { struct v4l2_audio *a = arg; - - DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index)); + DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index)); return 0; } -#ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_DBG_S_REGISTER: - case VIDIOC_DBG_G_REGISTER: - i2c_clients_command(&mxb->i2c_adapter, cmd, arg); - return 0; -#endif default: /* DEB2(printk("does not handle this ioctl.\n")); @@ -821,7 +944,7 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* unset the 7111 gpio register -- I don't know what this does exactly */ - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero); + mxb->saa7111a->driver->command(mxb->saa7111a, DECODER_SET_GPIO, &zero); mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); } else { v4l2_std_id std = V4L2_STD_PAL_BG; @@ -830,7 +953,7 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* set the 7111 gpio register -- I don't know what this does exactly */ - mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one); + mxb->saa7111a->driver->command(mxb->saa7111a, DECODER_SET_GPIO, &one); mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); } return 0; @@ -906,7 +1029,7 @@ static struct saa7146_extension extension = { static int __init mxb_init_module(void) { - if (saa7146_register_extension(&extension)) { + if( 0 != saa7146_register_extension(&extension)) { DEB_S(("failed to register extension.\n")); return -ENODEV; } diff --git a/trunk/drivers/media/video/ov511.c b/trunk/drivers/media/video/ov511.c index 935d73de57bd..c6852402c5e9 100644 --- a/trunk/drivers/media/video/ov511.c +++ b/trunk/drivers/media/video/ov511.c @@ -974,14 +974,14 @@ dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) for (i = reg1; i <= regn; i++) { rc = i2c_r(ov, i); - dev_info(&ov->dev->dev, "Sensor[0x%02X] = 0x%02X\n", i, rc); + info("Sensor[0x%02X] = 0x%02X", i, rc); } } static void dump_i2c_regs(struct usb_ov511 *ov) { - dev_info(&ov->dev->dev, "I2C REGS\n"); + info("I2C REGS"); dump_i2c_range(ov, 0x00, 0x7C); } @@ -992,28 +992,28 @@ dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) for (i = reg1; i <= regn; i++) { rc = reg_r(ov, i); - dev_info(&ov->dev->dev, "OV511[0x%02X] = 0x%02X\n", i, rc); + info("OV511[0x%02X] = 0x%02X", i, rc); } } static void ov511_dump_regs(struct usb_ov511 *ov) { - dev_info(&ov->dev->dev, "CAMERA INTERFACE REGS\n"); + info("CAMERA INTERFACE REGS"); dump_reg_range(ov, 0x10, 0x1f); - dev_info(&ov->dev->dev, "DRAM INTERFACE REGS\n"); + info("DRAM INTERFACE REGS"); dump_reg_range(ov, 0x20, 0x23); - dev_info(&ov->dev->dev, "ISO FIFO REGS\n"); + info("ISO FIFO REGS"); dump_reg_range(ov, 0x30, 0x31); - dev_info(&ov->dev->dev, "PIO REGS\n"); + info("PIO REGS"); dump_reg_range(ov, 0x38, 0x39); dump_reg_range(ov, 0x3e, 0x3e); - dev_info(&ov->dev->dev, "I2C REGS\n"); + info("I2C REGS"); dump_reg_range(ov, 0x40, 0x49); - dev_info(&ov->dev->dev, "SYSTEM CONTROL REGS\n"); + info("SYSTEM CONTROL REGS"); dump_reg_range(ov, 0x50, 0x55); dump_reg_range(ov, 0x5e, 0x5f); - dev_info(&ov->dev->dev, "OmniCE REGS\n"); + info("OmniCE REGS"); dump_reg_range(ov, 0x70, 0x79); /* NOTE: Quantization tables are not readable. You will get the value * in reg. 0x79 for every table register */ @@ -1025,25 +1025,25 @@ ov511_dump_regs(struct usb_ov511 *ov) static void ov518_dump_regs(struct usb_ov511 *ov) { - dev_info(&ov->dev->dev, "VIDEO MODE REGS\n"); + info("VIDEO MODE REGS"); dump_reg_range(ov, 0x20, 0x2f); - dev_info(&ov->dev->dev, "DATA PUMP AND SNAPSHOT REGS\n"); + info("DATA PUMP AND SNAPSHOT REGS"); dump_reg_range(ov, 0x30, 0x3f); - dev_info(&ov->dev->dev, "I2C REGS\n"); + info("I2C REGS"); dump_reg_range(ov, 0x40, 0x4f); - dev_info(&ov->dev->dev, "SYSTEM CONTROL AND VENDOR REGS\n"); + info("SYSTEM CONTROL AND VENDOR REGS"); dump_reg_range(ov, 0x50, 0x5f); - dev_info(&ov->dev->dev, "60 - 6F\n"); + info("60 - 6F"); dump_reg_range(ov, 0x60, 0x6f); - dev_info(&ov->dev->dev, "70 - 7F\n"); + info("70 - 7F"); dump_reg_range(ov, 0x70, 0x7f); - dev_info(&ov->dev->dev, "Y QUANTIZATION TABLE\n"); + info("Y QUANTIZATION TABLE"); dump_reg_range(ov, 0x80, 0x8f); - dev_info(&ov->dev->dev, "UV QUANTIZATION TABLE\n"); + info("UV QUANTIZATION TABLE"); dump_reg_range(ov, 0x90, 0x9f); - dev_info(&ov->dev->dev, "A0 - BF\n"); + info("A0 - BF"); dump_reg_range(ov, 0xa0, 0xbf); - dev_info(&ov->dev->dev, "CBR\n"); + info("CBR"); dump_reg_range(ov, 0xc0, 0xcf); } #endif @@ -3205,10 +3205,9 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) */ if (printph) { - dev_info(&ov->dev->dev, - "ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", - pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6], - in[7], in[8], in[9], in[10], in[11]); + info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", + pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6], + in[7], in[8], in[9], in[10], in[11]); } /* Check for SOF/EOF packet */ @@ -3367,10 +3366,8 @@ ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) * the definitive SOF/EOF format */ if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) { if (printph) { - dev_info(&ov->dev->dev, - "ph: %2x %2x %2x %2x %2x %2x %2x %2x\n", - in[0], in[1], in[2], in[3], in[4], in[5], - in[6], in[7]); + info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0], + in[1], in[2], in[3], in[4], in[5], in[6], in[7]); } if (frame->scanstate == STATE_LINES) { @@ -3649,16 +3646,14 @@ ov51x_init_isoc(struct usb_ov511 *ov) if (packetsize == -1) { ov518_set_packet_size(ov, 640); } else { - dev_info(&ov->dev->dev, "Forcing packet size to %d\n", - packetsize); + info("Forcing packet size to %d", packetsize); ov518_set_packet_size(ov, packetsize); } } else { if (packetsize == -1) { ov511_set_packet_size(ov, size); } else { - dev_info(&ov->dev->dev, "Forcing packet size to %d\n", - packetsize); + info("Forcing packet size to %d", packetsize); ov511_set_packet_size(ov, packetsize); } } @@ -4126,7 +4121,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, return -EIO; if (force_palette && p->palette != force_palette) { - dev_info(&ov->dev->dev, "Palette rejected (%s)\n", + info("Palette rejected (%s)", symbolic(v4l1_plist, p->palette)); return -EINVAL; } @@ -4854,27 +4849,26 @@ ov7xx0_configure(struct usb_ov511 *ov) err("Error detecting sensor type"); return -1; } else if ((rc & 3) == 3) { - dev_info(&ov->dev->dev, "Sensor is an OV7610\n"); + info("Sensor is an OV7610"); ov->sensor = SEN_OV7610; } else if ((rc & 3) == 1) { /* I don't know what's different about the 76BE yet. */ if (i2c_r(ov, 0x15) & 1) - dev_info(&ov->dev->dev, "Sensor is an OV7620AE\n"); + info("Sensor is an OV7620AE"); else - dev_info(&ov->dev->dev, "Sensor is an OV76BE\n"); + info("Sensor is an OV76BE"); /* OV511+ will return all zero isoc data unless we * configure the sensor as a 7620. Someone needs to * find the exact reg. setting that causes this. */ if (ov->bridge == BRG_OV511PLUS) { - dev_info(&ov->dev->dev, - "Enabling 511+/7620AE workaround\n"); + info("Enabling 511+/7620AE workaround"); ov->sensor = SEN_OV7620; } else { ov->sensor = SEN_OV76BE; } } else if ((rc & 3) == 0) { - dev_info(&ov->dev->dev, "Sensor is an OV7620\n"); + info("Sensor is an OV7620"); ov->sensor = SEN_OV7620; } else { err("Unknown image sensor version: %d", rc & 3); @@ -5030,16 +5024,16 @@ ov6xx0_configure(struct usb_ov511 *ov) if ((rc & 3) == 0) { ov->sensor = SEN_OV6630; - dev_info(&ov->dev->dev, "Sensor is an OV6630\n"); + info("Sensor is an OV6630"); } else if ((rc & 3) == 1) { ov->sensor = SEN_OV6620; - dev_info(&ov->dev->dev, "Sensor is an OV6620\n"); + info("Sensor is an OV6620"); } else if ((rc & 3) == 2) { ov->sensor = SEN_OV6630; - dev_info(&ov->dev->dev, "Sensor is an OV6630AE\n"); + info("Sensor is an OV6630AE"); } else if ((rc & 3) == 3) { ov->sensor = SEN_OV6630; - dev_info(&ov->dev->dev, "Sensor is an OV6630AF\n"); + info("Sensor is an OV6630AF"); } /* Set sensor-specific vars */ @@ -5094,10 +5088,10 @@ ks0127_configure(struct usb_ov511 *ov) err("Error detecting sensor type"); return -1; } else if ((rc & 0x0f) == 0) { - dev_info(&ov->dev->dev, "Sensor is a KS0127\n"); + info("Sensor is a KS0127"); ov->sensor = SEN_KS0127; } else if ((rc & 0x0f) == 9) { - dev_info(&ov->dev->dev, "Sensor is a KS0127B Rev. A\n"); + info("Sensor is a KS0127B Rev. A"); ov->sensor = SEN_KS0127B; } } else { @@ -5206,8 +5200,7 @@ saa7111a_configure(struct usb_ov511 *ov) err("Error detecting sensor version"); return -1; } else { - dev_info(&ov->dev->dev, - "Sensor is an SAA7111A (version 0x%x)\n", rc); + info("Sensor is an SAA7111A (version 0x%x)", rc); ov->sensor = SEN_SAA7111A; } @@ -5269,7 +5262,7 @@ ov511_configure(struct usb_ov511 *ov) PDEBUG (1, "CustomID = %d", ov->customid); ov->desc = symbolic(camlist, ov->customid); - dev_info(&ov->dev->dev, "model: %s\n", ov->desc); + info("model: %s", ov->desc); if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) { err("Camera type (%d) not recognized", ov->customid); @@ -5433,8 +5426,7 @@ ov518_configure(struct usb_ov511 *ov) PDEBUG(4, ""); /* First 5 bits of custom ID reg are a revision ID on OV518 */ - dev_info(&ov->dev->dev, "Device revision %d\n", - 0x1F & reg_r(ov, R511_SYS_CUST_ID)); + info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID)); /* Give it the default description */ ov->desc = symbolic(camlist, 0); @@ -5781,8 +5773,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; } - dev_info(&intf->dev, "USB %s video device found\n", - symbolic(brglist, ov->bridge)); + info("USB %s video device found", symbolic(brglist, ov->bridge)); init_waitqueue_head(&ov->wq); @@ -5863,8 +5854,8 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; } - dev_info(&intf->dev, "Device at %s registered to minor %d\n", - ov->usb_path, ov->vdev->minor); + info("Device at %s registered to minor %d", ov->usb_path, + ov->vdev->minor); usb_set_intfdata(intf, ov); if (ov_create_sysfs(ov->vdev)) { @@ -5967,8 +5958,7 @@ usb_ov511_init(void) if (retval) goto out; - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_VERSION " : " DRIVER_DESC); out: return retval; @@ -5978,7 +5968,8 @@ static void __exit usb_ov511_exit(void) { usb_deregister(&ov511_driver); - printk(KERN_INFO KBUILD_MODNAME ": driver deregistered\n"); + info("driver deregistered"); + } module_init(usb_ov511_init); diff --git a/trunk/drivers/media/video/ov511.h b/trunk/drivers/media/video/ov511.h index 70d99e52329d..baded1262ca9 100644 --- a/trunk/drivers/media/video/ov511.h +++ b/trunk/drivers/media/video/ov511.h @@ -12,8 +12,7 @@ #ifdef OV511_DEBUG #define PDEBUG(level, fmt, args...) \ - if (debug >= (level)) \ - printk(KERN_INFO KBUILD_MODNAME "[%s:%d] \n" fmt, \ + if (debug >= (level)) info("[%s:%d] " fmt, \ __func__, __LINE__ , ## args) #else #define PDEBUG(level, fmt, args...) do {} while(0) diff --git a/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c b/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c index 2c4acbf5a4fe..065c2454113e 100644 --- a/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c @@ -49,6 +49,12 @@ MODULE_LICENSE("GPL"); #define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */ #define GENERIC_REG_COM_I 0x29 /* misc ID bits */ +extern struct ovcamchip_ops ov6x20_ops; +extern struct ovcamchip_ops ov6x30_ops; +extern struct ovcamchip_ops ov7x10_ops; +extern struct ovcamchip_ops ov7x20_ops; +extern struct ovcamchip_ops ov76be_ops; + static char *chip_names[NUM_CC_TYPES] = { [CC_UNKNOWN] = "Unknown chip", [CC_OV76BE] = "OV76BE", diff --git a/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h b/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h index a05650faedda..9afa4fe47726 100644 --- a/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h +++ b/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h @@ -53,12 +53,6 @@ struct ovcamchip { int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */ }; -extern struct ovcamchip_ops ov6x20_ops; -extern struct ovcamchip_ops ov6x30_ops; -extern struct ovcamchip_ops ov7x10_ops; -extern struct ovcamchip_ops ov7x20_ops; -extern struct ovcamchip_ops ov76be_ops; - /* --------------------------------- */ /* I2C I/O */ /* --------------------------------- */ diff --git a/trunk/drivers/media/video/pms.c b/trunk/drivers/media/video/pms.c index 994807818aa2..7c84f795db54 100644 --- a/trunk/drivers/media/video/pms.c +++ b/trunk/drivers/media/video/pms.c @@ -47,7 +47,6 @@ struct pms_device struct video_picture picture; int height; int width; - unsigned long in_use; struct mutex lock; }; @@ -882,27 +881,10 @@ static ssize_t pms_read(struct file *file, char __user *buf, return len; } -static int pms_exclusive_open(struct inode *inode, struct file *file) -{ - struct video_device *v = video_devdata(file); - struct pms_device *pd = (struct pms_device *)v; - - return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0; -} - -static int pms_exclusive_release(struct inode *inode, struct file *file) -{ - struct video_device *v = video_devdata(file); - struct pms_device *pd = (struct pms_device *)v; - - clear_bit(0, &pd->in_use); - return 0; -} - static const struct file_operations pms_fops = { .owner = THIS_MODULE, - .open = pms_exclusive_open, - .release = pms_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = pms_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -915,7 +897,6 @@ static struct video_device pms_template= { .name = "Mediavision PMS", .fops = &pms_fops, - .release = video_device_release_empty, }; static struct pms_device pms_device; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 203f54cd18a1..0764fbfffb73 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c @@ -134,17 +134,13 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) /* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr) +int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr) { int ret = 0; if (!cptr) return 0; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->type == pvr2_ctl_int) { - if (cptr->info->get_def_value) { - ret = cptr->info->get_def_value(cptr, valptr); - } else { - *valptr = cptr->info->default_value; - } + ret = cptr->info->default_value; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h index 794ff90121c7..0371ae6e6e4e 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h @@ -49,7 +49,7 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl *); int pvr2_ctrl_get_min(struct pvr2_ctrl *); /* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *, int *valptr); +int pvr2_ctrl_get_def(struct pvr2_ctrl *); /* Retrieve control's enumeration count (enum only) */ int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index de7ee7264be6..657f861593b3 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -82,7 +82,6 @@ struct pvr2_ctl_info { /* Control's implementation */ pvr2_ctlf_get_value get_value; /* Get its value */ - pvr2_ctlf_get_value get_def_value; /* Get its default value */ pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */ pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */ pvr2_ctlf_set_value set_value; /* Set its value */ @@ -308,10 +307,6 @@ struct pvr2_hdw { struct v4l2_tuner tuner_signal_info; int tuner_signal_stale; - /* Cropping capability info */ - struct v4l2_cropcap cropcap_info; - int cropcap_stale; - /* Video standard handling */ v4l2_std_id std_mask_eeprom; // Hardware supported selections v4l2_std_id std_mask_avail; // Which standards we may select from @@ -372,10 +367,6 @@ struct pvr2_hdw { VCREATE_DATA(bass); VCREATE_DATA(treble); VCREATE_DATA(mute); - VCREATE_DATA(cropl); - VCREATE_DATA(cropt); - VCREATE_DATA(cropw); - VCREATE_DATA(croph); VCREATE_DATA(input); VCREATE_DATA(audiomode); VCREATE_DATA(res_hor); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 94265bd3d926..f051c6aa7f1f 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -298,7 +298,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, unsigned int timeout,int probe_fl, void *write_data,unsigned int write_len, void *read_data,unsigned int read_len); -static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw); static void trace_stbit(const char *name,int val) @@ -403,194 +402,6 @@ static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) return 0; } -static int ctrl_cropl_min_get(struct pvr2_ctrl *cptr, int *left) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *left = cap->bounds.left; - return 0; -} - -static int ctrl_cropl_max_get(struct pvr2_ctrl *cptr, int *left) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *left = cap->bounds.left; - if (cap->bounds.width > cptr->hdw->cropw_val) { - *left += cap->bounds.width - cptr->hdw->cropw_val; - } - return 0; -} - -static int ctrl_cropt_min_get(struct pvr2_ctrl *cptr, int *top) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *top = cap->bounds.top; - return 0; -} - -static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *top = cap->bounds.top; - if (cap->bounds.height > cptr->hdw->croph_val) { - *top += cap->bounds.height - cptr->hdw->croph_val; - } - return 0; -} - -static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = 0; - if (cap->bounds.width > cptr->hdw->cropl_val) { - *val = cap->bounds.width - cptr->hdw->cropl_val; - } - return 0; -} - -static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = 0; - if (cap->bounds.height > cptr->hdw->cropt_val) { - *val = cap->bounds.height - cptr->hdw->cropt_val; - } - return 0; -} - -static int ctrl_get_cropcapbl(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.left; - return 0; -} - -static int ctrl_get_cropcapbt(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.top; - return 0; -} - -static int ctrl_get_cropcapbw(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.width; - return 0; -} - -static int ctrl_get_cropcapbh(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->bounds.height; - return 0; -} - -static int ctrl_get_cropcapdl(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.left; - return 0; -} - -static int ctrl_get_cropcapdt(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.top; - return 0; -} - -static int ctrl_get_cropcapdw(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.width; - return 0; -} - -static int ctrl_get_cropcapdh(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->defrect.height; - return 0; -} - -static int ctrl_get_cropcappan(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->pixelaspect.numerator; - return 0; -} - -static int ctrl_get_cropcappad(struct pvr2_ctrl *cptr, int *val) -{ - struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; - int stat = pvr2_hdw_check_cropcap(cptr->hdw); - if (stat != 0) { - return stat; - } - *val = cap->pixelaspect.denominator; - return 0; -} - static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp) { /* Actual maximum depends on the video standard in effect. */ @@ -968,10 +779,6 @@ VCREATE_FUNCS(balance) VCREATE_FUNCS(bass) VCREATE_FUNCS(treble) VCREATE_FUNCS(mute) -VCREATE_FUNCS(cropl) -VCREATE_FUNCS(cropt) -VCREATE_FUNCS(cropw) -VCREATE_FUNCS(croph) VCREATE_FUNCS(audiomode) VCREATE_FUNCS(res_hor) VCREATE_FUNCS(res_ver) @@ -1042,72 +849,6 @@ static const struct pvr2_ctl_info control_defs[] = { .default_value = 0, DEFREF(mute), DEFBOOL, - }, { - .desc = "Capture crop left margin", - .name = "crop_left", - .internal_id = PVR2_CID_CROPL, - .default_value = 0, - DEFREF(cropl), - DEFINT(-129, 340), - .get_min_value = ctrl_cropl_min_get, - .get_max_value = ctrl_cropl_max_get, - .get_def_value = ctrl_get_cropcapdl, - }, { - .desc = "Capture crop top margin", - .name = "crop_top", - .internal_id = PVR2_CID_CROPT, - .default_value = 0, - DEFREF(cropt), - DEFINT(-35, 544), - .get_min_value = ctrl_cropt_min_get, - .get_max_value = ctrl_cropt_max_get, - .get_def_value = ctrl_get_cropcapdt, - }, { - .desc = "Capture crop width", - .name = "crop_width", - .internal_id = PVR2_CID_CROPW, - .default_value = 720, - DEFREF(cropw), - .get_max_value = ctrl_cropw_max_get, - .get_def_value = ctrl_get_cropcapdw, - }, { - .desc = "Capture crop height", - .name = "crop_height", - .internal_id = PVR2_CID_CROPH, - .default_value = 480, - DEFREF(croph), - .get_max_value = ctrl_croph_max_get, - .get_def_value = ctrl_get_cropcapdh, - }, { - .desc = "Capture capability pixel aspect numerator", - .name = "cropcap_pixel_numerator", - .internal_id = PVR2_CID_CROPCAPPAN, - .get_value = ctrl_get_cropcappan, - }, { - .desc = "Capture capability pixel aspect denominator", - .name = "cropcap_pixel_denominator", - .internal_id = PVR2_CID_CROPCAPPAD, - .get_value = ctrl_get_cropcappad, - }, { - .desc = "Capture capability bounds top", - .name = "cropcap_bounds_top", - .internal_id = PVR2_CID_CROPCAPBT, - .get_value = ctrl_get_cropcapbt, - }, { - .desc = "Capture capability bounds left", - .name = "cropcap_bounds_left", - .internal_id = PVR2_CID_CROPCAPBL, - .get_value = ctrl_get_cropcapbl, - }, { - .desc = "Capture capability bounds width", - .name = "cropcap_bounds_width", - .internal_id = PVR2_CID_CROPCAPBW, - .get_value = ctrl_get_cropcapbw, - }, { - .desc = "Capture capability bounds height", - .name = "cropcap_bounds_height", - .internal_id = PVR2_CID_CROPCAPBH, - .get_value = ctrl_get_cropcapbh, },{ .desc = "Video Source", .name = "input", @@ -1572,19 +1313,9 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE; memcpy(fw_ptr, fw_entry->data + fw_done, bcnt); /* Usbsnoop log shows that we must swap bytes... */ - /* Some background info: The data being swapped here is a - firmware image destined for the mpeg encoder chip that - lives at the other end of a USB endpoint. The encoder - chip always talks in 32 bit chunks and its storage is - organized into 32 bit words. However from the file - system to the encoder chip everything is purely a byte - stream. The firmware file's contents are always 32 bit - swapped from what the encoder expects. Thus the need - always exists to swap the bytes regardless of the endian - type of the host processor and therefore swab32() makes - the most sense. */ for (icnt = 0; icnt < bcnt/4 ; icnt++) - ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); + ((u32 *)fw_ptr)[icnt] = + ___swab32(((u32 *)fw_ptr)[icnt]); ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, &actual_length, HZ); @@ -2174,7 +1905,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, const struct usb_device_id *devid) { unsigned int idx,cnt1,cnt2,m; - struct pvr2_hdw *hdw = NULL; + struct pvr2_hdw *hdw; int valid_std_mask; struct pvr2_ctrl *cptr; const struct pvr2_device_desc *hdw_desc; @@ -2184,16 +1915,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); - if (hdw_desc == NULL) { - pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create:" - " No device description pointer," - " unable to continue."); - pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type," - " please contact Mike Isely " - " to get it included in the driver\n"); - goto fail; - } - hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", hdw,hdw_desc->description); @@ -2351,7 +2072,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, valid_std_mask; } - hdw->cropcap_stale = !0; hdw->eeprom_addr = -1; hdw->unit_number = -1; hdw->v4l_minor_number_video = -1; @@ -2788,28 +2508,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) /* Can't commit anything until pathway is ok. */ return 0; } - /* The broadcast decoder can only scale down, so if - * res_*_dirty && crop window < output format ==> enlarge crop. - * - * The mpeg encoder receives fields of res_hor_val dots and - * res_ver_val halflines. Limits: hor<=720, ver<=576. - */ - if (hdw->res_hor_dirty && hdw->cropw_val < hdw->res_hor_val) { - hdw->cropw_val = hdw->res_hor_val; - hdw->cropw_dirty = !0; - } else if (hdw->cropw_dirty) { - hdw->res_hor_dirty = !0; /* must rescale */ - hdw->res_hor_val = min(720, hdw->cropw_val); - } - if (hdw->res_ver_dirty && hdw->croph_val < hdw->res_ver_val) { - hdw->croph_val = hdw->res_ver_val; - hdw->croph_dirty = !0; - } else if (hdw->croph_dirty) { - int nvres = hdw->std_mask_cur & V4L2_STD_525_60 ? 480 : 576; - hdw->res_ver_dirty = !0; - hdw->res_ver_val = min(nvres, hdw->croph_val); - } - /* If any of the below has changed, then we can't do the update while the pipeline is running. Pipeline must be paused first and decoder -> encoder connection be made quiescent before we @@ -2820,8 +2518,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) hdw->srate_dirty || hdw->res_ver_dirty || hdw->res_hor_dirty || - hdw->cropw_dirty || - hdw->croph_dirty || hdw->input_dirty || (hdw->active_stream_type != hdw->desired_stream_type)); if (disruptive_change && !hdw->state_pipeline_idle) { @@ -2891,9 +2587,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) } hdw->state_pipeline_config = !0; - /* Hardware state may have changed in a way to cause the cropping - capabilities to have changed. So mark it stale, which will - cause a later re-fetch. */ trace_stbit("state_pipeline_config",hdw->state_pipeline_config); return !0; } @@ -2984,33 +2677,6 @@ void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw) } -static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw) -{ - if (!hdw->cropcap_stale) { - return 0; - } - pvr2_i2c_core_status_poll(hdw); - if (hdw->cropcap_stale) { - return -EIO; - } - return 0; -} - - -/* Return information about cropping capabilities */ -int pvr2_hdw_get_cropcap(struct pvr2_hdw *hdw, struct v4l2_cropcap *pp) -{ - int stat = 0; - LOCK_TAKE(hdw->big_lock); - stat = pvr2_hdw_check_cropcap(hdw); - if (!stat) { - memcpy(pp, &hdw->cropcap_info, sizeof(hdw->cropcap_info)); - } - LOCK_GIVE(hdw->big_lock); - return stat; -} - - /* Return information about the tuner */ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) { diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 49482d1f2b28..c04956d304a7 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -36,16 +36,6 @@ #define PVR2_CID_FREQUENCY 6 #define PVR2_CID_HRES 7 #define PVR2_CID_VRES 8 -#define PVR2_CID_CROPL 9 -#define PVR2_CID_CROPT 10 -#define PVR2_CID_CROPW 11 -#define PVR2_CID_CROPH 12 -#define PVR2_CID_CROPCAPPAN 13 -#define PVR2_CID_CROPCAPPAD 14 -#define PVR2_CID_CROPCAPBL 15 -#define PVR2_CID_CROPCAPBT 16 -#define PVR2_CID_CROPCAPBW 17 -#define PVR2_CID_CROPCAPBH 18 /* Legal values for the INPUT state variable */ #define PVR2_CVAL_INPUT_TV 0 @@ -180,9 +170,6 @@ void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *); /* Return information about the tuner */ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *); -/* Return information about cropping capabilities */ -int pvr2_hdw_get_cropcap(struct pvr2_hdw *, struct v4l2_cropcap *); - /* Query device and see if it thinks it is on a high-speed USB link */ int pvr2_hdw_is_hsm(struct pvr2_hdw *); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index 94a47718e88e..ccdb429fc7af 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -37,9 +37,8 @@ #define OP_VOLUME 3 #define OP_FREQ 4 #define OP_AUDIORATE 5 -#define OP_CROP 6 -#define OP_SIZE 7 -#define OP_LOG 8 +#define OP_SIZE 6 +#define OP_LOG 7 static const struct pvr2_i2c_op * const ops[] = { [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, @@ -47,7 +46,6 @@ static const struct pvr2_i2c_op * const ops[] = { [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, - [OP_CROP] = &pvr2_i2c_op_v4l2_crop, [OP_SIZE] = &pvr2_i2c_op_v4l2_size, [OP_LOG] = &pvr2_i2c_op_v4l2_log, }; @@ -61,7 +59,6 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) (1 << OP_BCSH) | (1 << OP_VOLUME) | (1 << OP_FREQ) | - (1 << OP_CROP) | (1 << OP_SIZE) | (1 << OP_LOG)); cp->status_poll = pvr2_v4l2_cmd_status_poll; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c index 16bb11902a52..55f04a0b2047 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c @@ -37,7 +37,6 @@ static void set_standard(struct pvr2_hdw *hdw) pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); } hdw->tuner_signal_stale = !0; - hdw->cropcap_stale = !0; } @@ -234,37 +233,6 @@ const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { }; -static void set_crop(struct pvr2_hdw *hdw) -{ - struct v4l2_crop crop; - - memset(&crop, 0, sizeof crop); - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - crop.c.left = hdw->cropl_val; - crop.c.top = hdw->cropt_val; - crop.c.height = hdw->croph_val; - crop.c.width = hdw->cropw_val; - - pvr2_trace(PVR2_TRACE_CHIPS, - "i2c v4l2 set_crop crop=%d:%d:%d:%d", - crop.c.width, crop.c.height, crop.c.left, crop.c.top); - - pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop); -} - -static int check_crop(struct pvr2_hdw *hdw) -{ - return (hdw->cropl_dirty || hdw->cropt_dirty || - hdw->cropw_dirty || hdw->croph_dirty); -} - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = { - .check = check_crop, - .update = set_crop, - .name = "v4l2_crop", -}; - - static void do_log(struct pvr2_hdw *hdw) { pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); @@ -295,19 +263,7 @@ void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp) { - int stat; - struct pvr2_hdw *hdw = cp->hdw; - if (hdw->cropcap_stale) { - hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP, - &hdw->cropcap_info); - if (stat == 0) { - /* Check was successful, so the data is no - longer considered stale. */ - hdw->cropcap_stale = 0; - } - } - pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info); + pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&cp->hdw->tuner_signal_info); } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h index eb744a20610d..7fa38683b3b1 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h @@ -29,7 +29,6 @@ extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index d6a35401fefb..e600576a6c4b 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -827,7 +827,7 @@ static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { unsigned int idx; unsigned long msk,sm; - + int spcfl; bcnt = scnprintf(buf,maxlen," ["); ccnt += bcnt; buf += bcnt; maxlen -= bcnt; sm = 0; @@ -891,7 +891,6 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client) INIT_LIST_HEAD(&cp->list); cp->client = client; mutex_lock(&hdw->i2c_list_lock); do { - hdw->cropcap_stale = !0; list_add_tail(&cp->list,&hdw->i2c_clients); hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; } while (0); mutex_unlock(&hdw->i2c_list_lock); @@ -906,7 +905,6 @@ static int pvr2_i2c_detach_inform(struct i2c_client *client) unsigned long amask = 0; int foundfl = 0; mutex_lock(&hdw->i2c_list_lock); do { - hdw->cropcap_stale = !0; list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) { if (cp->client == client) { trace_i2c("pvr2_i2c_detach" @@ -948,32 +946,22 @@ static struct i2c_adapter pvr2_i2c_adap_template = { .client_unregister = pvr2_i2c_detach_inform, }; - -/* Return true if device exists at given address */ -static int do_i2c_probe(struct pvr2_hdw *hdw, int addr) +static void do_i2c_scan(struct pvr2_hdw *hdw) { struct i2c_msg msg[1]; - int rc; + int i,rc; msg[0].addr = 0; msg[0].flags = I2C_M_RD; msg[0].len = 0; msg[0].buf = NULL; - msg[0].addr = addr; - rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg)); - return rc == 1; -} - -static void do_i2c_scan(struct pvr2_hdw *hdw) -{ - int i; - printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name); + printk("%s: i2c scan beginning\n",hdw->name); for (i = 0; i < 128; i++) { - if (do_i2c_probe(hdw, i)) { - printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n", - hdw->name, i); - } + msg[0].addr = i; + rc = i2c_transfer(&hdw->i2c_adap,msg, ARRAY_SIZE(msg)); + if (rc != 1) continue; + printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i); } - printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); + printk("%s: i2c scan done.\n",hdw->name); } void pvr2_i2c_core_init(struct pvr2_hdw *hdw) @@ -992,6 +980,8 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) hdw->i2c_func[0x18] = i2c_black_hole; } else if (ir_mode[hdw->unit_number] == 1) { if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { + /* This comment is present PURELY to get + checkpatch.pl to STFU. Lovely, eh? */ hdw->i2c_func[0x18] = i2c_24xxx_ir; } } @@ -1016,16 +1006,6 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) mutex_init(&hdw->i2c_list_lock); hdw->i2c_linked = !0; i2c_add_adapter(&hdw->i2c_adap); - if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { - /* Probe for a different type of IR receiver on this - device. If present, disable the emulated IR receiver. */ - if (do_i2c_probe(hdw, 0x71)) { - pvr2_trace(PVR2_TRACE_INFO, - "Device has newer IR hardware;" - " disabling unneeded virtual IR device"); - hdw->i2c_func[0x18] = NULL; - } - } if (i2c_scan) do_i2c_scan(hdw); } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c index 9b3c874d96d6..ad0d98c2ebb4 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -137,11 +137,9 @@ static int __init pvr_init(void) ret = usb_register(&pvr_driver); if (ret == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - if (pvrusb2_debug) - printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n", - pvrusb2_debug,pvrusb2_debug); + info(DRIVER_DESC " : " DRIVER_VERSION); + if (pvrusb2_debug) info("Debug mask is %d (0x%x)", + pvrusb2_debug,pvrusb2_debug); pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 733680f21317..46a8c39ba030 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -65,7 +65,6 @@ struct pvr2_sysfs_ctl_item { struct device_attribute attr_type; struct device_attribute attr_min; struct device_attribute attr_max; - struct device_attribute attr_def; struct device_attribute attr_enum; struct device_attribute attr_bits; struct device_attribute attr_val; @@ -146,23 +145,6 @@ static ssize_t show_max(struct device *class_dev, return scnprintf(buf, PAGE_SIZE, "%ld\n", val); } -static ssize_t show_def(struct device *class_dev, - struct device_attribute *attr, - char *buf) -{ - struct pvr2_sysfs_ctl_item *cip; - int val; - int ret; - cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def); - ret = pvr2_ctrl_get_def(cip->cptr, &val); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %d, stat=%d", - cip->chptr, cip->ctl_id, val, ret); - if (ret < 0) { - return ret; - } - return scnprintf(buf, PAGE_SIZE, "%d\n", val); -} - static ssize_t show_val_norm(struct device *class_dev, struct device_attribute *attr, char *buf) @@ -338,10 +320,6 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) cip->attr_max.attr.mode = S_IRUGO; cip->attr_max.show = show_max; - cip->attr_def.attr.name = "def_val"; - cip->attr_def.attr.mode = S_IRUGO; - cip->attr_def.show = show_def; - cip->attr_val.attr.name = "cur_val"; cip->attr_val.attr.mode = S_IRUGO; @@ -365,7 +343,6 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) cip->attr_gen[acnt++] = &cip->attr_name.attr; cip->attr_gen[acnt++] = &cip->attr_type.attr; cip->attr_gen[acnt++] = &cip->attr_val.attr; - cip->attr_gen[acnt++] = &cip->attr_def.attr; cip->attr_val.show = show_val_norm; cip->attr_val.store = store_val_norm; if (pvr2_ctrl_has_custom_symbols(cptr)) { diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index f048d80b77e5..00306faeac01 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -533,7 +533,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, lmin = pvr2_ctrl_get_min(hcp); lmax = pvr2_ctrl_get_max(hcp); - pvr2_ctrl_get_def(hcp, &ldef); + ldef = pvr2_ctrl_get_def(hcp); if (w == -1) { w = ldef; } else if (w < lmin) { @@ -543,7 +543,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, } lmin = pvr2_ctrl_get_min(vcp); lmax = pvr2_ctrl_get_max(vcp); - pvr2_ctrl_get_def(vcp, &ldef); + ldef = pvr2_ctrl_get_def(vcp); if (h == -1) { h = ldef; } else if (h < lmin) { @@ -604,7 +604,6 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_QUERYCTRL: { struct pvr2_ctrl *cptr; - int val; struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; ret = 0; if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { @@ -628,8 +627,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, pvr2_ctrl_get_desc(cptr)); strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); vc->flags = pvr2_ctrl_get_v4lflags(cptr); - pvr2_ctrl_get_def(cptr, &val); - vc->default_value = val; + vc->default_value = pvr2_ctrl_get_def(cptr); switch (pvr2_ctrl_get_type(cptr)) { case pvr2_ctl_enum: vc->type = V4L2_CTRL_TYPE_MENU; @@ -755,92 +753,6 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, break; } - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg; - if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret = -EINVAL; - break; - } - ret = pvr2_hdw_get_cropcap(hdw, cap); - cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */ - break; - } - case VIDIOC_G_CROP: - { - struct v4l2_crop *crop = (struct v4l2_crop *)arg; - int val = 0; - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret = -EINVAL; - break; - } - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val); - if (ret != 0) { - ret = -EINVAL; - break; - } - crop->c.left = val; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val); - if (ret != 0) { - ret = -EINVAL; - break; - } - crop->c.top = val; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val); - if (ret != 0) { - ret = -EINVAL; - break; - } - crop->c.width = val; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val); - if (ret != 0) { - ret = -EINVAL; - break; - } - crop->c.height = val; - } - case VIDIOC_S_CROP: - { - struct v4l2_crop *crop = (struct v4l2_crop *)arg; - struct v4l2_cropcap cap; - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - ret = -EINVAL; - break; - } - cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), - crop->c.left); - if (ret != 0) { - ret = -EINVAL; - break; - } - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), - crop->c.top); - if (ret != 0) { - ret = -EINVAL; - break; - } - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), - crop->c.width); - if (ret != 0) { - ret = -EINVAL; - break; - } - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), - crop->c.height); - if (ret != 0) { - ret = -EINVAL; - break; - } - } case VIDIOC_LOG_STATUS: { pvr2_hdw_trigger_module_log(hdw); diff --git a/trunk/drivers/media/video/pwc/pwc-ctrl.c b/trunk/drivers/media/video/pwc/pwc-ctrl.c index c66530210192..dbc560742553 100644 --- a/trunk/drivers/media/video/pwc/pwc-ctrl.c +++ b/trunk/drivers/media/video/pwc/pwc-ctrl.c @@ -41,6 +41,7 @@ #include #endif #include +#include #include "pwc.h" #include "pwc-uncompress.h" diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c index ab28389b4cda..9aee7cb6f79a 100644 --- a/trunk/drivers/media/video/pwc/pwc-if.c +++ b/trunk/drivers/media/video/pwc/pwc-if.c @@ -1112,7 +1112,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev); - pdev = video_get_drvdata(vdev); + pdev = (struct pwc_device *)vdev->priv; BUG_ON(!pdev); if (pdev->vopen) { PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); @@ -1233,7 +1233,7 @@ static int pwc_video_close(struct inode *inode, struct file *file) PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); lock_kernel(); - pdev = video_get_drvdata(vdev); + pdev = (struct pwc_device *)vdev->priv; if (pdev->vopen == 0) PWC_DEBUG_MODULE("video_close() called on closed device?\n"); @@ -1304,7 +1304,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, vdev, buf, count); if (vdev == NULL) return -EFAULT; - pdev = video_get_drvdata(vdev); + pdev = vdev->priv; if (pdev == NULL) return -EFAULT; @@ -1386,7 +1386,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) if (vdev == NULL) return -EFAULT; - pdev = video_get_drvdata(vdev); + pdev = vdev->priv; if (pdev == NULL) return -EFAULT; @@ -1408,7 +1408,7 @@ static int pwc_video_ioctl(struct inode *inode, struct file *file, if (!vdev) goto out; - pdev = video_get_drvdata(vdev); + pdev = vdev->priv; mutex_lock(&pdev->modlock); if (!pdev->unplugged) @@ -1428,7 +1428,7 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) int index; PWC_DEBUG_MEMORY(">> %s\n", __func__); - pdev = video_get_drvdata(vdev); + pdev = vdev->priv; size = vma->vm_end - vma->vm_start; start = vma->vm_start; diff --git a/trunk/drivers/media/video/pwc/pwc-v4l.c b/trunk/drivers/media/video/pwc/pwc-v4l.c index 76a1376c9751..1742889874df 100644 --- a/trunk/drivers/media/video/pwc/pwc-v4l.c +++ b/trunk/drivers/media/video/pwc/pwc-v4l.c @@ -346,7 +346,7 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file, if (vdev == NULL) return -EFAULT; - pdev = video_get_drvdata(vdev); + pdev = vdev->priv; if (pdev == NULL) return -EFAULT; diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c index eb6be5802928..cf96b2cc4f1c 100644 --- a/trunk/drivers/media/video/pxa_camera.c +++ b/trunk/drivers/media/video/pxa_camera.c @@ -629,6 +629,17 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) pdata->init(pcdev->dev); } + if (pdata && pdata->power) { + dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__); + pdata->power(pcdev->dev, 1); + } + + if (pdata && pdata->reset) { + dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", + __func__); + pdata->reset(pcdev->dev, 1); + } + CICR0 = 0x3FF; /* disable all interrupts */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) @@ -649,7 +660,20 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) { + struct pxacamera_platform_data *board = pcdev->pdata; + clk_disable(pcdev->clk); + + if (board && board->reset) { + dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", + __func__); + board->reset(pcdev->dev, 0); + } + + if (board && board->power) { + dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__); + board->power(pcdev->dev, 0); + } } static irqreturn_t pxa_camera_irq(int irq, void *data) @@ -1120,31 +1144,31 @@ static int pxa_camera_probe(struct platform_device *pdev) pcdev->dev = &pdev->dev; /* request dma */ - err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, - pxa_camera_dma_irq_y, pcdev); - if (err < 0) { + pcdev->dma_chans[0] = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, + pxa_camera_dma_irq_y, pcdev); + if (pcdev->dma_chans[0] < 0) { dev_err(pcdev->dev, "Can't request DMA for Y\n"); + err = -ENOMEM; goto exit_iounmap; } - pcdev->dma_chans[0] = err; dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); - err = pxa_request_dma("CI_U", DMA_PRIO_HIGH, - pxa_camera_dma_irq_u, pcdev); - if (err < 0) { + pcdev->dma_chans[1] = pxa_request_dma("CI_U", DMA_PRIO_HIGH, + pxa_camera_dma_irq_u, pcdev); + if (pcdev->dma_chans[1] < 0) { dev_err(pcdev->dev, "Can't request DMA for U\n"); + err = -ENOMEM; goto exit_free_dma_y; } - pcdev->dma_chans[1] = err; dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); - err = pxa_request_dma("CI_V", DMA_PRIO_HIGH, - pxa_camera_dma_irq_v, pcdev); - if (err < 0) { + pcdev->dma_chans[2] = pxa_request_dma("CI_V", DMA_PRIO_HIGH, + pxa_camera_dma_irq_v, pcdev); + if (pcdev->dma_chans[0] < 0) { dev_err(pcdev->dev, "Can't request DMA for V\n"); + err = -ENOMEM; goto exit_free_dma_u; } - pcdev->dma_chans[2] = err; dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD; diff --git a/trunk/drivers/media/video/s2255drv.c b/trunk/drivers/media/video/s2255drv.c index 5272926db73e..92b83feae366 100644 --- a/trunk/drivers/media/video/s2255drv.c +++ b/trunk/drivers/media/video/s2255drv.c @@ -58,8 +58,6 @@ -/* default JPEG quality */ -#define S2255_DEF_JPEG_QUAL 50 /* vendor request in */ #define S2255_VR_IN 0 /* vendor request out */ @@ -69,21 +67,20 @@ /* USB endpoint number for configuring the device */ #define S2255_CONFIG_EP 2 /* maximum time for DSP to start responding after last FW word loaded(ms) */ -#define S2255_DSP_BOOTTIME 800 +#define S2255_DSP_BOOTTIME 400 /* maximum time to wait for firmware to load (ms) */ #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) #define S2255_DEF_BUFS 16 -#define S2255_SETMODE_TIMEOUT 500 #define MAX_CHANNELS 4 -#define S2255_MARKER_FRAME 0x2255DA4AL -#define S2255_MARKER_RESPONSE 0x2255ACACL -#define S2255_USB_XFER_SIZE (16 * 1024) +#define FRAME_MARKER 0x2255DA4AL +#define MAX_PIPE_USBBLOCK (40 * 1024) +#define DEFAULT_PIPE_USBBLOCK (16 * 1024) #define MAX_CHANNELS 4 #define MAX_PIPE_BUFFERS 1 #define SYS_FRAMES 4 /* maximum size is PAL full size plus room for the marker header(s) */ -#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) -#define DEF_USB_BLOCK S2255_USB_XFER_SIZE +#define SYS_FRAMES_MAXSIZE (720 * 288 * 2 * 2 + 4096) +#define DEF_USB_BLOCK (4096) #define LINE_SZ_4CIFS_NTSC 640 #define LINE_SZ_2CIFS_NTSC 640 #define LINE_SZ_1CIFS_NTSC 320 @@ -111,9 +108,6 @@ #define COLOR_YUVPL 1 /* YUV planar */ #define COLOR_YUVPK 2 /* YUV packed */ #define COLOR_Y8 4 /* monochrome */ -#define COLOR_JPG 5 /* JPEG */ -#define MASK_COLOR 0xff -#define MASK_JPG_QUALITY 0xff00 /* frame decimation. Not implemented by V4L yet(experimental in V4L) */ #define FDEC_1 1 /* capture every frame. default */ @@ -154,14 +148,16 @@ struct s2255_mode { u32 restart; /* if DSP requires restart */ }; +/* frame structure */ +#define FRAME_STATE_UNUSED 0 +#define FRAME_STATE_FILLING 1 +#define FRAME_STATE_FULL 2 -#define S2255_READ_IDLE 0 -#define S2255_READ_FRAME 1 -/* frame structure */ struct s2255_framei { unsigned long size; - unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/ + + unsigned long ulState; /* ulState ==0 unused, 1 being filled, 2 full */ void *lpvbits; /* image data */ unsigned long cur_size; /* current data copied to it */ }; @@ -192,10 +188,6 @@ struct s2255_dmaqueue { #define S2255_FW_FAILED 3 #define S2255_FW_DISCONNECTING 4 -#define S2255_FW_MARKER 0x22552f2f -/* 2255 read states */ -#define S2255_READ_IDLE 0 -#define S2255_READ_FRAME 1 struct s2255_fw { int fw_loaded; int fw_size; @@ -203,6 +195,7 @@ struct s2255_fw { atomic_t fw_state; void *pfw_data; wait_queue_head_t wait_fw; + struct timer_list dsp_wait; const struct firmware *fw; }; @@ -244,27 +237,15 @@ struct s2255_dev { struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; struct s2255_bufferi buffer[MAX_CHANNELS]; struct s2255_mode mode[MAX_CHANNELS]; - /* jpeg compression */ - struct v4l2_jpegcompression jc[MAX_CHANNELS]; const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; int cur_frame[MAX_CHANNELS]; int last_frame[MAX_CHANNELS]; u32 cc; /* current channel */ int b_acquire[MAX_CHANNELS]; - /* allocated image size */ unsigned long req_image_size[MAX_CHANNELS]; - /* received packet size */ - unsigned long pkt_size[MAX_CHANNELS]; int bad_payload[MAX_CHANNELS]; unsigned long frame_count[MAX_CHANNELS]; int frame_ready; - /* if JPEG image */ - int jpg_size[MAX_CHANNELS]; - /* if channel configured to default state */ - int chn_configured[MAX_CHANNELS]; - wait_queue_head_t wait_setmode[MAX_CHANNELS]; - int setmode_ready[MAX_CHANNELS]; - int chn_ready; struct kref kref; spinlock_t slock; }; @@ -325,16 +306,12 @@ static void s2255_stop_readpipe(struct s2255_dev *dev); static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn); static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn); static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, - int chn, int jpgsize); + int chn); static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, struct s2255_mode *mode); static int s2255_board_shutdown(struct s2255_dev *dev); static void s2255_exit_v4l(struct s2255_dev *dev); -static void s2255_fwload_start(struct s2255_dev *dev, int reset); -static void s2255_destroy(struct kref *kref); -static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, - u16 index, u16 value, void *buf, - s32 buf_len, int bOut); +static void s2255_fwload_start(struct s2255_dev *dev); #define dprintk(level, fmt, arg...) \ do { \ @@ -429,10 +406,6 @@ static const struct s2255_fmt formats[] = { .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16 - }, { - .name = "JPG", - .fourcc = V4L2_PIX_FMT_JPEG, - .depth = 24 }, { .name = "8bpp GREY", .fourcc = V4L2_PIX_FMT_GREY, @@ -491,13 +464,6 @@ static void planar422p_to_yuv_packed(const unsigned char *in, return; } -static void s2255_reset_dsppower(struct s2255_dev *dev) -{ - s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1); - msleep(10); - s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1); - return; -} /* kickstarts the firmware loading. from probe */ @@ -514,6 +480,18 @@ static void s2255_timer(unsigned long user_data) } } +/* called when DSP is up and running. DSP is guaranteed to + be running after S2255_DSP_BOOTTIME */ +static void s2255_dsp_running(unsigned long user_data) +{ + struct s2255_fw *data = (struct s2255_fw *)user_data; + dprintk(1, "dsp running\n"); + atomic_set(&data->fw_state, S2255_FW_SUCCESS); + wake_up(&data->wait_fw); + printk(KERN_INFO "s2255: firmware loaded successfully\n"); + return; +} + /* this loads the firmware asynchronously. Originally this was done synchroously in probe. @@ -571,14 +549,19 @@ static void s2255_fwchunk_complete(struct urb *urb) } data->fw_loaded += len; } else { + init_timer(&data->dsp_wait); + data->dsp_wait.function = s2255_dsp_running; + data->dsp_wait.data = (unsigned long)data; atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); + mod_timer(&data->dsp_wait, msecs_to_jiffies(S2255_DSP_BOOTTIME) + + jiffies); } dprintk(100, "2255 complete done\n"); return; } -static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize) +static int s2255_got_frame(struct s2255_dev *dev, int chn) { struct s2255_dmaqueue *dma_q = &dev->vidq[chn]; struct s2255_buffer *buf; @@ -603,7 +586,8 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize) list_del(&buf->vb.queue); do_gettimeofday(&buf->vb.ts); dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i); - s2255_fillbuff(dev, buf, dma_q->channel, jpgsize); + + s2255_fillbuff(dev, buf, dma_q->channel); wake_up(&buf->vb.done); dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); unlock: @@ -637,7 +621,7 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc) * */ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, - int chn, int jpgsize) + int chn) { int pos = 0; struct timeval ts; @@ -665,10 +649,6 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, case V4L2_PIX_FMT_GREY: memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); break; - case V4L2_PIX_FMT_JPEG: - buf->vb.size = jpgsize; - memcpy(vbuf, tmpbuf, buf->vb.size); - break; case V4L2_PIX_FMT_YUV422P: memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height * 2); @@ -677,6 +657,9 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, printk(KERN_DEBUG "s2255: unknown format?\n"); } dev->last_frame[chn] = -1; + /* done with the frame, free it */ + frm->ulState = 0; + dprintk(4, "freeing buffer\n"); } else { printk(KERN_ERR "s2255: =======no frame\n"); return; @@ -1038,10 +1021,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, case V4L2_PIX_FMT_GREY: fh->mode.color = COLOR_Y8; break; - case V4L2_PIX_FMT_JPEG: - fh->mode.color = COLOR_JPG | - (fh->dev->jc[fh->channel].quality << 8); - break; case V4L2_PIX_FMT_YUV422P: fh->mode.color = COLOR_YUVPL; break; @@ -1160,7 +1139,7 @@ static u32 get_transfer_size(struct s2255_mode *mode) } } outImageSize = linesPerFrame * pixelsPerLine; - if ((mode->color & MASK_COLOR) != COLOR_Y8) { + if (mode->color != COLOR_Y8) { /* 2 bytes/pixel if not monochrome */ outImageSize *= 2; } @@ -1206,17 +1185,12 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, u32 *buffer; unsigned long chn_rev; - mutex_lock(&dev->lock); chn_rev = G_chnmap[chn]; dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale); dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn], dev->mode[chn].scale); dprintk(2, "mode contrast %x\n", mode->contrast); - /* if JPEG, set the quality */ - if ((mode->color & MASK_COLOR) == COLOR_JPG) - mode->color = (dev->jc[chn].quality << 8) | COLOR_JPG; - /* save the mode */ dev->mode[chn] = *mode; dev->req_image_size[chn] = get_transfer_size(mode); @@ -1225,7 +1199,6 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, buffer = kzalloc(512, GFP_KERNEL); if (buffer == NULL) { dev_err(&dev->udev->dev, "out of mem\n"); - mutex_unlock(&dev->lock); return -ENOMEM; } @@ -1241,20 +1214,12 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, dprintk(1, "set mode done chn %lu, %d\n", chn, res); /* wait at least 3 frames before continuing */ - if (mode->restart) { - dev->setmode_ready[chn] = 0; - wait_event_timeout(dev->wait_setmode[chn], - (dev->setmode_ready[chn] != 0), - msecs_to_jiffies(S2255_SETMODE_TIMEOUT)); - if (dev->setmode_ready[chn] != 1) { - printk(KERN_DEBUG "s2255: no set mode response\n"); - res = -EFAULT; - } - } + if (mode->restart) + msleep(125); /* clear the restart flag */ dev->mode[chn].restart = 0; - mutex_unlock(&dev->lock); + return res; } @@ -1305,7 +1270,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) dev->cur_frame[chn] = 0; dev->frame_count[chn] = 0; for (j = 0; j < SYS_FRAMES; j++) { - dev->buffer[chn].frame[j].ulState = S2255_READ_IDLE; + dev->buffer[chn].frame[j].ulState = 0; dev->buffer[chn].frame[j].cur_size = 0; } res = videobuf_streamon(&fh->vb_vidq); @@ -1481,27 +1446,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return -EINVAL; } -static int vidioc_g_jpegcomp(struct file *file, void *priv, - struct v4l2_jpegcompression *jc) -{ - struct s2255_fh *fh = priv; - struct s2255_dev *dev = fh->dev; - *jc = dev->jc[fh->channel]; - dprintk(2, "getting jpegcompression, quality %d\n", jc->quality); - return 0; -} - -static int vidioc_s_jpegcomp(struct file *file, void *priv, - struct v4l2_jpegcompression *jc) -{ - struct s2255_fh *fh = priv; - struct s2255_dev *dev = fh->dev; - if (jc->quality < 0 || jc->quality > 100) - return -EINVAL; - dev->jc[fh->channel].quality = jc->quality; - dprintk(2, "setting jpeg quality %d\n", jc->quality); - return 0; -} static int s2255_open(struct inode *inode, struct file *file) { int minor = iminor(inode); @@ -1511,10 +1455,8 @@ static int s2255_open(struct inode *inode, struct file *file) enum v4l2_buf_type type = 0; int i = 0; int cur_channel = -1; - int state; dprintk(1, "s2255: open called (minor=%d)\n", minor); - lock_kernel(); list_for_each(list, &s2255_devlist) { h = list_entry(list, struct s2255_dev, s2255_devlist); for (i = 0; i < MAX_CHANNELS; i++) { @@ -1527,78 +1469,45 @@ static int s2255_open(struct inode *inode, struct file *file) } if ((NULL == dev) || (cur_channel == -1)) { - unlock_kernel(); - printk(KERN_INFO "s2255: openv4l no dev\n"); + dprintk(1, "s2255: openv4l no dev\n"); return -ENODEV; } - if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { - unlock_kernel(); - printk(KERN_INFO "disconnecting\n"); - return -ENODEV; - } - kref_get(&dev->kref); mutex_lock(&dev->open_lock); dev->users[cur_channel]++; dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); - switch (atomic_read(&dev->fw_data->fw_state)) { - case S2255_FW_FAILED: + if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) { err("2255 firmware load failed. retrying.\n"); - s2255_fwload_start(dev, 1); + s2255_fwload_start(dev); wait_event_timeout(dev->fw_data->wait_fw, - ((atomic_read(&dev->fw_data->fw_state) - == S2255_FW_SUCCESS) || - (atomic_read(&dev->fw_data->fw_state) - == S2255_FW_DISCONNECTING)), + (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_NOTLOADED), msecs_to_jiffies(S2255_LOAD_TIMEOUT)); - break; - case S2255_FW_NOTLOADED: - case S2255_FW_LOADED_DSPWAIT: + if (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_SUCCESS) { + printk(KERN_INFO "2255 FW load failed.\n"); + dev->users[cur_channel]--; + mutex_unlock(&dev->open_lock); + return -EFAULT; + } + } else if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_NOTLOADED) { /* give S2255_LOAD_TIMEOUT time for firmware to load in case driver loaded and then device immediately opened */ printk(KERN_INFO "%s waiting for firmware load\n", __func__); wait_event_timeout(dev->fw_data->wait_fw, - ((atomic_read(&dev->fw_data->fw_state) - == S2255_FW_SUCCESS) || - (atomic_read(&dev->fw_data->fw_state) - == S2255_FW_DISCONNECTING)), - msecs_to_jiffies(S2255_LOAD_TIMEOUT)); - break; - case S2255_FW_SUCCESS: - default: - break; - } - state = atomic_read(&dev->fw_data->fw_state); - if (state != S2255_FW_SUCCESS) { - int rc; - switch (state) { - case S2255_FW_FAILED: - printk(KERN_INFO "2255 FW load failed. %d\n", state); - rc = -ENODEV; - break; - case S2255_FW_DISCONNECTING: - printk(KERN_INFO "%s: disconnecting\n", __func__); - rc = -ENODEV; - break; - case S2255_FW_LOADED_DSPWAIT: - case S2255_FW_NOTLOADED: - printk(KERN_INFO "%s: firmware not loaded yet" - "please try again later\n", - __func__); - rc = -EAGAIN; - break; - default: - printk(KERN_INFO "%s: unknown state\n", __func__); - rc = -EFAULT; - break; + (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_NOTLOADED), + msecs_to_jiffies(S2255_LOAD_TIMEOUT)); + if (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_SUCCESS) { + printk(KERN_INFO "2255 firmware not loaded" + "try again\n"); + dev->users[cur_channel]--; + mutex_unlock(&dev->open_lock); + return -EBUSY; } - dev->users[cur_channel]--; - mutex_unlock(&dev->open_lock); - kref_put(&dev->kref, s2255_destroy); - unlock_kernel(); - return rc; } /* allocate + initialize per filehandle data */ @@ -1606,8 +1515,6 @@ static int s2255_open(struct inode *inode, struct file *file) if (NULL == fh) { dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); - kref_put(&dev->kref, s2255_destroy); - unlock_kernel(); return -ENOMEM; } @@ -1621,13 +1528,6 @@ static int s2255_open(struct inode *inode, struct file *file) fh->height = NUM_LINES_4CIFS_NTSC * 2; fh->channel = cur_channel; - /* configure channel to default state */ - if (!dev->chn_configured[cur_channel]) { - s2255_set_mode(dev, cur_channel, &fh->mode); - dev->chn_configured[cur_channel] = 1; - } - - /* Put all controls at a sane state */ for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) qctl_regs[i] = s2255_qctrl[i].default_value; @@ -1646,8 +1546,8 @@ static int s2255_open(struct inode *inode, struct file *file) V4L2_FIELD_INTERLACED, sizeof(struct s2255_buffer), fh); + kref_get(&dev->kref); mutex_unlock(&dev->open_lock); - unlock_kernel(); return 0; } @@ -1669,24 +1569,30 @@ static unsigned int s2255_poll(struct file *file, static void s2255_destroy(struct kref *kref) { struct s2255_dev *dev = to_s2255_dev(kref); - struct list_head *list; - int i; if (!dev) { printk(KERN_ERR "s2255drv: kref problem\n"); return; } + + /* + * Wake up any firmware load waiting (only done in .open, + * which holds the open_lock mutex) + */ atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); wake_up(&dev->fw_data->wait_fw); - for (i = 0; i < MAX_CHANNELS; i++) { - dev->setmode_ready[i] = 1; - wake_up(&dev->wait_setmode[i]); - } + + /* prevent s2255_disconnect from racing s2255_open */ mutex_lock(&dev->open_lock); - /* reset the DSP so firmware can be reload next time */ - s2255_reset_dsppower(dev); s2255_exit_v4l(dev); + /* + * device unregistered so no longer possible to open. open_mutex + * can be unlocked and timers deleted afterwards. + */ + mutex_unlock(&dev->open_lock); + /* board shutdown stops the read pipe if it is running */ s2255_board_shutdown(dev); + /* make sure firmware still not trying to load */ del_timer(&dev->timer); /* only started in .probe and .open */ @@ -1696,19 +1602,23 @@ static void s2255_destroy(struct kref *kref) usb_free_urb(dev->fw_data->fw_urb); dev->fw_data->fw_urb = NULL; } + + /* + * delete the dsp_wait timer, which sets the firmware + * state on completion. This is done before fw_data + * is freed below. + */ + + del_timer(&dev->fw_data->dsp_wait); /* only started in .open */ + if (dev->fw_data->fw) release_firmware(dev->fw_data->fw); kfree(dev->fw_data->pfw_data); kfree(dev->fw_data); + usb_put_dev(dev->udev); dprintk(1, "%s", __func__); kfree(dev); - - while (!list_empty(&s2255_devlist)) { - list = s2255_devlist.next; - list_del(list); - } - mutex_unlock(&dev->open_lock); } static int s2255_close(struct inode *inode, struct file *file) @@ -1792,8 +1702,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidioc_cgmbuf, #endif - .vidioc_s_jpegcomp = vidioc_s_jpegcomp, - .vidioc_g_jpegcomp = vidioc_g_jpegcomp, }; static struct video_device template = { @@ -1832,7 +1740,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) ret = video_register_device(dev->vdev[i], VFL_TYPE_GRABBER, cur_nr + i); - video_set_drvdata(dev->vdev[i], dev); + dev->vdev[i]->priv = dev; if (ret != 0) { dev_err(&dev->udev->dev, @@ -1846,16 +1754,18 @@ static int s2255_probe_v4l(struct s2255_dev *dev) static void s2255_exit_v4l(struct s2255_dev *dev) { - + struct list_head *list; int i; + /* unregister the video devices */ + while (!list_empty(&s2255_devlist)) { + list = s2255_devlist.next; + list_del(list); + } for (i = 0; i < MAX_CHANNELS; i++) { - if (-1 != dev->vdev[i]->minor) { + if (-1 != dev->vdev[i]->minor) video_unregister_device(dev->vdev[i]); - printk(KERN_INFO "s2255 unregistered\n"); - } else { + else video_device_release(dev->vdev[i]); - printk(KERN_INFO "s2255 released\n"); - } } } @@ -1865,122 +1775,133 @@ static void s2255_exit_v4l(struct s2255_dev *dev) * function again). * * Received frame structure: - * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME) + * bytes 0-3: marker : 0x2255DA4AL (FRAME_MARKER) * bytes 4-7: channel: 0-3 * bytes 8-11: payload size: size of the frame * bytes 12-payloadsize+12: frame data */ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) { + static int dbgsync; /* = 0; */ char *pdest; u32 offset = 0; - int bframe = 0; + int bsync = 0; + int btrunc = 0; char *psrc; unsigned long copy_size; unsigned long size; s32 idx = -1; struct s2255_framei *frm; unsigned char *pdata; - + unsigned long cur_size; + int bsearch = 0; + struct s2255_bufferi *buf; dprintk(100, "buffer to user\n"); idx = dev->cur_frame[dev->cc]; - frm = &dev->buffer[dev->cc].frame[idx]; + buf = &dev->buffer[dev->cc]; + frm = &buf->frame[idx]; - if (frm->ulState == S2255_READ_IDLE) { - int jj; - unsigned int cc; - s32 *pdword; - int payload; - /* search for marker codes */ - pdata = (unsigned char *)pipe_info->transfer_buffer; - for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { - switch (*(s32 *) pdata) { - case S2255_MARKER_FRAME: - pdword = (s32 *)pdata; - dprintk(4, "found frame marker at offset:" - " %d [%x %x]\n", jj, pdata[0], - pdata[1]); - offset = jj + PREFIX_SIZE; - bframe = 1; - cc = pdword[1]; - if (cc >= MAX_CHANNELS) { - printk(KERN_ERR - "bad channel\n"); - return -EINVAL; - } - /* reverse it */ - dev->cc = G_chnmap[cc]; - payload = pdword[3]; - if (payload > dev->req_image_size[dev->cc]) { - dev->bad_payload[dev->cc]++; - /* discard the bad frame */ - return -EINVAL; - } - dev->pkt_size[dev->cc] = payload; - dev->jpg_size[dev->cc] = pdword[4]; - break; - case S2255_MARKER_RESPONSE: - pdword = (s32 *)pdata; - pdata += DEF_USB_BLOCK; - jj += DEF_USB_BLOCK; - if (pdword[1] >= MAX_CHANNELS) - break; - cc = G_chnmap[pdword[1]]; - if (!(cc >= 0 && cc < MAX_CHANNELS)) - break; - switch (pdword[2]) { - case 0x01: - /* check if channel valid */ - /* set mode ready */ - dev->setmode_ready[cc] = 1; - wake_up(&dev->wait_setmode[cc]); - dprintk(5, "setmode ready %d\n", cc); - break; - case 0x10: - - dev->chn_ready |= (1 << cc); - if ((dev->chn_ready & 0x0f) != 0x0f) - break; - /* all channels ready */ - printk(KERN_INFO "s2255: fw loaded\n"); - atomic_set(&dev->fw_data->fw_state, - S2255_FW_SUCCESS); - wake_up(&dev->fw_data->wait_fw); + if (frm->ulState == 0) { + frm->ulState = 1; + frm->cur_size = 0; + bsearch = 1; + } else if (frm->ulState == 2) { + /* system frame was not freed */ + dprintk(2, "sys frame not free. overrun ringbuf\n"); + bsearch = 1; + frm->ulState = 1; + frm->cur_size = 0; + } + + if (bsearch) { + if (*(s32 *) pipe_info->transfer_buffer != FRAME_MARKER) { + u32 jj; + if (dbgsync == 0) { + dprintk(3, "not synched, discarding all packets" + "until marker\n"); + + dbgsync++; + } + pdata = (unsigned char *)pipe_info->transfer_buffer; + for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); + jj++) { + if (*(s32 *) pdata == FRAME_MARKER) { + int cc; + dprintk(3, + "found frame marker at offset:" + " %d [%x %x]\n", jj, pdata[0], + pdata[1]); + offset = jj; + bsync = 1; + cc = *(u32 *) (pdata + sizeof(u32)); + if (cc >= MAX_CHANNELS) { + printk(KERN_ERR + "bad channel\n"); + return -EINVAL; + } + /* reverse it */ + dev->cc = G_chnmap[cc]; break; - default: - printk(KERN_INFO "s2255 unknwn resp\n"); } - default: pdata++; - break; } - if (bframe) - break; - } /* for */ - if (!bframe) - return -EINVAL; - } - - - idx = dev->cur_frame[dev->cc]; - frm = &dev->buffer[dev->cc].frame[idx]; + if (bsync == 0) + return -EINVAL; + } else { + u32 *pword; + u32 payload; + int cc; + dbgsync = 0; + bsync = 1; + pword = (u32 *) pipe_info->transfer_buffer; + cc = pword[1]; + + if (cc >= MAX_CHANNELS) { + printk("invalid channel found. " + "throwing out data!\n"); + return -EINVAL; + } + dev->cc = G_chnmap[cc]; + payload = pword[2]; + if (payload != dev->req_image_size[dev->cc]) { + dprintk(1, "[%d][%d]unexpected payload: %d" + "required: %lu \n", cc, dev->cc, + payload, dev->req_image_size[dev->cc]); + dev->bad_payload[dev->cc]++; + /* discard the bad frame */ + return -EINVAL; + } - /* search done. now find out if should be acquiring on this channel */ + } + } + /* search done. now find out if should be acquiring + on this channel */ if (!dev->b_acquire[dev->cc]) { - /* we found a frame, but this channel is turned off */ - frm->ulState = S2255_READ_IDLE; + frm->ulState = 0; return -EINVAL; } - if (frm->ulState == S2255_READ_IDLE) { - frm->ulState = S2255_READ_FRAME; + idx = dev->cur_frame[dev->cc]; + frm = &dev->buffer[dev->cc].frame[idx]; + + if (frm->ulState == 0) { + frm->ulState = 1; + frm->cur_size = 0; + } else if (frm->ulState == 2) { + /* system frame ring buffer overrun */ + dprintk(2, "sys frame overrun. overwriting frame %d %d\n", + dev->cc, idx); + frm->ulState = 1; frm->cur_size = 0; } - /* skip the marker 512 bytes (and offset if out of sync) */ - psrc = (u8 *)pipe_info->transfer_buffer + offset; - + if (bsync) { + /* skip the marker 512 bytes (and offset if out of sync) */ + psrc = (u8 *)pipe_info->transfer_buffer + offset + PREFIX_SIZE; + } else { + psrc = (u8 *)pipe_info->transfer_buffer; + } if (frm->lpvbits == NULL) { dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d", @@ -1990,20 +1911,33 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) pdest = frm->lpvbits + frm->cur_size; - copy_size = (pipe_info->cur_transfer_size - offset); + if (bsync) { + copy_size = + (pipe_info->cur_transfer_size - offset) - PREFIX_SIZE; + if (copy_size > pipe_info->cur_transfer_size) { + printk("invalid copy size, overflow!\n"); + return -ENOMEM; + } + } else { + copy_size = pipe_info->cur_transfer_size; + } - size = dev->pkt_size[dev->cc] - PREFIX_SIZE; + cur_size = frm->cur_size; + size = dev->req_image_size[dev->cc]; - /* sanity check on pdest */ - if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc]) - memcpy(pdest, psrc, copy_size); + if ((copy_size + cur_size) > size) { + copy_size = size - cur_size; + btrunc = 1; + } + memcpy(pdest, psrc, copy_size); + cur_size += copy_size; frm->cur_size += copy_size; - dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size); - - if (frm->cur_size >= size) { + dprintk(50, "cur_size size %lu size %lu \n", cur_size, size); + if (cur_size >= (size - PREFIX_SIZE)) { u32 cc = dev->cc; + frm->ulState = 2; dprintk(2, "****************[%d]Buffer[%d]full*************\n", cc, idx); dev->last_frame[cc] = dev->cur_frame[cc]; @@ -2012,13 +1946,16 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) if ((dev->cur_frame[cc] == SYS_FRAMES) || (dev->cur_frame[cc] == dev->buffer[cc].dwFrames)) dev->cur_frame[cc] = 0; - /* frame ready */ + + /* signal the semaphore for this channel */ if (dev->b_acquire[cc]) - s2255_got_frame(dev, cc, dev->jpg_size[cc]); + s2255_got_frame(dev, cc); dev->frame_count[cc]++; - frm->ulState = S2255_READ_IDLE; - frm->cur_size = 0; - + } + /* frame was truncated */ + if (btrunc) { + /* return more data to process */ + return EAGAIN; } /* done successfully */ return 0; @@ -2037,8 +1974,8 @@ static void s2255_read_video_callback(struct s2255_dev *dev, } /* otherwise copy to the system buffers */ res = save_frame(dev, pipe_info); - if (res != 0) - dprintk(4, "s2255: read callback failed\n"); + if (res == EAGAIN) + save_frame(dev, pipe_info); dprintk(50, "callback read video done\n"); return; @@ -2158,9 +2095,11 @@ static int s2255_board_init(struct s2255_dev *dev) memset(pipe, 0, sizeof(*pipe)); pipe->dev = dev; - pipe->cur_transfer_size = S2255_USB_XFER_SIZE; - pipe->max_transfer_size = S2255_USB_XFER_SIZE; + pipe->cur_transfer_size = DEFAULT_PIPE_USBBLOCK; + pipe->max_transfer_size = MAX_PIPE_USBBLOCK; + if (pipe->cur_transfer_size > pipe->max_transfer_size) + pipe->cur_transfer_size = pipe->max_transfer_size; pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, GFP_KERNEL); if (pipe->transfer_buffer == NULL) { @@ -2180,7 +2119,6 @@ static int s2255_board_init(struct s2255_dev *dev) for (j = 0; j < MAX_CHANNELS; j++) { dev->b_acquire[j] = 0; dev->mode[j] = mode_def; - dev->jc[j].quality = S2255_DEF_JPEG_QUAL; dev->cur_fmt[j] = &formats[0]; dev->mode[j].restart = 1; dev->req_image_size[j] = get_transfer_size(&mode_def); @@ -2385,7 +2323,7 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn) kfree(buffer); dev->b_acquire[chn] = 0; - return res; + return 0; } static void s2255_stop_readpipe(struct s2255_dev *dev) @@ -2421,10 +2359,8 @@ static void s2255_stop_readpipe(struct s2255_dev *dev) return; } -static void s2255_fwload_start(struct s2255_dev *dev, int reset) +static void s2255_fwload_start(struct s2255_dev *dev) { - if (reset) - s2255_reset_dsppower(dev); dev->fw_data->fw_size = dev->fw_data->fw->size; atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED); memcpy(dev->fw_data->pfw_data, @@ -2447,8 +2383,6 @@ static int s2255_probe(struct usb_interface *interface, struct usb_endpoint_descriptor *endpoint; int i; int retval = -ENOMEM; - __le32 *pdata; - int fw_size; dprintk(2, "s2255: probe\n"); @@ -2503,8 +2437,6 @@ static int s2255_probe(struct usb_interface *interface, dev->timer.data = (unsigned long)dev->fw_data; init_waitqueue_head(&dev->fw_data->wait_fw); - for (i = 0; i < MAX_CHANNELS; i++) - init_waitqueue_head(&dev->wait_setmode[i]); dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); @@ -2524,30 +2456,16 @@ static int s2255_probe(struct usb_interface *interface, printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); goto error; } - /* check the firmware is valid */ - fw_size = dev->fw_data->fw->size; - pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8]; - if (*pdata != S2255_FW_MARKER) { - printk(KERN_INFO "Firmware invalid.\n"); - retval = -ENODEV; - goto error; - } else { - /* make sure firmware is the latest */ - __le32 *pRel; - pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; - printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); - } /* loads v4l specific */ s2255_probe_v4l(dev); - usb_reset_device(dev->udev); /* load 2255 board specific */ s2255_board_init(dev); dprintk(4, "before probe done %p\n", dev); spin_lock_init(&dev->slock); - s2255_fwload_start(dev, 0); + s2255_fwload_start(dev); dev_info(&interface->dev, "Sensoray 2255 detected\n"); return 0; error: @@ -2558,30 +2476,14 @@ static int s2255_probe(struct usb_interface *interface, static void s2255_disconnect(struct usb_interface *interface) { struct s2255_dev *dev = NULL; - int i; dprintk(1, "s2255: disconnect interface %p\n", interface); dev = usb_get_intfdata(interface); - - /* - * wake up any of the timers to allow open_lock to be - * acquired sooner - */ - atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); - wake_up(&dev->fw_data->wait_fw); - for (i = 0; i < MAX_CHANNELS; i++) { - dev->setmode_ready[i] = 1; - wake_up(&dev->wait_setmode[i]); - } - - mutex_lock(&dev->open_lock); - usb_set_intfdata(interface, NULL); - mutex_unlock(&dev->open_lock); - if (dev) { kref_put(&dev->kref, s2255_destroy); dprintk(1, "s2255drv: disconnect\n"); dev_info(&interface->dev, "s2255usb now disconnected\n"); } + usb_set_intfdata(interface, NULL); } static struct usb_driver s2255_driver = { diff --git a/trunk/drivers/media/video/saa5246a.c b/trunk/drivers/media/video/saa5246a.c index 4a21b8a6a709..6ee63e69b36c 100644 --- a/trunk/drivers/media/video/saa5246a.c +++ b/trunk/drivers/media/video/saa5246a.c @@ -43,364 +43,136 @@ #include #include #include -#include -#include #include #include #include #include -#include +#include + +#include "saa5246a.h" MODULE_AUTHOR("Michael Geng "); MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver"); MODULE_LICENSE("GPL"); -#define MAJOR_VERSION 1 /* driver major version number */ -#define MINOR_VERSION 8 /* driver minor version number */ - -/* Number of DAUs = number of pages that can be searched at the same time. */ -#define NUM_DAUS 4 - -#define NUM_ROWS_PER_PAGE 40 - -/* first column is 0 (not 1) */ -#define POS_TIME_START 32 -#define POS_TIME_END 39 - -#define POS_HEADER_START 7 -#define POS_HEADER_END 31 - -/* Returns 'true' if the part of the videotext page described with req contains - (at least parts of) the time field */ -#define REQ_CONTAINS_TIME(p_req) \ - ((p_req)->start <= POS_TIME_END && \ - (p_req)->end >= POS_TIME_START) - -/* Returns 'true' if the part of the videotext page described with req contains - (at least parts of) the page header */ -#define REQ_CONTAINS_HEADER(p_req) \ - ((p_req)->start <= POS_HEADER_END && \ - (p_req)->end >= POS_HEADER_START) - -/*****************************************************************************/ -/* Mode register numbers of the SAA5246A */ -/*****************************************************************************/ -#define SAA5246A_REGISTER_R0 0 -#define SAA5246A_REGISTER_R1 1 -#define SAA5246A_REGISTER_R2 2 -#define SAA5246A_REGISTER_R3 3 -#define SAA5246A_REGISTER_R4 4 -#define SAA5246A_REGISTER_R5 5 -#define SAA5246A_REGISTER_R6 6 -#define SAA5246A_REGISTER_R7 7 -#define SAA5246A_REGISTER_R8 8 -#define SAA5246A_REGISTER_R9 9 -#define SAA5246A_REGISTER_R10 10 -#define SAA5246A_REGISTER_R11 11 -#define SAA5246A_REGISTER_R11B 11 - -/* SAA5246A mode registers often autoincrement to the next register. - Therefore we use variable argument lists. The following macro indicates - the end of a command list. */ -#define COMMAND_END (-1) - -/*****************************************************************************/ -/* Contents of the mode registers of the SAA5246A */ -/*****************************************************************************/ -/* Register R0 (Advanced Control) */ -#define R0_SELECT_R11 0x00 -#define R0_SELECT_R11B 0x01 - -#define R0_PLL_TIME_CONSTANT_LONG 0x00 -#define R0_PLL_TIME_CONSTANT_SHORT 0x02 - -#define R0_ENABLE_nODD_EVEN_OUTPUT 0x00 -#define R0_DISABLE_nODD_EVEN_OUTPUT 0x04 - -#define R0_ENABLE_HDR_POLL 0x00 -#define R0_DISABLE_HDR_POLL 0x10 - -#define R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x00 -#define R0_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x20 - -#define R0_NO_FREE_RUN_PLL 0x00 -#define R0_FREE_RUN_PLL 0x40 - -#define R0_NO_AUTOMATIC_FASTEXT_PROMPT 0x00 -#define R0_AUTOMATIC_FASTEXT_PROMPT 0x80 - -/* Register R1 (Mode) */ -#define R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES 0x00 -#define R1_NON_INTERLACED_312_313_LINES 0x01 -#define R1_NON_INTERLACED_312_312_LINES 0x02 -#define R1_FFB_LEADING_EDGE_IN_FIRST_BROAD_PULSE 0x03 -#define R1_FFB_LEADING_EDGE_IN_SECOND_BROAD_PULSE 0x07 - -#define R1_DEW 0x00 -#define R1_FULL_FIELD 0x08 - -#define R1_EXTENDED_PACKET_DISABLE 0x00 -#define R1_EXTENDED_PACKET_ENABLE 0x10 - -#define R1_DAUS_ALL_ON 0x00 -#define R1_DAUS_ALL_OFF 0x20 - -#define R1_7_BITS_PLUS_PARITY 0x00 -#define R1_8_BITS_NO_PARITY 0x40 - -#define R1_VCS_TO_SCS 0x00 -#define R1_NO_VCS_TO_SCS 0x80 - -/* Register R2 (Page request address) */ -#define R2_IN_R3_SELECT_PAGE_HUNDREDS 0x00 -#define R2_IN_R3_SELECT_PAGE_TENS 0x01 -#define R2_IN_R3_SELECT_PAGE_UNITS 0x02 -#define R2_IN_R3_SELECT_HOURS_TENS 0x03 -#define R2_IN_R3_SELECT_HOURS_UNITS 0x04 -#define R2_IN_R3_SELECT_MINUTES_TENS 0x05 -#define R2_IN_R3_SELECT_MINUTES_UNITS 0x06 - -#define R2_DAU_0 0x00 -#define R2_DAU_1 0x10 -#define R2_DAU_2 0x20 -#define R2_DAU_3 0x30 - -#define R2_BANK_0 0x00 -#define R2_BANK 1 0x40 - -#define R2_HAMMING_CHECK_ON 0x80 -#define R2_HAMMING_CHECK_OFF 0x00 - -/* Register R3 (Page request data) */ -#define R3_PAGE_HUNDREDS_0 0x00 -#define R3_PAGE_HUNDREDS_1 0x01 -#define R3_PAGE_HUNDREDS_2 0x02 -#define R3_PAGE_HUNDREDS_3 0x03 -#define R3_PAGE_HUNDREDS_4 0x04 -#define R3_PAGE_HUNDREDS_5 0x05 -#define R3_PAGE_HUNDREDS_6 0x06 -#define R3_PAGE_HUNDREDS_7 0x07 - -#define R3_HOLD_PAGE 0x00 -#define R3_UPDATE_PAGE 0x08 - -#define R3_PAGE_HUNDREDS_DO_NOT_CARE 0x00 -#define R3_PAGE_HUNDREDS_DO_CARE 0x10 - -#define R3_PAGE_TENS_DO_NOT_CARE 0x00 -#define R3_PAGE_TENS_DO_CARE 0x10 - -#define R3_PAGE_UNITS_DO_NOT_CARE 0x00 -#define R3_PAGE_UNITS_DO_CARE 0x10 - -#define R3_HOURS_TENS_DO_NOT_CARE 0x00 -#define R3_HOURS_TENS_DO_CARE 0x10 - -#define R3_HOURS_UNITS_DO_NOT_CARE 0x00 -#define R3_HOURS_UNITS_DO_CARE 0x10 - -#define R3_MINUTES_TENS_DO_NOT_CARE 0x00 -#define R3_MINUTES_TENS_DO_CARE 0x10 - -#define R3_MINUTES_UNITS_DO_NOT_CARE 0x00 -#define R3_MINUTES_UNITS_DO_CARE 0x10 - -/* Register R4 (Display chapter) */ -#define R4_DISPLAY_PAGE_0 0x00 -#define R4_DISPLAY_PAGE_1 0x01 -#define R4_DISPLAY_PAGE_2 0x02 -#define R4_DISPLAY_PAGE_3 0x03 -#define R4_DISPLAY_PAGE_4 0x04 -#define R4_DISPLAY_PAGE_5 0x05 -#define R4_DISPLAY_PAGE_6 0x06 -#define R4_DISPLAY_PAGE_7 0x07 - -/* Register R5 (Normal display control) */ -#define R5_PICTURE_INSIDE_BOXING_OFF 0x00 -#define R5_PICTURE_INSIDE_BOXING_ON 0x01 - -#define R5_PICTURE_OUTSIDE_BOXING_OFF 0x00 -#define R5_PICTURE_OUTSIDE_BOXING_ON 0x02 - -#define R5_TEXT_INSIDE_BOXING_OFF 0x00 -#define R5_TEXT_INSIDE_BOXING_ON 0x04 - -#define R5_TEXT_OUTSIDE_BOXING_OFF 0x00 -#define R5_TEXT_OUTSIDE_BOXING_ON 0x08 - -#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00 -#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10 - -#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00 -#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20 - -#define R5_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00 -#define R5_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40 - -#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00 -#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80 - -/* Register R6 (Newsflash display) */ -#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_ON 0x01 - -#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_ON 0x02 - -#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_ON 0x04 - -#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_ON 0x08 - -#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10 - -#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20 - -#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40 - -#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00 -#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80 - -/* Register R7 (Display mode) */ -#define R7_BOX_OFF_ROW_0 0x00 -#define R7_BOX_ON_ROW_0 0x01 - -#define R7_BOX_OFF_ROW_1_TO_23 0x00 -#define R7_BOX_ON_ROW_1_TO_23 0x02 - -#define R7_BOX_OFF_ROW_24 0x00 -#define R7_BOX_ON_ROW_24 0x04 - -#define R7_SINGLE_HEIGHT 0x00 -#define R7_DOUBLE_HEIGHT 0x08 - -#define R7_TOP_HALF 0x00 -#define R7_BOTTOM_HALF 0x10 - -#define R7_REVEAL_OFF 0x00 -#define R7_REVEAL_ON 0x20 - -#define R7_CURSER_OFF 0x00 -#define R7_CURSER_ON 0x40 - -#define R7_STATUS_BOTTOM 0x00 -#define R7_STATUS_TOP 0x80 - -/* Register R8 (Active chapter) */ -#define R8_ACTIVE_CHAPTER_0 0x00 -#define R8_ACTIVE_CHAPTER_1 0x01 -#define R8_ACTIVE_CHAPTER_2 0x02 -#define R8_ACTIVE_CHAPTER_3 0x03 -#define R8_ACTIVE_CHAPTER_4 0x04 -#define R8_ACTIVE_CHAPTER_5 0x05 -#define R8_ACTIVE_CHAPTER_6 0x06 -#define R8_ACTIVE_CHAPTER_7 0x07 - -#define R8_CLEAR_MEMORY 0x08 -#define R8_DO_NOT_CLEAR_MEMORY 0x00 - -/* Register R9 (Curser row) */ -#define R9_CURSER_ROW_0 0x00 -#define R9_CURSER_ROW_1 0x01 -#define R9_CURSER_ROW_2 0x02 -#define R9_CURSER_ROW_25 0x19 - -/* Register R10 (Curser column) */ -#define R10_CURSER_COLUMN_0 0x00 -#define R10_CURSER_COLUMN_6 0x06 -#define R10_CURSER_COLUMN_8 0x08 - -/*****************************************************************************/ -/* Row 25 control data in column 0 to 9 */ -/*****************************************************************************/ -#define ROW25_COLUMN0_PAGE_UNITS 0x0F - -#define ROW25_COLUMN1_PAGE_TENS 0x0F - -#define ROW25_COLUMN2_MINUTES_UNITS 0x0F +struct saa5246a_device +{ + u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; + int is_searching[NUM_DAUS]; + struct i2c_client *client; + struct mutex lock; +}; -#define ROW25_COLUMN3_MINUTES_TENS 0x07 -#define ROW25_COLUMN3_DELETE_PAGE 0x08 +static struct video_device saa_template; /* Declared near bottom */ -#define ROW25_COLUMN4_HOUR_UNITS 0x0F +/* Addresses to scan */ +static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END }; -#define ROW25_COLUMN5_HOUR_TENS 0x03 -#define ROW25_COLUMN5_INSERT_HEADLINE 0x04 -#define ROW25_COLUMN5_INSERT_SUBTITLE 0x08 +I2C_CLIENT_INSMOD; -#define ROW25_COLUMN6_SUPPRESS_HEADER 0x01 -#define ROW25_COLUMN6_UPDATE_PAGE 0x02 -#define ROW25_COLUMN6_INTERRUPTED_SEQUENCE 0x04 -#define ROW25_COLUMN6_SUPPRESS_DISPLAY 0x08 +static struct i2c_client client_template; -#define ROW25_COLUMN7_SERIAL_MODE 0x01 -#define ROW25_COLUMN7_CHARACTER_SET 0x0E +static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind) +{ + int pgbuf; + int err; + struct i2c_client *client; + struct video_device *vd; + struct saa5246a_device *t; -#define ROW25_COLUMN8_PAGE_HUNDREDS 0x07 -#define ROW25_COLUMN8_PAGE_NOT_FOUND 0x10 + printk(KERN_INFO "saa5246a: teletext chip found.\n"); + client=kmalloc(sizeof(*client), GFP_KERNEL); + if(client==NULL) + return -ENOMEM; + client_template.adapter = adap; + client_template.addr = addr; + memcpy(client, &client_template, sizeof(*client)); + t = kzalloc(sizeof(*t), GFP_KERNEL); + if(t==NULL) + { + kfree(client); + return -ENOMEM; + } + strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); + mutex_init(&t->lock); -#define ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR 0x20 + /* + * Now create a video4linux device + */ -#define ROW25_COLUMN0_TO_7_HAMMING_ERROR 0x10 + vd = video_device_alloc(); + if(vd==NULL) + { + kfree(t); + kfree(client); + return -ENOMEM; + } + i2c_set_clientdata(client, vd); + memcpy(vd, &saa_template, sizeof(*vd)); -/*****************************************************************************/ -/* Helper macros for extracting page, hour and minute digits */ -/*****************************************************************************/ -/* BYTE_POS 0 is at row 0, column 0, - BYTE_POS 1 is at row 0, column 1, - BYTE_POS 40 is at row 1, column 0, (with NUM_ROWS_PER_PAGE = 40) - BYTE_POS 41 is at row 1, column 1, (with NUM_ROWS_PER_PAGE = 40), - ... */ -#define ROW(BYTE_POS) (BYTE_POS / NUM_ROWS_PER_PAGE) -#define COLUMN(BYTE_POS) (BYTE_POS % NUM_ROWS_PER_PAGE) + for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) + { + memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); + t->is_searching[pgbuf] = false; + } + vd->priv=t; -/*****************************************************************************/ -/* Helper macros for extracting page, hour and minute digits */ -/*****************************************************************************/ -/* Macros for extracting hundreds, tens and units of a page number which - must be in the range 0 ... 0x799. - Note that page is coded in hexadecimal, i.e. 0x123 means page 123. - page 0x.. means page 8.. */ -#define HUNDREDS_OF_PAGE(page) (((page) / 0x100) & 0x7) -#define TENS_OF_PAGE(page) (((page) / 0x10) & 0xF) -#define UNITS_OF_PAGE(page) ((page) & 0xF) -/* Macros for extracting tens and units of a hour information which - must be in the range 0 ... 0x24. - Note that hour is coded in hexadecimal, i.e. 0x12 means 12 hours */ -#define TENS_OF_HOUR(hour) ((hour) / 0x10) -#define UNITS_OF_HOUR(hour) ((hour) & 0xF) - -/* Macros for extracting tens and units of a minute information which - must be in the range 0 ... 0x59. - Note that minute is coded in hexadecimal, i.e. 0x12 means 12 minutes */ -#define TENS_OF_MINUTE(minute) ((minute) / 0x10) -#define UNITS_OF_MINUTE(minute) ((minute) & 0xF) - -#define HOUR_MAX 0x23 -#define MINUTE_MAX 0x59 -#define PAGE_MAX 0x8FF + /* + * Register it + */ + if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0) + { + kfree(t); + kfree(client); + video_device_release(vd); + return err; + } + t->client = client; + i2c_attach_client(client); + return 0; +} -struct saa5246a_device +/* + * We do most of the hard work when we become a device on the i2c. + */ +static int saa5246a_probe(struct i2c_adapter *adap) { - u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; - int is_searching[NUM_DAUS]; - struct i2c_client *client; - unsigned long in_use; - struct mutex lock; -}; + if (adap->class & I2C_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, saa5246a_attach); + return 0; +} -static struct video_device saa_template; /* Declared near bottom */ +static int saa5246a_detach(struct i2c_client *client) +{ + struct video_device *vd = i2c_get_clientdata(client); + i2c_detach_client(client); + video_unregister_device(vd); + kfree(vd->priv); + kfree(client); + return 0; +} /* * I2C interfaces */ +static struct i2c_driver i2c_driver_videotext = +{ + .driver = { + .name = IF_NAME, /* name */ + }, + .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ + .attach_adapter = saa5246a_probe, + .detach_client = saa5246a_detach, +}; + +static struct i2c_client client_template = { + .driver = &i2c_driver_videotext, + .name = "(unset)", +}; + static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data) { char buf[64]; @@ -807,8 +579,8 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t, static int do_saa5246a_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct saa5246a_device *t = video_drvdata(file); - + struct video_device *vd = video_devdata(file); + struct saa5246a_device *t=vd->priv; switch(cmd) { case VTXIOCGETINFO: @@ -948,7 +720,8 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) static int saa5246a_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct saa5246a_device *t = video_drvdata(file); + struct video_device *vd = video_devdata(file); + struct saa5246a_device *t = vd->priv; int err; cmd = vtx_fix_command(cmd); @@ -960,15 +733,21 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file, static int saa5246a_open(struct inode *inode, struct file *file) { - struct saa5246a_device *t = video_drvdata(file); + struct video_device *vd = video_devdata(file); + struct saa5246a_device *t = vd->priv; + int err; - if (t->client == NULL) - return -ENODEV; + err = video_exclusive_open(inode,file); + if (err < 0) + return err; - if (test_and_set_bit(0, &t->in_use)) - return -EBUSY; + if (t->client==NULL) { + err = -ENODEV; + goto fail; + } if (i2c_senddata(t, SAA5246A_REGISTER_R0, + R0_SELECT_R11 | R0_PLL_TIME_CONSTANT_LONG | R0_ENABLE_nODD_EVEN_OUTPUT | @@ -994,15 +773,21 @@ static int saa5246a_open(struct inode *inode, struct file *file) COMMAND_END)) { - clear_bit(0, &t->in_use); - return -EIO; + err = -EIO; + goto fail; } + return 0; + +fail: + video_exclusive_release(inode,file); + return err; } static int saa5246a_release(struct inode *inode, struct file *file) { - struct saa5246a_device *t = video_drvdata(file); + struct video_device *vd = video_devdata(file); + struct saa5246a_device *t = vd->priv; /* Stop all acquisition circuits. */ i2c_senddata(t, SAA5246A_REGISTER_R1, @@ -1015,10 +800,26 @@ static int saa5246a_release(struct inode *inode, struct file *file) R1_VCS_TO_SCS, COMMAND_END); - clear_bit(0, &t->in_use); + video_exclusive_release(inode,file); return 0; } +static int __init init_saa_5246a (void) +{ + printk(KERN_INFO + "SAA5246A (or compatible) Teletext decoder driver version %d.%d\n", + MAJOR_VERSION, MINOR_VERSION); + return i2c_add_driver(&i2c_driver_videotext); +} + +static void __exit cleanup_saa_5246a (void) +{ + i2c_del_driver(&i2c_driver_videotext); +} + +module_init(init_saa_5246a); +module_exit(cleanup_saa_5246a); + static const struct file_operations saa_fops = { .owner = THIS_MODULE, .open = saa5246a_open, @@ -1029,79 +830,8 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { - .name = "saa5246a", + .name = IF_NAME, .fops = &saa_fops, .release = video_device_release, .minor = -1, }; - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - -static int saa5246a_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int pgbuf; - int err; - struct video_device *vd; - struct saa5246a_device *t; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - v4l_info(client, "VideoText version %d.%d\n", - MAJOR_VERSION, MINOR_VERSION); - t = kzalloc(sizeof(*t), GFP_KERNEL); - if (t == NULL) - return -ENOMEM; - mutex_init(&t->lock); - - /* Now create a video4linux device */ - vd = video_device_alloc(); - if (vd == NULL) { - kfree(t); - return -ENOMEM; - } - i2c_set_clientdata(client, vd); - memcpy(vd, &saa_template, sizeof(*vd)); - - for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { - memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); - t->is_searching[pgbuf] = false; - } - video_set_drvdata(vd, t); - - /* Register it */ - err = video_register_device(vd, VFL_TYPE_VTX, -1); - if (err < 0) { - kfree(t); - video_device_release(vd); - return err; - } - t->client = client; - return 0; -} - -static int saa5246a_remove(struct i2c_client *client) -{ - struct video_device *vd = i2c_get_clientdata(client); - - video_unregister_device(vd); - kfree(video_get_drvdata(vd)); - return 0; -} - -static const struct i2c_device_id saa5246a_id[] = { - { "saa5246a", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa5246a_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa5246a", - .driverid = I2C_DRIVERID_SAA5249, - .probe = saa5246a_probe, - .remove = saa5246a_remove, - .id_table = saa5246a_id, -}; diff --git a/trunk/drivers/media/video/saa5246a.h b/trunk/drivers/media/video/saa5246a.h new file mode 100644 index 000000000000..64394c036c60 --- /dev/null +++ b/trunk/drivers/media/video/saa5246a.h @@ -0,0 +1,359 @@ +/* + Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from + Philips. + + Copyright (C) 2004 Michael Geng (linux@MichaelGeng.de) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ +#ifndef __SAA5246A_H__ +#define __SAA5246A_H__ + +#define MAJOR_VERSION 1 /* driver major version number */ +#define MINOR_VERSION 8 /* driver minor version number */ + +#define IF_NAME "SAA5246A" + +#define I2C_ADDRESS 17 + +/* Number of DAUs = number of pages that can be searched at the same time. */ +#define NUM_DAUS 4 + +#define NUM_ROWS_PER_PAGE 40 + +/* first column is 0 (not 1) */ +#define POS_TIME_START 32 +#define POS_TIME_END 39 + +#define POS_HEADER_START 7 +#define POS_HEADER_END 31 + +/* Returns 'true' if the part of the videotext page described with req contains + (at least parts of) the time field */ +#define REQ_CONTAINS_TIME(p_req) \ + ((p_req)->start <= POS_TIME_END && \ + (p_req)->end >= POS_TIME_START) + +/* Returns 'true' if the part of the videotext page described with req contains + (at least parts of) the page header */ +#define REQ_CONTAINS_HEADER(p_req) \ + ((p_req)->start <= POS_HEADER_END && \ + (p_req)->end >= POS_HEADER_START) + +/*****************************************************************************/ +/* Mode register numbers of the SAA5246A */ +/*****************************************************************************/ +#define SAA5246A_REGISTER_R0 0 +#define SAA5246A_REGISTER_R1 1 +#define SAA5246A_REGISTER_R2 2 +#define SAA5246A_REGISTER_R3 3 +#define SAA5246A_REGISTER_R4 4 +#define SAA5246A_REGISTER_R5 5 +#define SAA5246A_REGISTER_R6 6 +#define SAA5246A_REGISTER_R7 7 +#define SAA5246A_REGISTER_R8 8 +#define SAA5246A_REGISTER_R9 9 +#define SAA5246A_REGISTER_R10 10 +#define SAA5246A_REGISTER_R11 11 +#define SAA5246A_REGISTER_R11B 11 + +/* SAA5246A mode registers often autoincrement to the next register. + Therefore we use variable argument lists. The following macro indicates + the end of a command list. */ +#define COMMAND_END (- 1) + +/*****************************************************************************/ +/* Contents of the mode registers of the SAA5246A */ +/*****************************************************************************/ +/* Register R0 (Advanced Control) */ +#define R0_SELECT_R11 0x00 +#define R0_SELECT_R11B 0x01 + +#define R0_PLL_TIME_CONSTANT_LONG 0x00 +#define R0_PLL_TIME_CONSTANT_SHORT 0x02 + +#define R0_ENABLE_nODD_EVEN_OUTPUT 0x00 +#define R0_DISABLE_nODD_EVEN_OUTPUT 0x04 + +#define R0_ENABLE_HDR_POLL 0x00 +#define R0_DISABLE_HDR_POLL 0x10 + +#define R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x00 +#define R0_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x20 + +#define R0_NO_FREE_RUN_PLL 0x00 +#define R0_FREE_RUN_PLL 0x40 + +#define R0_NO_AUTOMATIC_FASTEXT_PROMPT 0x00 +#define R0_AUTOMATIC_FASTEXT_PROMPT 0x80 + +/* Register R1 (Mode) */ +#define R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES 0x00 +#define R1_NON_INTERLACED_312_313_LINES 0x01 +#define R1_NON_INTERLACED_312_312_LINES 0x02 +#define R1_FFB_LEADING_EDGE_IN_FIRST_BROAD_PULSE 0x03 +#define R1_FFB_LEADING_EDGE_IN_SECOND_BROAD_PULSE 0x07 + +#define R1_DEW 0x00 +#define R1_FULL_FIELD 0x08 + +#define R1_EXTENDED_PACKET_DISABLE 0x00 +#define R1_EXTENDED_PACKET_ENABLE 0x10 + +#define R1_DAUS_ALL_ON 0x00 +#define R1_DAUS_ALL_OFF 0x20 + +#define R1_7_BITS_PLUS_PARITY 0x00 +#define R1_8_BITS_NO_PARITY 0x40 + +#define R1_VCS_TO_SCS 0x00 +#define R1_NO_VCS_TO_SCS 0x80 + +/* Register R2 (Page request address) */ +#define R2_IN_R3_SELECT_PAGE_HUNDREDS 0x00 +#define R2_IN_R3_SELECT_PAGE_TENS 0x01 +#define R2_IN_R3_SELECT_PAGE_UNITS 0x02 +#define R2_IN_R3_SELECT_HOURS_TENS 0x03 +#define R2_IN_R3_SELECT_HOURS_UNITS 0x04 +#define R2_IN_R3_SELECT_MINUTES_TENS 0x05 +#define R2_IN_R3_SELECT_MINUTES_UNITS 0x06 + +#define R2_DAU_0 0x00 +#define R2_DAU_1 0x10 +#define R2_DAU_2 0x20 +#define R2_DAU_3 0x30 + +#define R2_BANK_0 0x00 +#define R2_BANK 1 0x40 + +#define R2_HAMMING_CHECK_ON 0x80 +#define R2_HAMMING_CHECK_OFF 0x00 + +/* Register R3 (Page request data) */ +#define R3_PAGE_HUNDREDS_0 0x00 +#define R3_PAGE_HUNDREDS_1 0x01 +#define R3_PAGE_HUNDREDS_2 0x02 +#define R3_PAGE_HUNDREDS_3 0x03 +#define R3_PAGE_HUNDREDS_4 0x04 +#define R3_PAGE_HUNDREDS_5 0x05 +#define R3_PAGE_HUNDREDS_6 0x06 +#define R3_PAGE_HUNDREDS_7 0x07 + +#define R3_HOLD_PAGE 0x00 +#define R3_UPDATE_PAGE 0x08 + +#define R3_PAGE_HUNDREDS_DO_NOT_CARE 0x00 +#define R3_PAGE_HUNDREDS_DO_CARE 0x10 + +#define R3_PAGE_TENS_DO_NOT_CARE 0x00 +#define R3_PAGE_TENS_DO_CARE 0x10 + +#define R3_PAGE_UNITS_DO_NOT_CARE 0x00 +#define R3_PAGE_UNITS_DO_CARE 0x10 + +#define R3_HOURS_TENS_DO_NOT_CARE 0x00 +#define R3_HOURS_TENS_DO_CARE 0x10 + +#define R3_HOURS_UNITS_DO_NOT_CARE 0x00 +#define R3_HOURS_UNITS_DO_CARE 0x10 + +#define R3_MINUTES_TENS_DO_NOT_CARE 0x00 +#define R3_MINUTES_TENS_DO_CARE 0x10 + +#define R3_MINUTES_UNITS_DO_NOT_CARE 0x00 +#define R3_MINUTES_UNITS_DO_CARE 0x10 + +/* Register R4 (Display chapter) */ +#define R4_DISPLAY_PAGE_0 0x00 +#define R4_DISPLAY_PAGE_1 0x01 +#define R4_DISPLAY_PAGE_2 0x02 +#define R4_DISPLAY_PAGE_3 0x03 +#define R4_DISPLAY_PAGE_4 0x04 +#define R4_DISPLAY_PAGE_5 0x05 +#define R4_DISPLAY_PAGE_6 0x06 +#define R4_DISPLAY_PAGE_7 0x07 + +/* Register R5 (Normal display control) */ +#define R5_PICTURE_INSIDE_BOXING_OFF 0x00 +#define R5_PICTURE_INSIDE_BOXING_ON 0x01 + +#define R5_PICTURE_OUTSIDE_BOXING_OFF 0x00 +#define R5_PICTURE_OUTSIDE_BOXING_ON 0x02 + +#define R5_TEXT_INSIDE_BOXING_OFF 0x00 +#define R5_TEXT_INSIDE_BOXING_ON 0x04 + +#define R5_TEXT_OUTSIDE_BOXING_OFF 0x00 +#define R5_TEXT_OUTSIDE_BOXING_ON 0x08 + +#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00 +#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10 + +#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00 +#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20 + +#define R5_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00 +#define R5_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40 + +#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00 +#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80 + +/* Register R6 (Newsflash display) */ +#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_ON 0x01 + +#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_ON 0x02 + +#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_ON 0x04 + +#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_ON 0x08 + +#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10 + +#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20 + +#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40 + +#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00 +#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80 + +/* Register R7 (Display mode) */ +#define R7_BOX_OFF_ROW_0 0x00 +#define R7_BOX_ON_ROW_0 0x01 + +#define R7_BOX_OFF_ROW_1_TO_23 0x00 +#define R7_BOX_ON_ROW_1_TO_23 0x02 + +#define R7_BOX_OFF_ROW_24 0x00 +#define R7_BOX_ON_ROW_24 0x04 + +#define R7_SINGLE_HEIGHT 0x00 +#define R7_DOUBLE_HEIGHT 0x08 + +#define R7_TOP_HALF 0x00 +#define R7_BOTTOM_HALF 0x10 + +#define R7_REVEAL_OFF 0x00 +#define R7_REVEAL_ON 0x20 + +#define R7_CURSER_OFF 0x00 +#define R7_CURSER_ON 0x40 + +#define R7_STATUS_BOTTOM 0x00 +#define R7_STATUS_TOP 0x80 + +/* Register R8 (Active chapter) */ +#define R8_ACTIVE_CHAPTER_0 0x00 +#define R8_ACTIVE_CHAPTER_1 0x01 +#define R8_ACTIVE_CHAPTER_2 0x02 +#define R8_ACTIVE_CHAPTER_3 0x03 +#define R8_ACTIVE_CHAPTER_4 0x04 +#define R8_ACTIVE_CHAPTER_5 0x05 +#define R8_ACTIVE_CHAPTER_6 0x06 +#define R8_ACTIVE_CHAPTER_7 0x07 + +#define R8_CLEAR_MEMORY 0x08 +#define R8_DO_NOT_CLEAR_MEMORY 0x00 + +/* Register R9 (Curser row) */ +#define R9_CURSER_ROW_0 0x00 +#define R9_CURSER_ROW_1 0x01 +#define R9_CURSER_ROW_2 0x02 +#define R9_CURSER_ROW_25 0x19 + +/* Register R10 (Curser column) */ +#define R10_CURSER_COLUMN_0 0x00 +#define R10_CURSER_COLUMN_6 0x06 +#define R10_CURSER_COLUMN_8 0x08 + +/*****************************************************************************/ +/* Row 25 control data in column 0 to 9 */ +/*****************************************************************************/ +#define ROW25_COLUMN0_PAGE_UNITS 0x0F + +#define ROW25_COLUMN1_PAGE_TENS 0x0F + +#define ROW25_COLUMN2_MINUTES_UNITS 0x0F + +#define ROW25_COLUMN3_MINUTES_TENS 0x07 +#define ROW25_COLUMN3_DELETE_PAGE 0x08 + +#define ROW25_COLUMN4_HOUR_UNITS 0x0F + +#define ROW25_COLUMN5_HOUR_TENS 0x03 +#define ROW25_COLUMN5_INSERT_HEADLINE 0x04 +#define ROW25_COLUMN5_INSERT_SUBTITLE 0x08 + +#define ROW25_COLUMN6_SUPPRESS_HEADER 0x01 +#define ROW25_COLUMN6_UPDATE_PAGE 0x02 +#define ROW25_COLUMN6_INTERRUPTED_SEQUENCE 0x04 +#define ROW25_COLUMN6_SUPPRESS_DISPLAY 0x08 + +#define ROW25_COLUMN7_SERIAL_MODE 0x01 +#define ROW25_COLUMN7_CHARACTER_SET 0x0E + +#define ROW25_COLUMN8_PAGE_HUNDREDS 0x07 +#define ROW25_COLUMN8_PAGE_NOT_FOUND 0x10 + +#define ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR 0x20 + +#define ROW25_COLUMN0_TO_7_HAMMING_ERROR 0x10 + +/*****************************************************************************/ +/* Helper macros for extracting page, hour and minute digits */ +/*****************************************************************************/ +/* BYTE_POS 0 is at row 0, column 0, + BYTE_POS 1 is at row 0, column 1, + BYTE_POS 40 is at row 1, column 0, (with NUM_ROWS_PER_PAGE = 40) + BYTE_POS 41 is at row 1, column 1, (with NUM_ROWS_PER_PAGE = 40), + ... */ +#define ROW(BYTE_POS) (BYTE_POS / NUM_ROWS_PER_PAGE) +#define COLUMN(BYTE_POS) (BYTE_POS % NUM_ROWS_PER_PAGE) + +/*****************************************************************************/ +/* Helper macros for extracting page, hour and minute digits */ +/*****************************************************************************/ +/* Macros for extracting hundreds, tens and units of a page number which + must be in the range 0 ... 0x799. + Note that page is coded in hexadecimal, i.e. 0x123 means page 123. + page 0x.. means page 8.. */ +#define HUNDREDS_OF_PAGE(page) (((page) / 0x100) & 0x7) +#define TENS_OF_PAGE(page) (((page) / 0x10) & 0xF) +#define UNITS_OF_PAGE(page) ((page) & 0xF) + +/* Macros for extracting tens and units of a hour information which + must be in the range 0 ... 0x24. + Note that hour is coded in hexadecimal, i.e. 0x12 means 12 hours */ +#define TENS_OF_HOUR(hour) ((hour) / 0x10) +#define UNITS_OF_HOUR(hour) ((hour) & 0xF) + +/* Macros for extracting tens and units of a minute information which + must be in the range 0 ... 0x59. + Note that minute is coded in hexadecimal, i.e. 0x12 means 12 minutes */ +#define TENS_OF_MINUTE(minute) ((minute) / 0x10) +#define UNITS_OF_MINUTE(minute) ((minute) & 0xF) + +#define HOUR_MAX 0x23 +#define MINUTE_MAX 0x59 +#define PAGE_MAX 0x8FF + +#endif /* __SAA5246A_H__ */ diff --git a/trunk/drivers/media/video/saa5249.c b/trunk/drivers/media/video/saa5249.c index 3bb959c25d9d..0d639738d4e6 100644 --- a/trunk/drivers/media/video/saa5249.c +++ b/trunk/drivers/media/video/saa5249.c @@ -15,6 +15,8 @@ * * Copyright (c) 1998 Richard Guenther * + * $Id: saa5249.c,v 1.1 1998/03/30 22:23:23 alan Exp $ + * * Derived From * * vtx.c: @@ -43,28 +45,33 @@ #include #include +#include #include +#include +#include +#include +#include #include +#include #include -#include -#include -#include #include #include #include #include -#include +#include -MODULE_AUTHOR("Michael Geng "); -MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver"); -MODULE_LICENSE("GPL"); + +#include +#include #define VTX_VER_MAJ 1 #define VTX_VER_MIN 8 + #define NUM_DAUS 4 #define NUM_BUFS 8 +#define IF_NAME "SAA5249" static const int disp_modes[8][3] = { @@ -102,7 +109,6 @@ struct saa5249_device int disp_mode; int virtual_mode; struct i2c_client *client; - unsigned long in_use; struct mutex lock; }; @@ -117,8 +123,125 @@ struct saa5249_device #define VTX_DEV_MINOR 0 +/* General defines and debugging support */ + +#define RESCHED do { cond_resched(); } while(0) + static struct video_device saa_template; /* Declared near bottom */ +/* Addresses to scan */ +static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END}; + +I2C_CLIENT_INSMOD; + +static struct i2c_client client_template; + +static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) +{ + int pgbuf; + int err; + struct i2c_client *client; + struct video_device *vd; + struct saa5249_device *t; + + printk(KERN_INFO "saa5249: teletext chip found.\n"); + client=kmalloc(sizeof(*client), GFP_KERNEL); + if(client==NULL) + return -ENOMEM; + client_template.adapter = adap; + client_template.addr = addr; + memcpy(client, &client_template, sizeof(*client)); + t = kzalloc(sizeof(*t), GFP_KERNEL); + if(t==NULL) + { + kfree(client); + return -ENOMEM; + } + strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); + mutex_init(&t->lock); + + /* + * Now create a video4linux device + */ + + vd = kmalloc(sizeof(struct video_device), GFP_KERNEL); + if(vd==NULL) + { + kfree(t); + kfree(client); + return -ENOMEM; + } + i2c_set_clientdata(client, vd); + memcpy(vd, &saa_template, sizeof(*vd)); + + for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) + { + memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); + memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); + memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); + t->vdau[pgbuf].expire = 0; + t->vdau[pgbuf].clrfound = true; + t->vdau[pgbuf].stopped = true; + t->is_searching[pgbuf] = false; + } + vd->priv=t; + + + /* + * Register it + */ + + if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0) + { + kfree(t); + kfree(vd); + kfree(client); + return err; + } + t->client = client; + i2c_attach_client(client); + return 0; +} + +/* + * We do most of the hard work when we become a device on the i2c. + */ + +static int saa5249_probe(struct i2c_adapter *adap) +{ + if (adap->class & I2C_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, saa5249_attach); + return 0; +} + +static int saa5249_detach(struct i2c_client *client) +{ + struct video_device *vd = i2c_get_clientdata(client); + i2c_detach_client(client); + video_unregister_device(vd); + kfree(vd->priv); + kfree(vd); + kfree(client); + return 0; +} + +/* new I2C driver support */ + +static struct i2c_driver i2c_driver_videotext = +{ + .driver = { + .name = IF_NAME, /* name */ + }, + .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ + .attach_adapter = saa5249_probe, + .detach_client = saa5249_detach, +}; + +static struct i2c_client client_template = { + .driver = &i2c_driver_videotext, + .name = "(unset)", +}; + /* * Wait the given number of jiffies (10ms). This calls the scheduler, so the actual * delay may be longer. @@ -152,7 +275,7 @@ static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) buf[0] = reg; memcpy(buf+1, data, count); - if (i2c_master_send(t->client, buf, count + 1) == count + 1) + if(i2c_master_send(t->client, buf, count+1)==count+1) return 0; return -1; } @@ -194,236 +317,246 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { static int virtual_mode = false; - struct saa5249_device *t = video_drvdata(file); + struct video_device *vd = video_devdata(file); + struct saa5249_device *t=vd->priv; - switch (cmd) { - case VTXIOCGETINFO: + switch(cmd) { - vtx_info_t *info = arg; - info->version_major = VTX_VER_MAJ; - info->version_minor = VTX_VER_MIN; - info->numpages = NUM_DAUS; - /*info->cct_type = CCT_TYPE;*/ - return 0; - } - - case VTXIOCCLRPAGE: - { - vtx_pagereq_t *req = arg; + case VTXIOCGETINFO: + { + vtx_info_t *info = arg; + info->version_major = VTX_VER_MAJ; + info->version_minor = VTX_VER_MIN; + info->numpages = NUM_DAUS; + /*info->cct_type = CCT_TYPE;*/ + return 0; + } - if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) - return -EINVAL; - memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); - t->vdau[req->pgbuf].clrfound = true; - return 0; - } + case VTXIOCCLRPAGE: + { + vtx_pagereq_t *req = arg; - case VTXIOCCLRFOUND: - { - vtx_pagereq_t *req = arg; + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) + return -EINVAL; + memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); + t->vdau[req->pgbuf].clrfound = true; + return 0; + } - if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) - return -EINVAL; - t->vdau[req->pgbuf].clrfound = true; - return 0; - } + case VTXIOCCLRFOUND: + { + vtx_pagereq_t *req = arg; - case VTXIOCPAGEREQ: - { - vtx_pagereq_t *req = arg; - if (!(req->pagemask & PGMASK_PAGE)) - req->page = 0; - if (!(req->pagemask & PGMASK_HOUR)) - req->hour = 0; - if (!(req->pagemask & PGMASK_MINUTE)) - req->minute = 0; - if (req->page < 0 || req->page > 0x8ff) /* 7FF ?? */ - return -EINVAL; - req->page &= 0x7ff; - if (req->hour < 0 || req->hour > 0x3f || req->minute < 0 || req->minute > 0x7f || - req->pagemask < 0 || req->pagemask >= PGMASK_MAX || req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) - return -EINVAL; - t->vdau[req->pgbuf].sregs[0] = (req->pagemask & PG_HUND ? 0x10 : 0) | (req->page / 0x100); - t->vdau[req->pgbuf].sregs[1] = (req->pagemask & PG_TEN ? 0x10 : 0) | ((req->page / 0x10) & 0xf); - t->vdau[req->pgbuf].sregs[2] = (req->pagemask & PG_UNIT ? 0x10 : 0) | (req->page & 0xf); - t->vdau[req->pgbuf].sregs[3] = (req->pagemask & HR_TEN ? 0x10 : 0) | (req->hour / 0x10); - t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf); - t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10); - t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf); - t->vdau[req->pgbuf].stopped = false; - t->vdau[req->pgbuf].clrfound = true; - t->is_searching[req->pgbuf] = true; - return 0; - } + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) + return -EINVAL; + t->vdau[req->pgbuf].clrfound = true; + return 0; + } - case VTXIOCGETSTAT: - { - vtx_pagereq_t *req = arg; - u8 infobits[10]; - vtx_pageinfo_t info; - int a; - - if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) - return -EINVAL; - if (!t->vdau[req->pgbuf].stopped) { - if (i2c_senddata(t, 2, 0, -1) || - i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req->pgbuf].sregs) || - i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) || - i2c_senddata(t, 2, 0, t->vdau[req->pgbuf].sregs[0] | 8, -1) || - i2c_senddata(t, 8, 0, 25, 0, -1)) - return -EIO; - jdelay(PAGE_WAIT); - if (i2c_getdata(t, 10, infobits)) - return -EIO; + case VTXIOCPAGEREQ: + { + vtx_pagereq_t *req = arg; + if (!(req->pagemask & PGMASK_PAGE)) + req->page = 0; + if (!(req->pagemask & PGMASK_HOUR)) + req->hour = 0; + if (!(req->pagemask & PGMASK_MINUTE)) + req->minute = 0; + if (req->page < 0 || req->page > 0x8ff) /* 7FF ?? */ + return -EINVAL; + req->page &= 0x7ff; + if (req->hour < 0 || req->hour > 0x3f || req->minute < 0 || req->minute > 0x7f || + req->pagemask < 0 || req->pagemask >= PGMASK_MAX || req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) + return -EINVAL; + t->vdau[req->pgbuf].sregs[0] = (req->pagemask & PG_HUND ? 0x10 : 0) | (req->page / 0x100); + t->vdau[req->pgbuf].sregs[1] = (req->pagemask & PG_TEN ? 0x10 : 0) | ((req->page / 0x10) & 0xf); + t->vdau[req->pgbuf].sregs[2] = (req->pagemask & PG_UNIT ? 0x10 : 0) | (req->page & 0xf); + t->vdau[req->pgbuf].sregs[3] = (req->pagemask & HR_TEN ? 0x10 : 0) | (req->hour / 0x10); + t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf); + t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10); + t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf); + t->vdau[req->pgbuf].stopped = false; + t->vdau[req->pgbuf].clrfound = true; + t->is_searching[req->pgbuf] = true; + return 0; + } - if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */ - (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) || - time_after_eq(jiffies, t->vdau[req->pgbuf].expire))) - { /* check if new page arrived */ - if (i2c_senddata(t, 8, 0, 0, 0, -1) || - i2c_getdata(t, VTX_PAGESIZE, t->vdau[req->pgbuf].pgbuf)) + case VTXIOCGETSTAT: + { + vtx_pagereq_t *req = arg; + u8 infobits[10]; + vtx_pageinfo_t info; + int a; + + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) + return -EINVAL; + if (!t->vdau[req->pgbuf].stopped) + { + if (i2c_senddata(t, 2, 0, -1) || + i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req->pgbuf].sregs) || + i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) || + i2c_senddata(t, 2, 0, t->vdau[req->pgbuf].sregs[0] | 8, -1) || + i2c_senddata(t, 8, 0, 25, 0, -1)) return -EIO; - t->vdau[req->pgbuf].expire = jiffies + PGBUF_EXPIRE; - memset(t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE); - if (t->virtual_mode) { - /* Packet X/24 */ - if (i2c_senddata(t, 8, 0, 0x20, 0, -1) || - i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40)) - return -EIO; - /* Packet X/27/0 */ - if (i2c_senddata(t, 8, 0, 0x21, 0, -1) || - i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40)) - return -EIO; - /* Packet 8/30/0...8/30/15 - * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30, - * so we should undo this here. - */ - if (i2c_senddata(t, 8, 0, 0x22, 0, -1) || - i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40)) + jdelay(PAGE_WAIT); + if (i2c_getdata(t, 10, infobits)) + return -EIO; + + if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */ + (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) || + time_after_eq(jiffies, t->vdau[req->pgbuf].expire))) + { /* check if new page arrived */ + if (i2c_senddata(t, 8, 0, 0, 0, -1) || + i2c_getdata(t, VTX_PAGESIZE, t->vdau[req->pgbuf].pgbuf)) return -EIO; + t->vdau[req->pgbuf].expire = jiffies + PGBUF_EXPIRE; + memset(t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE); + if (t->virtual_mode) + { + /* Packet X/24 */ + if (i2c_senddata(t, 8, 0, 0x20, 0, -1) || + i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40)) + return -EIO; + /* Packet X/27/0 */ + if (i2c_senddata(t, 8, 0, 0x21, 0, -1) || + i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40)) + return -EIO; + /* Packet 8/30/0...8/30/15 + * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30, + * so we should undo this here. + */ + if (i2c_senddata(t, 8, 0, 0x22, 0, -1) || + i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40)) + return -EIO; + } + t->vdau[req->pgbuf].clrfound = false; + memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits)); + } + else + { + memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)); } - t->vdau[req->pgbuf].clrfound = false; - memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits)); - } else { + } + else + { memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)); } - } else { - memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)); - } - info.pagenum = ((infobits[8] << 8) & 0x700) | ((infobits[1] << 4) & 0xf0) | (infobits[0] & 0x0f); - if (info.pagenum < 0x100) - info.pagenum += 0x800; - info.hour = ((infobits[5] << 4) & 0x30) | (infobits[4] & 0x0f); - info.minute = ((infobits[3] << 4) & 0x70) | (infobits[2] & 0x0f); - info.charset = ((infobits[7] >> 1) & 7); - info.delete = !!(infobits[3] & 8); - info.headline = !!(infobits[5] & 4); - info.subtitle = !!(infobits[5] & 8); - info.supp_header = !!(infobits[6] & 1); - info.update = !!(infobits[6] & 2); - info.inter_seq = !!(infobits[6] & 4); - info.dis_disp = !!(infobits[6] & 8); - info.serial = !!(infobits[7] & 1); - info.notfound = !!(infobits[8] & 0x10); - info.pblf = !!(infobits[9] & 0x20); - info.hamming = 0; - for (a = 0; a <= 7; a++) { - if (infobits[a] & 0xf0) { - info.hamming = 1; - break; + info.pagenum = ((infobits[8] << 8) & 0x700) | ((infobits[1] << 4) & 0xf0) | (infobits[0] & 0x0f); + if (info.pagenum < 0x100) + info.pagenum += 0x800; + info.hour = ((infobits[5] << 4) & 0x30) | (infobits[4] & 0x0f); + info.minute = ((infobits[3] << 4) & 0x70) | (infobits[2] & 0x0f); + info.charset = ((infobits[7] >> 1) & 7); + info.delete = !!(infobits[3] & 8); + info.headline = !!(infobits[5] & 4); + info.subtitle = !!(infobits[5] & 8); + info.supp_header = !!(infobits[6] & 1); + info.update = !!(infobits[6] & 2); + info.inter_seq = !!(infobits[6] & 4); + info.dis_disp = !!(infobits[6] & 8); + info.serial = !!(infobits[7] & 1); + info.notfound = !!(infobits[8] & 0x10); + info.pblf = !!(infobits[9] & 0x20); + info.hamming = 0; + for (a = 0; a <= 7; a++) + { + if (infobits[a] & 0xf0) + { + info.hamming = 1; + break; + } } - } - if (t->vdau[req->pgbuf].clrfound) - info.notfound = 1; - if (copy_to_user(req->buffer, &info, sizeof(vtx_pageinfo_t))) - return -EFAULT; - if (!info.hamming && !info.notfound) - t->is_searching[req->pgbuf] = false; - return 0; - } - - case VTXIOCGETPAGE: - { - vtx_pagereq_t *req = arg; - int start, end; - - if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || req->start < 0 || - req->start > req->end || req->end >= (virtual_mode ? VTX_VIRTUALSIZE : VTX_PAGESIZE)) - return -EINVAL; - if (copy_to_user(req->buffer, &t->vdau[req->pgbuf].pgbuf[req->start], req->end - req->start + 1)) - return -EFAULT; - - /* - * Always read the time directly from SAA5249 - */ - - if (req->start <= 39 && req->end >= 32) { - int len; - char buf[16]; - start = max(req->start, 32); - end = min(req->end, 39); - len = end - start + 1; - if (i2c_senddata(t, 8, 0, 0, start, -1) || - i2c_getdata(t, len, buf)) - return -EIO; - if (copy_to_user(req->buffer + start - req->start, buf, len)) + if (t->vdau[req->pgbuf].clrfound) + info.notfound = 1; + if(copy_to_user(req->buffer, &info, sizeof(vtx_pageinfo_t))) return -EFAULT; + if (!info.hamming && !info.notfound) + { + t->is_searching[req->pgbuf] = false; + } + return 0; } - /* Insert the current header if DAU is still searching for a page */ - if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf]) { - char buf[32]; - int len; - - start = max(req->start, 7); - end = min(req->end, 31); - len = end - start + 1; - if (i2c_senddata(t, 8, 0, 0, start, -1) || - i2c_getdata(t, len, buf)) - return -EIO; - if (copy_to_user(req->buffer + start - req->start, buf, len)) + + case VTXIOCGETPAGE: + { + vtx_pagereq_t *req = arg; + int start, end; + + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || req->start < 0 || + req->start > req->end || req->end >= (virtual_mode ? VTX_VIRTUALSIZE : VTX_PAGESIZE)) + return -EINVAL; + if(copy_to_user(req->buffer, &t->vdau[req->pgbuf].pgbuf[req->start], req->end - req->start + 1)) return -EFAULT; + + /* + * Always read the time directly from SAA5249 + */ + + if (req->start <= 39 && req->end >= 32) + { + int len; + char buf[16]; + start = max(req->start, 32); + end = min(req->end, 39); + len=end-start+1; + if (i2c_senddata(t, 8, 0, 0, start, -1) || + i2c_getdata(t, len, buf)) + return -EIO; + if(copy_to_user(req->buffer+start-req->start, buf, len)) + return -EFAULT; + } + /* Insert the current header if DAU is still searching for a page */ + if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf]) + { + char buf[32]; + int len; + start = max(req->start, 7); + end = min(req->end, 31); + len=end-start+1; + if (i2c_senddata(t, 8, 0, 0, start, -1) || + i2c_getdata(t, len, buf)) + return -EIO; + if(copy_to_user(req->buffer+start-req->start, buf, len)) + return -EFAULT; + } + return 0; } - return 0; - } - case VTXIOCSTOPDAU: - { - vtx_pagereq_t *req = arg; + case VTXIOCSTOPDAU: + { + vtx_pagereq_t *req = arg; - if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) - return -EINVAL; - t->vdau[req->pgbuf].stopped = true; - t->is_searching[req->pgbuf] = false; - return 0; - } + if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) + return -EINVAL; + t->vdau[req->pgbuf].stopped = true; + t->is_searching[req->pgbuf] = false; + return 0; + } - case VTXIOCPUTPAGE: - case VTXIOCSETDISP: - case VTXIOCPUTSTAT: - return 0; + case VTXIOCPUTPAGE: + case VTXIOCSETDISP: + case VTXIOCPUTSTAT: + return 0; - case VTXIOCCLRCACHE: - { - if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11, - ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', - -1)) - return -EIO; - if (i2c_senddata(t, 3, 0x20, -1)) - return -EIO; - jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */ - return 0; - } + case VTXIOCCLRCACHE: + { + if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11, + ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', + ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -1)) + return -EIO; + if (i2c_senddata(t, 3, 0x20, -1)) + return -EIO; + jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */ + return 0; + } - case VTXIOCSETVIRT: - { - /* The SAA5249 has virtual-row reception turned on always */ - t->virtual_mode = (int)(long)arg; - return 0; - } + case VTXIOCSETVIRT: + { + /* The SAA5249 has virtual-row reception turned on always */ + t->virtual_mode = (int)(long)arg; + return 0; + } } return -EINVAL; } @@ -483,7 +616,8 @@ static inline unsigned int vtx_fix_command(unsigned int cmd) static int saa5249_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct saa5249_device *t = video_drvdata(file); + struct video_device *vd = video_devdata(file); + struct saa5249_device *t=vd->priv; int err; cmd = vtx_fix_command(cmd); @@ -495,27 +629,32 @@ static int saa5249_ioctl(struct inode *inode, struct file *file, static int saa5249_open(struct inode *inode, struct file *file) { - struct saa5249_device *t = video_drvdata(file); - int pgbuf; + struct video_device *vd = video_devdata(file); + struct saa5249_device *t=vd->priv; + int err,pgbuf; - if (t->client == NULL) - return -ENODEV; + err = video_exclusive_open(inode,file); + if (err < 0) + return err; - if (test_and_set_bit(0, &t->in_use)) - return -EBUSY; + if (t->client==NULL) { + err = -ENODEV; + goto fail; + } - if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */ - /* Turn off parity checks (we do this ourselves) */ + if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */ + /* Turn off parity checks (we do this ourselves) */ i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) || - /* Display TV-picture, no virtual rows */ - i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) - /* Set display to page 4 */ + /* Display TV-picture, no virtual rows */ + i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */ + { - clear_bit(0, &t->in_use); - return -EIO; + err = -EIO; + goto fail; } - for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { + for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) + { memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); @@ -526,20 +665,39 @@ static int saa5249_open(struct inode *inode, struct file *file) } t->virtual_mode = false; return 0; + + fail: + video_exclusive_release(inode,file); + return err; } static int saa5249_release(struct inode *inode, struct file *file) { - struct saa5249_device *t = video_drvdata(file); - + struct video_device *vd = video_devdata(file); + struct saa5249_device *t=vd->priv; i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */ i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */ - clear_bit(0, &t->in_use); + video_exclusive_release(inode,file); return 0; } +static int __init init_saa_5249 (void) +{ + printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n", + VTX_VER_MAJ, VTX_VER_MIN); + return i2c_add_driver(&i2c_driver_videotext); +} + +static void __exit cleanup_saa_5249 (void) +{ + i2c_del_driver(&i2c_driver_videotext); +} + +module_init(init_saa_5249); +module_exit(cleanup_saa_5249); + static const struct file_operations saa_fops = { .owner = THIS_MODULE, .open = saa5249_open, @@ -553,84 +711,8 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { - .name = "saa5249", + .name = IF_NAME, .fops = &saa_fops, - .release = video_device_release, }; -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - -static int saa5249_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int pgbuf; - int err; - struct video_device *vd; - struct saa5249_device *t; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - v4l_info(client, "VideoText version %d.%d\n", - VTX_VER_MAJ, VTX_VER_MIN); - t = kzalloc(sizeof(*t), GFP_KERNEL); - if (t == NULL) - return -ENOMEM; - mutex_init(&t->lock); - - /* Now create a video4linux device */ - vd = kmalloc(sizeof(struct video_device), GFP_KERNEL); - if (vd == NULL) { - kfree(client); - return -ENOMEM; - } - i2c_set_clientdata(client, vd); - memcpy(vd, &saa_template, sizeof(*vd)); - - for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { - memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); - memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); - memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); - t->vdau[pgbuf].expire = 0; - t->vdau[pgbuf].clrfound = true; - t->vdau[pgbuf].stopped = true; - t->is_searching[pgbuf] = false; - } - video_set_drvdata(vd, t); - - /* Register it */ - err = video_register_device(vd, VFL_TYPE_VTX, -1); - if (err < 0) { - kfree(t); - kfree(vd); - return err; - } - t->client = client; - return 0; -} - -static int saa5249_remove(struct i2c_client *client) -{ - struct video_device *vd = i2c_get_clientdata(client); - - video_unregister_device(vd); - kfree(video_get_drvdata(vd)); - kfree(vd); - return 0; -} - -static const struct i2c_device_id saa5249_id[] = { - { "saa5249", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa5249_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa5249", - .driverid = I2C_DRIVERID_SAA5249, - .probe = saa5249_probe, - .remove = saa5249_remove, - .id_table = saa5249_id, -}; +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/saa7115.c b/trunk/drivers/media/video/saa7115.c index c8e9cb3db30a..ad733caec720 100644 --- a/trunk/drivers/media/video/saa7115.c +++ b/trunk/drivers/media/video/saa7115.c @@ -1057,7 +1057,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo for (i = 0; i <= 23; i++) lcr[i] = 0xff; - if (fmt == NULL) { + if (fmt->service_set == 0) { /* raw VBI */ if (is_50hz) for (i = 6; i <= 23; i++) @@ -1113,7 +1113,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo } /* enable/disable raw VBI capturing */ - saa711x_writeregs(client, fmt == NULL ? + saa711x_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off); } @@ -1153,10 +1153,6 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt saa711x_set_lcr(client, &fmt->fmt.sliced); return 0; } - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - saa711x_set_lcr(client, NULL); - return 0; - } if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1313,13 +1309,10 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar case VIDIOC_INT_S_VIDEO_ROUTING: { struct v4l2_routing *route = arg; - u32 input = route->input; - u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0; v4l_dbg(1, debug, client, "decoder set input %d output %d\n", route->input, route->output); - /* saa7111/3 does not have these inputs */ - if ((state->ident == V4L2_IDENT_SAA7113 || - state->ident == V4L2_IDENT_SAA7111) && + /* saa7113 does not have these inputs */ + if (state->ident == V4L2_IDENT_SAA7113 && (route->input == SAA7115_COMPOSITE4 || route->input == SAA7115_COMPOSITE5)) { return -EINVAL; @@ -1334,23 +1327,10 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite", (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off"); state->input = route->input; - /* saa7111 has slightly different input numbering */ - if (state->ident == V4L2_IDENT_SAA7111) { - if (input >= SAA7115_COMPOSITE4) - input -= 2; - /* saa7111 specific */ - saa711x_write(client, R_10_CHROMA_CNTL_2, - (saa711x_read(client, R_10_CHROMA_CNTL_2) & 0x3f) | - ((route->output & 0xc0) ^ 0x40)); - saa711x_write(client, R_13_RT_X_PORT_OUT_CNTL, - (saa711x_read(client, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) | - ((route->output & 2) ? 0x0a : 0)); - } - /* select mode */ saa711x_write(client, R_02_INPUT_CNTL_1, - (saa711x_read(client, R_02_INPUT_CNTL_1) & mask) | - input); + (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) | + state->input); /* bypass chrominance trap for S-Video modes */ saa711x_write(client, R_09_LUMA_CNTL, @@ -1404,13 +1384,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar saa711x_writeregs(client, saa7115_cfg_reset_scaler); break; - case VIDIOC_INT_S_GPIO: - if (state->ident != V4L2_IDENT_SAA7111) - return -EINVAL; - saa711x_write(client, 0x11, (saa711x_read(client, 0x11) & 0x7f) | - (*(u32 *)arg ? 0x80 : 0)); - break; - case VIDIOC_INT_G_VBI_DATA: { struct v4l2_sliced_vbi_data *data = arg; @@ -1566,8 +1539,7 @@ static int saa7115_probe(struct i2c_client *client, state->crystal_freq = SAA7115_FREQ_32_11_MHZ; saa711x_writeregs(client, saa7115_init_auto_input); } - if (state->ident != V4L2_IDENT_SAA7111) - saa711x_writeregs(client, saa7115_init_misc); + saa711x_writeregs(client, saa7115_init_misc); saa711x_set_v4lstd(client, V4L2_STD_NTSC); v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", diff --git a/trunk/drivers/media/video/saa7134/saa6752hs.c b/trunk/drivers/media/video/saa7134/saa6752hs.c index 1fb6eccdade3..707be175509d 100644 --- a/trunk/drivers/media/video/saa7134/saa6752hs.c +++ b/trunk/drivers/media/video/saa7134/saa6752hs.c @@ -1,27 +1,3 @@ - /* - saa6752hs - i2c-driver for the saa6752hs by Philips - - Copyright (C) 2004 Andrew de Quincey - - AC-3 support: - - Copyright (C) 2008 Hans Verkuil - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License vs published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. - */ - #include #include #include @@ -34,8 +10,6 @@ #include #include #include -#include -#include #include #include @@ -53,6 +27,9 @@ MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); MODULE_AUTHOR("Andrew de Quincey"); MODULE_LICENSE("GPL"); +static struct i2c_driver driver; +static struct i2c_client client_template; + enum saa6752hs_videoformat { SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ @@ -69,9 +46,7 @@ struct saa6752hs_mpeg_params { __u16 ts_pid_pcr; /* audio */ - enum v4l2_mpeg_audio_encoding au_encoding; - enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; - enum v4l2_mpeg_audio_ac3_bitrate au_ac3_bitrate; + enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; /* video */ enum v4l2_mpeg_video_aspect vi_aspect; @@ -95,9 +70,7 @@ static const struct v4l2_format v4l2_format_table[] = }; struct saa6752hs_state { - int chip; - u32 revision; - int has_ac3; + struct i2c_client client; struct saa6752hs_mpeg_params params; enum saa6752hs_videoformat video_format; v4l2_std_id standard; @@ -172,39 +145,6 @@ static u8 PMT[] = { 0x00, 0x00, 0x00, 0x00 /* CRC32 */ }; -static u8 PMT_AC3[] = { - 0xc2, /* i2c register */ - 0x01, /* table number for encoder(1) */ - 0x47, /* sync */ - - 0x40, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0) */ - 0x10, /* PMT PID (0x0010) */ - 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ - - 0x00, /* PSI pointer to start of table */ - - 0x02, /* TID (2) */ - 0xb0, 0x1a, /* section_syntax_indicator(1), section_length(26) */ - - 0x00, 0x01, /* program_number(1) */ - - 0xc1, /* version_number(0), current_next_indicator(1) */ - - 0x00, 0x00, /* section_number(0), last_section_number(0) */ - - 0xe1, 0x04, /* PCR_PID (0x0104) */ - - 0xf0, 0x00, /* program_info_length(0) */ - - 0x02, 0xe1, 0x00, 0xf0, 0x00, /* video stream type(2), pid */ - 0x06, 0xe1, 0x03, 0xf0, 0x03, /* audio stream type(6), pid */ - 0x6a, /* AC3 */ - 0x01, /* Descriptor_length(1) */ - 0x00, /* component_type_flag(0), bsid_flag(0), mainid_flag(0), asvc_flag(0), reserved flags(0) */ - - 0xED, 0xDE, 0x2D, 0xF3 /* CRC32 BE */ -}; - static struct saa6752hs_mpeg_params param_defaults = { .ts_pid_pmt = 16, @@ -217,14 +157,12 @@ static struct saa6752hs_mpeg_params param_defaults = .vi_bitrate_peak = 6000, .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - .au_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, - .au_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_256K, }; /* ---------------------------------------------------------------------- */ -static int saa6752hs_chip_command(struct i2c_client *client, +static int saa6752hs_chip_command(struct i2c_client* client, enum saa6752hs_command command) { unsigned char buf[3]; @@ -291,61 +229,45 @@ static int saa6752hs_chip_command(struct i2c_client *client, } -static inline void set_reg8(struct i2c_client *client, uint8_t reg, uint8_t val) -{ - u8 buf[2]; - - buf[0] = reg; - buf[1] = val; - i2c_master_send(client, buf, 2); -} - -static inline void set_reg16(struct i2c_client *client, uint8_t reg, uint16_t val) +static int saa6752hs_set_bitrate(struct i2c_client* client, + struct saa6752hs_mpeg_params* params) { u8 buf[3]; - - buf[0] = reg; - buf[1] = val >> 8; - buf[2] = val & 0xff; - i2c_master_send(client, buf, 3); -} - -static int saa6752hs_set_bitrate(struct i2c_client *client, - struct saa6752hs_state *h) -{ - struct saa6752hs_mpeg_params *params = &h->params; int tot_bitrate; - int is_384k; /* set the bitrate mode */ - set_reg8(client, 0x71, - params->vi_bitrate_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); + buf[0] = 0x71; + buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; + i2c_master_send(client, buf, 2); /* set the video bitrate */ if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { /* set the target bitrate */ - set_reg16(client, 0x80, params->vi_bitrate); + buf[0] = 0x80; + buf[1] = params->vi_bitrate >> 8; + buf[2] = params->vi_bitrate & 0xff; + i2c_master_send(client, buf, 3); /* set the max bitrate */ - set_reg16(client, 0x81, params->vi_bitrate_peak); + buf[0] = 0x81; + buf[1] = params->vi_bitrate_peak >> 8; + buf[2] = params->vi_bitrate_peak & 0xff; + i2c_master_send(client, buf, 3); tot_bitrate = params->vi_bitrate_peak; } else { /* set the target bitrate (no max bitrate for CBR) */ - set_reg16(client, 0x81, params->vi_bitrate); + buf[0] = 0x81; + buf[1] = params->vi_bitrate >> 8; + buf[2] = params->vi_bitrate & 0xff; + i2c_master_send(client, buf, 3); tot_bitrate = params->vi_bitrate; } - /* set the audio encoding */ - set_reg8(client, 0x93, - params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); - /* set the audio bitrate */ - if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) - is_384k = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; - else - is_384k = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; - set_reg8(client, 0x94, is_384k); - tot_bitrate += is_384k ? 384 : 256; + buf[0] = 0x94; + buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; + i2c_master_send(client, buf, 2); + tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384; /* Note: the total max bitrate is determined by adding the video and audio bitrates together and also adding an extra 768kbit/s to stay on the @@ -356,12 +278,16 @@ static int saa6752hs_set_bitrate(struct i2c_client *client, tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; /* set the total bitrate */ - set_reg16(client, 0xb1, tot_bitrate); + buf[0] = 0xb1; + buf[1] = tot_bitrate >> 8; + buf[2] = tot_bitrate & 0xff; + i2c_master_send(client, buf, 3); + return 0; } -static void saa6752hs_set_subsampling(struct i2c_client *client, - struct v4l2_format *f) +static void saa6752hs_set_subsampling(struct i2c_client* client, + struct v4l2_format* f) { struct saa6752hs_state *h = i2c_get_clientdata(client); int dist_352, dist_480, dist_720; @@ -406,7 +332,7 @@ static void saa6752hs_set_subsampling(struct i2c_client *client, } -static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, +static int handle_ctrl(struct saa6752hs_mpeg_params *params, struct v4l2_ext_control *ctrl, unsigned int cmd) { int old = 0, new; @@ -453,9 +379,8 @@ static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, params->ts_pid_pcr = new; break; case V4L2_CID_MPEG_AUDIO_ENCODING: - old = params->au_encoding; - if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && - (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) + old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; + if (set && new != old) return -ERANGE; new = old; break; @@ -470,19 +395,6 @@ static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; params->au_l2_bitrate = new; break; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - if (!has_ac3) - return -EINVAL; - old = params->au_ac3_bitrate; - if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K && - new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K) - return -ERANGE; - if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K) - new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K; - else - new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K; - params->au_ac3_bitrate = new; - break; case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; if (set && new != old) @@ -536,19 +448,17 @@ static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, return 0; } -static int saa6752hs_qctrl(struct saa6752hs_state *h, +static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, struct v4l2_queryctrl *qctrl) { - struct saa6752hs_mpeg_params *params = &h->params; int err; switch (qctrl->id) { case V4L2_CID_MPEG_AUDIO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2); case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return v4l2_ctrl_query_fill(qctrl, @@ -556,14 +466,6 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h, V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, V4L2_MPEG_AUDIO_L2_BITRATE_256K); - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - if (!h->has_ac3) - return -EINVAL; - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_AC3_BITRATE_256K, - V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1, - V4L2_MPEG_AUDIO_AC3_BITRATE_256K); - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, @@ -610,57 +512,44 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h, return -EINVAL; } -static int saa6752hs_qmenu(struct saa6752hs_state *h, +static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params, struct v4l2_querymenu *qmenu) { - static const u32 mpeg_audio_encoding[] = { - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - V4L2_CTRL_MENU_IDS_END - }; - static const u32 mpeg_audio_ac3_encoding[] = { - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - V4L2_MPEG_AUDIO_ENCODING_AC3, - V4L2_CTRL_MENU_IDS_END - }; - static u32 mpeg_audio_l2_bitrate[] = { - V4L2_MPEG_AUDIO_L2_BITRATE_256K, - V4L2_MPEG_AUDIO_L2_BITRATE_384K, - V4L2_CTRL_MENU_IDS_END - }; - static u32 mpeg_audio_ac3_bitrate[] = { - V4L2_MPEG_AUDIO_AC3_BITRATE_256K, - V4L2_MPEG_AUDIO_AC3_BITRATE_384K, - V4L2_CTRL_MENU_IDS_END + static const char *mpeg_audio_l2_bitrate[] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "256 kbps", + "", + "384 kbps", + NULL }; struct v4l2_queryctrl qctrl; int err; qctrl.id = qmenu->id; - err = saa6752hs_qctrl(h, &qctrl); + err = saa6752hs_qctrl(params, &qctrl); if (err) return err; - switch (qmenu->id) { - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - return v4l2_ctrl_query_menu_valid_items(qmenu, + if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE) + return v4l2_ctrl_query_menu(qmenu, &qctrl, mpeg_audio_l2_bitrate); - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - if (!h->has_ac3) - return -EINVAL; - return v4l2_ctrl_query_menu_valid_items(qmenu, - mpeg_audio_ac3_bitrate); - case V4L2_CID_MPEG_AUDIO_ENCODING: - return v4l2_ctrl_query_menu_valid_items(qmenu, - h->has_ac3 ? mpeg_audio_ac3_encoding : - mpeg_audio_encoding); - } - return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + v4l2_ctrl_get_menu(qmenu->id)); } -static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) +static int saa6752hs_init(struct i2c_client* client) { unsigned char buf[9], buf2[4]; struct saa6752hs_state *h; - unsigned size; u32 crc; unsigned char localPAT[256]; unsigned char localPMT[256]; @@ -668,31 +557,45 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) h = i2c_get_clientdata(client); /* Set video format - must be done first as it resets other settings */ - set_reg8(client, 0x41, h->video_format); + buf[0] = 0x41; + buf[1] = h->video_format; + i2c_master_send(client, buf, 2); /* Set number of lines in input signal */ - set_reg8(client, 0x40, (h->standard & V4L2_STD_525_60) ? 1 : 0); + buf[0] = 0x40; + buf[1] = 0x00; + if (h->standard & V4L2_STD_525_60) + buf[1] = 0x01; + i2c_master_send(client, buf, 2); /* set bitrate */ - saa6752hs_set_bitrate(client, h); + saa6752hs_set_bitrate(client, &h->params); /* Set GOP structure {3, 13} */ - set_reg16(client, 0x72, 0x030d); + buf[0] = 0x72; + buf[1] = 0x03; + buf[2] = 0x0D; + i2c_master_send(client,buf,3); /* Set minimum Q-scale {4} */ - set_reg8(client, 0x82, 0x04); + buf[0] = 0x82; + buf[1] = 0x04; + i2c_master_send(client,buf,2); /* Set maximum Q-scale {12} */ - set_reg8(client, 0x83, 0x0c); + buf[0] = 0x83; + buf[1] = 0x0C; + i2c_master_send(client,buf,2); /* Set Output Protocol */ - set_reg8(client, 0xd0, 0x81); + buf[0] = 0xD0; + buf[1] = 0x81; + i2c_master_send(client,buf,2); /* Set video output stream format {TS} */ - set_reg8(client, 0xb0, 0x05); - - /* Set leading null byte for TS */ - set_reg16(client, 0xf6, leading_null_bytes); + buf[0] = 0xB0; + buf[1] = 0x05; + i2c_master_send(client,buf,2); /* compute PAT */ memcpy(localPAT, PAT, sizeof(PAT)); @@ -705,13 +608,7 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) localPAT[sizeof(PAT) - 1] = crc & 0xFF; /* compute PMT */ - if (h->params.au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) { - size = sizeof(PMT_AC3); - memcpy(localPMT, PMT_AC3, size); - } else { - size = sizeof(PMT); - memcpy(localPMT, PMT, size); - } + memcpy(localPMT, PMT, sizeof(PMT)); localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); localPMT[4] = h->params.ts_pid_pmt & 0xff; localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); @@ -720,28 +617,40 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) localPMT[21] = h->params.ts_pid_video & 0xFF; localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F); localPMT[26] = h->params.ts_pid_audio & 0xFF; - crc = crc32_be(~0, &localPMT[7], size - 7 - 4); - localPMT[size - 4] = (crc >> 24) & 0xFF; - localPMT[size - 3] = (crc >> 16) & 0xFF; - localPMT[size - 2] = (crc >> 8) & 0xFF; - localPMT[size - 1] = crc & 0xFF; + crc = crc32_be(~0, &localPMT[7], sizeof(PMT) - 7 - 4); + localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF; + localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF; + localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; + localPMT[sizeof(PMT) - 1] = crc & 0xFF; /* Set Audio PID */ - set_reg16(client, 0xc1, h->params.ts_pid_audio); + buf[0] = 0xC1; + buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; + buf[2] = h->params.ts_pid_audio & 0xFF; + i2c_master_send(client,buf,3); /* Set Video PID */ - set_reg16(client, 0xc0, h->params.ts_pid_video); + buf[0] = 0xC0; + buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; + buf[2] = h->params.ts_pid_video & 0xFF; + i2c_master_send(client,buf,3); /* Set PCR PID */ - set_reg16(client, 0xc4, h->params.ts_pid_pcr); + buf[0] = 0xC4; + buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; + buf[2] = h->params.ts_pid_pcr & 0xFF; + i2c_master_send(client,buf,3); /* Send SI tables */ - i2c_master_send(client, localPAT, sizeof(PAT)); - i2c_master_send(client, localPMT, size); + i2c_master_send(client,localPAT,sizeof(PAT)); + i2c_master_send(client,localPMT,sizeof(PMT)); /* mute then unmute audio. This removes buzzing artefacts */ - set_reg8(client, 0xa4, 1); - set_reg8(client, 0xa4, 0); + buf[0] = 0xa4; + buf[1] = 1; + i2c_master_send(client, buf, 2); + buf[1] = 0; + i2c_master_send(client, buf, 2); /* start it going */ saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); @@ -779,6 +688,45 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) return 0; } +static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) +{ + struct saa6752hs_state *h; + + + if (NULL == (h = kzalloc(sizeof(*h), GFP_KERNEL))) + return -ENOMEM; + h->client = client_template; + h->params = param_defaults; + h->client.adapter = adap; + h->client.addr = addr; + + /* Assume 625 input lines */ + h->standard = 0; + + i2c_set_clientdata(&h->client, h); + i2c_attach_client(&h->client); + + v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); + return 0; +} + +static int saa6752hs_probe(struct i2c_adapter *adap) +{ + if (adap->class & I2C_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, saa6752hs_attach); + return 0; +} + +static int saa6752hs_detach(struct i2c_client *client) +{ + struct saa6752hs_state *h; + + h = i2c_get_clientdata(client); + i2c_detach_client(client); + kfree(h); + return 0; +} + static int saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -789,13 +737,14 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) int i; switch (cmd) { - case VIDIOC_INT_INIT: - /* apply settings and start encoder */ - saa6752hs_init(client, *(u32 *)arg); - break; case VIDIOC_S_EXT_CTRLS: if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; + if (ctrls->count == 0) { + /* apply settings and start encoder */ + saa6752hs_init(client); + break; + } /* fall through */ case VIDIOC_TRY_EXT_CTRLS: case VIDIOC_G_EXT_CTRLS: @@ -803,8 +752,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) return -EINVAL; params = h->params; for (i = 0; i < ctrls->count; i++) { - err = handle_ctrl(h->has_ac3, ¶ms, ctrls->controls + i, cmd); - if (err) { + if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { ctrls->error_idx = i; return err; } @@ -812,9 +760,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) h->params = params; break; case VIDIOC_QUERYCTRL: - return saa6752hs_qctrl(h, arg); + return saa6752hs_qctrl(&h->params, arg); case VIDIOC_QUERYMENU: - return saa6752hs_qmenu(h, arg); + return saa6752hs_qmenu(&h->params, arg); case VIDIOC_G_FMT: { struct v4l2_format *f = arg; @@ -837,11 +785,6 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) case VIDIOC_S_STD: h->standard = *((v4l2_std_id *) arg); break; - - case VIDIOC_G_CHIP_IDENT: - return v4l2_chip_ident_i2c_client(client, - arg, h->chip, h->revision); - default: /* nothing */ break; @@ -850,55 +793,36 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) return err; } -static int saa6752hs_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL); - u8 addr = 0x13; - u8 data[12]; +/* ----------------------------------------------------------------------- */ - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - if (h == NULL) - return -ENOMEM; +static struct i2c_driver driver = { + .driver = { + .name = "saa6752hs", + }, + .id = I2C_DRIVERID_SAA6752HS, + .attach_adapter = saa6752hs_probe, + .detach_client = saa6752hs_detach, + .command = saa6752hs_command, +}; - i2c_master_send(client, &addr, 1); - i2c_master_recv(client, data, sizeof(data)); - h->chip = V4L2_IDENT_SAA6752HS; - h->revision = (data[8] << 8) | data[9]; - h->has_ac3 = 0; - if (h->revision == 0x0206) { - h->chip = V4L2_IDENT_SAA6752HS_AC3; - h->has_ac3 = 1; - v4l_info(client, "support AC-3\n"); - } - h->params = param_defaults; - h->standard = 0; /* Assume 625 input lines */ +static struct i2c_client client_template = +{ + .name = "saa6752hs", + .driver = &driver, +}; - i2c_set_clientdata(client, h); - return 0; +static int __init saa6752hs_init_module(void) +{ + return i2c_add_driver(&driver); } -static int saa6752hs_remove(struct i2c_client *client) +static void __exit saa6752hs_cleanup_module(void) { - kfree(i2c_get_clientdata(client)); - return 0; + i2c_del_driver(&driver); } -static const struct i2c_device_id saa6752hs_id[] = { - { "saa6752hs", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa6752hs_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa6752hs", - .driverid = I2C_DRIVERID_SAA6752HS, - .command = saa6752hs_command, - .probe = saa6752hs_probe, - .remove = saa6752hs_remove, - .id_table = saa6752hs_id, -}; +module_init(saa6752hs_init_module); +module_exit(saa6752hs_cleanup_module); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index ddc5402c5fb0..98364d171def 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -3260,7 +3260,6 @@ struct saa7134_board saa7134_boards[] = { }, [SAA7134_BOARD_HAUPPAUGE_HVR1110] = { /* Thomas Genty */ - /* David Bentham */ .name = "Hauppauge WinTV-HVR1110 DVB-T/Hybrid", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_TDA8290, @@ -3269,26 +3268,23 @@ struct saa7134_board saa7134_boards[] = { .radio_addr = ADDR_UNSET, .tuner_config = 1, .mpeg = SAA7134_MPEG_DVB, - .gpiomask = 0x0200100, .inputs = {{ .name = name_tv, .vmux = 1, .amux = TV, .tv = 1, - .gpio = 0x0000100, - }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE1, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE1, - } }, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE2, /* FIXME: audio doesn't work on svideo/composite */ + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, /* FIXME: audio doesn't work on svideo/composite */ + }}, .radio = { .name = name_radio, - .amux = TV, - .gpio = 0x0200100, + .amux = TV, }, }, [SAA7134_BOARD_CINERGY_HT_PCMCIA] = { @@ -3392,42 +3388,6 @@ struct saa7134_board saa7134_boards[] = { .amux = 0, }, }, - [SAA7134_BOARD_ENCORE_ENLTV_FM53] = { - .name = "Encore ENLTV-FM v5.3", - .audio_clock = 0x00200000, - .tuner_type = TUNER_TNF_5335MF, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .gpiomask = 0x7000, - .inputs = { { - .name = name_tv, - .vmux = 1, - .amux = 1, - .tv = 1, - .gpio = 0x50000, - }, { - .name = name_comp1, - .vmux = 3, - .amux = 2, - .gpio = 0x2000, - }, { - .name = name_svideo, - .vmux = 8, - .amux = 2, - .gpio = 0x2000, - } }, - .radio = { - .name = name_radio, - .vmux = 1, - .amux = 1, - }, - .mute = { - .name = name_mute, - .gpio = 0xf000, - .amux = 0, - }, - }, [SAA7134_BOARD_CINERGY_HT_PCI] = { .name = "Terratec Cinergy HT PCI", .audio_clock = 0x00187de7, @@ -3671,40 +3631,6 @@ struct saa7134_board saa7134_boards[] = { .tv = 1, }}, }, - [SAA7134_BOARD_AVERMEDIA_M135A] = { - .name = "Avermedia PCI pure analog (M135A)", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tuner_config = 2, - .gpiomask = 0x020200000, - .inputs = {{ - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE1, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE1, - } }, - .radio = { - .name = name_radio, - .amux = TV, - .gpio = 0x00200000, - }, - .mute = { - .name = name_mute, - .amux = TV, - .gpio = 0x01, - }, - }, [SAA7134_BOARD_BEHOLD_401] = { /* Beholder Intl. Ltd. 2008 */ /*Dmitry Belimov */ @@ -4483,129 +4409,6 @@ struct saa7134_board saa7134_boards[] = { /* no DVB support for now */ /* .mpeg = SAA7134_MPEG_DVB, */ }, - [SAA7134_BOARD_ASUSTeK_TIGER_3IN1] = { - .name = "Asus Tiger 3in1", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tuner_config = 2, - .gpiomask = 1 << 21, - .mpeg = SAA7134_MPEG_DVB, - .inputs = {{ - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - }, { - .name = name_comp, - .vmux = 0, - .amux = LINE2, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE2, - } }, - .radio = { - .name = name_radio, - .amux = TV, - .gpio = 0x0200000, - }, - }, - [SAA7134_BOARD_REAL_ANGEL_220] = { - .name = "Zogis Real Angel 220", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_TNF_5335MF, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .gpiomask = 0x801a8087, - .inputs = { { - .name = name_tv, - .vmux = 3, - .amux = LINE2, - .tv = 1, - .gpio = 0x624000, - }, { - .name = name_comp1, - .vmux = 1, - .amux = LINE1, - .gpio = 0x624000, - }, { - .name = name_svideo, - .vmux = 1, - .amux = LINE1, - .gpio = 0x624000, - } }, - .radio = { - .name = name_radio, - .amux = LINE2, - .gpio = 0x624001, - }, - .mute = { - .name = name_mute, - .amux = TV, - }, - }, - [SAA7134_BOARD_ADS_INSTANT_HDTV_PCI] = { - .name = "ADS Tech Instant HDTV", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TUV1236D, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, - .mpeg = SAA7134_MPEG_DVB, - .inputs = { { - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - }, { - .name = name_comp, - .vmux = 4, - .amux = LINE1, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE1, - } }, - }, - [SAA7134_BOARD_ASUSTeK_TIGER] = { - .name = "Asus Tiger Rev:1.00", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tuner_config = 0, - .mpeg = SAA7134_MPEG_DVB, - .gpiomask = 0x0200000, - .inputs = { { - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE2, - }, { - .name = name_comp2, - .vmux = 0, - .amux = LINE2, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE2, - } }, - .radio = { - .name = name_radio, - .amux = TV, - .gpio = 0x0200000, - }, - }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -4973,12 +4776,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM, },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x1461, /* Avermedia Technologies Inc */ - .subdevice = 0xf11d, - .driver_data = SAA7134_BOARD_AVERMEDIA_M135A, - }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7130, .subvendor = PCI_VENDOR_ID_PHILIPS, @@ -5359,12 +5156,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x230f, .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM, },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7130, - .subvendor = 0x1a7f, - .subdevice = 0x2008, - .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53, - }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x153b, @@ -5392,8 +5183,8 @@ struct pci_device_id saa7134_pci_tbl[] = { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x1043, - .subdevice = 0x4857, /* REV:1.00 */ - .driver_data = SAA7134_BOARD_ASUSTeK_TIGER, + .subdevice = 0x4857, + .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -5622,12 +5413,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x185b, .subdevice = 0xc900, .driver_data = SAA7134_BOARD_VIDEOMATE_T750, - }, { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */ - .subvendor = 0x1421, - .subdevice = 0x0380, - .driver_data = SAA7134_BOARD_ADS_INSTANT_HDTV_PCI, }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -5646,12 +5431,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1461, /* Avermedia Technologies Inc */ .subdevice = 0xf636, .driver_data = SAA7134_BOARD_AVERMEDIA_M103, - }, { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x1043, - .subdevice = 0x4878, /* REV:1.02G */ - .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -5761,7 +5540,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, return 0; } -int saa7134_tuner_callback(void *priv, int component, int command, int arg) +int saa7134_tuner_callback(void *priv, int command, int arg) { struct saa7134_dev *dev = priv; if (dev != NULL) { @@ -5841,7 +5620,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_507: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: case SAA7134_BOARD_AVERMEDIA_777: - case SAA7134_BOARD_AVERMEDIA_M135A: /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ case SAA7134_BOARD_VIDEOMATE_TV_PVR: case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: @@ -5866,7 +5644,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_A16AR: case SAA7134_BOARD_ENCORE_ENLTV: case SAA7134_BOARD_ENCORE_ENLTV_FM: - case SAA7134_BOARD_ENCORE_ENLTV_FM53: case SAA7134_BOARD_10MOONSTVMASTER3: case SAA7134_BOARD_BEHOLD_401: case SAA7134_BOARD_BEHOLD_403: @@ -5879,7 +5656,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_BEHOLD_505FM: case SAA7134_BOARD_BEHOLD_507_9FM: case SAA7134_BOARD_GENIUS_TVGO_A11MCE: - case SAA7134_BOARD_REAL_ANGEL_220: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: @@ -5969,7 +5745,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_PINNACLE_PCTV_110i: case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_UPMOST_PURPLE_TV: - case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: case SAA7134_BOARD_HAUPPAUGE_HVR1110: case SAA7134_BOARD_BEHOLD_607_9FM: case SAA7134_BOARD_BEHOLD_M6: @@ -6212,7 +5987,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_KWORLD_DVBT_210: case SAA7134_BOARD_TEVION_DVBT_220RF: - case SAA7134_BOARD_ASUSTeK_TIGER: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: case SAA7134_BOARD_MEDION_MD8800_QUADRO: @@ -6228,14 +6002,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } - case SAA7134_BOARD_ASUSTeK_TIGER_3IN1: - { - u8 data[] = { 0x3c, 0x33, 0x60}; - struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data, - .len = sizeof(data)}; - i2c_transfer(&dev->i2c_adap, &msg, 1); - break; - } case SAA7134_BOARD_FLYDVB_TRIO: { u8 data[] = { 0x3c, 0x33, 0x62}; @@ -6261,7 +6027,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } - case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: case SAA7134_BOARD_KWORLD_ATSC110: { /* enable tuner */ diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c index b686bfabbde0..75d618415f4f 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-core.c +++ b/trunk/drivers/media/video/saa7134/saa7134-core.c @@ -215,7 +215,7 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf) int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) { __le32 *cpu; - dma_addr_t dma_addr = 0; + dma_addr_t dma_addr; cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); if (NULL == cpu) @@ -359,6 +359,32 @@ void saa7134_buffer_timeout(unsigned long data) spin_unlock_irqrestore(&dev->slock,flags); } +/* resends a current buffer in queue after resume */ + +static int saa7134_buffer_requeue(struct saa7134_dev *dev, + struct saa7134_dmaqueue *q) +{ + struct saa7134_buf *buf, *next; + + assert_spin_locked(&dev->slock); + + buf = q->curr; + next = buf; + dprintk("buffer_requeue\n"); + + if (!buf) + return 0; + + dprintk("buffer_requeue : resending active buffers \n"); + + if (!list_empty(&q->queue)) + next = list_entry(q->queue.next, struct saa7134_buf, + vb.queue); + buf->activate(dev, buf, next); + + return 0; +} + /* ------------------------------------------------------------------ */ int saa7134_set_dmabits(struct saa7134_dev *dev) @@ -416,7 +442,9 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) /* TS capture -- dma 5 */ if (dev->ts_q.curr) { ctrl |= SAA7134_MAIN_CTRL_TE5; - irq |= SAA7134_IRQ1_INTE_RA2_1 | + irq |= SAA7134_IRQ1_INTE_RA2_3 | + SAA7134_IRQ1_INTE_RA2_2 | + SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0; } @@ -699,10 +727,6 @@ static int saa7134_hw_enable2(struct saa7134_dev *dev) irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A; } - if (dev->has_remote == SAA7134_REMOTE_I2C) { - request_module("ir-kbd-i2c"); - } - saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, irq2_mask); @@ -1115,32 +1139,6 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) } #ifdef CONFIG_PM - -/* resends a current buffer in queue after resume */ -static int saa7134_buffer_requeue(struct saa7134_dev *dev, - struct saa7134_dmaqueue *q) -{ - struct saa7134_buf *buf, *next; - - assert_spin_locked(&dev->slock); - - buf = q->curr; - next = buf; - dprintk("buffer_requeue\n"); - - if (!buf) - return 0; - - dprintk("buffer_requeue : resending active buffers \n"); - - if (!list_empty(&q->queue)) - next = list_entry(q->queue.next, struct saa7134_buf, - vb.queue); - buf->activate(dev, buf, next); - - return 0; -} - static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) { diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 87c10983266f..be48b9b66a67 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -553,6 +553,7 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, /* ------------------------------------------------------------------ */ static struct tda827x_config tda827x_cfg_0 = { + .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 0, @@ -560,6 +561,7 @@ static struct tda827x_config tda827x_cfg_0 = { }; static struct tda827x_config tda827x_cfg_1 = { + .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 1, @@ -567,6 +569,7 @@ static struct tda827x_config tda827x_cfg_1 = { }; static struct tda827x_config tda827x_cfg_2 = { + .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 2, @@ -574,6 +577,7 @@ static struct tda827x_config tda827x_cfg_2 = { }; static struct tda827x_config tda827x_cfg_2_sw42 = { + .tuner_callback = saa7134_tuner_callback, .init = philips_tda827x_tuner_init, .sleep = philips_tda827x_tuner_sleep, .config = 2, @@ -795,20 +799,6 @@ static struct tda1004x_config twinhan_dtv_dvb_3056_config = { .request_firmware = philips_tda1004x_request_firmware }; -static struct tda1004x_config asus_tiger_3in1_config = { - .demod_address = 0x0b, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X, - .gpio_config = TDA10046_GP11_I, - .if_freq = TDA10046_FREQ_045, - .i2c_gate = 0x4b, - .tuner_address = 0x61, - .antenna_switch = 1, - .request_firmware = philips_tda1004x_request_firmware -}; - /* ------------------------------------------------------------------ * special case: this card uses saa713x GPIO22 for the mode switch */ @@ -832,6 +822,7 @@ static int ads_duo_tuner_sleep(struct dvb_frontend *fe) } static struct tda827x_config ads_duo_cfg = { + .tuner_callback = saa7134_tuner_callback, .init = ads_duo_tuner_init, .sleep = ads_duo_tuner_sleep, .config = 0 @@ -1156,7 +1147,6 @@ static int dvb_init(struct saa7134_dev *dev) dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_TDHU2); break; - case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: case SAA7134_BOARD_KWORLD_ATSC110: dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, &dev->i2c_adap); @@ -1310,36 +1300,6 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap); attach_xc3028 = 1; break; - case SAA7134_BOARD_ASUSTeK_TIGER_3IN1: - if (!use_frontend) { /* terrestrial */ - if (configure_tda827x_fe(dev, &asus_tiger_3in1_config, - &tda827x_cfg_2) < 0) - goto dettach_frontend; - } else { /* satellite */ - dev->dvb.frontend = dvb_attach(tda10086_attach, - &flydvbs, &dev->i2c_adap); - if (dev->dvb.frontend) { - if (dvb_attach(tda826x_attach, - dev->dvb.frontend, 0x60, - &dev->i2c_adap, 0) == NULL) { - wprintk("%s: Asus Tiger 3in1, no " - "tda826x found!\n", __func__); - goto dettach_frontend; - } - if (dvb_attach(lnbp21_attach, dev->dvb.frontend, - &dev->i2c_adap, 0, 0) == NULL) { - wprintk("%s: Asus Tiger 3in1, no lnbp21" - " found!\n", __func__); - goto dettach_frontend; - } - } - } - break; - case SAA7134_BOARD_ASUSTeK_TIGER: - if (configure_tda827x_fe(dev, &philips_tiger_config, - &tda827x_cfg_0) < 0) - goto dettach_frontend; - break; default: wprintk("Huh? unknown DVB card?\n"); break; @@ -1367,8 +1327,6 @@ static int dvb_init(struct saa7134_dev *dev) printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); return -1; } - /* define general-purpose callback pointer */ - dev->dvb.frontend->callback = saa7134_tuner_callback; /* register everything else */ ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index 9a8766a78a0c..c0c5d7509c25 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -29,7 +29,6 @@ #include #include -#include /* ------------------------------------------------------------------ */ @@ -64,19 +63,10 @@ static void ts_reset_encoder(struct saa7134_dev* dev) static int ts_init_encoder(struct saa7134_dev* dev) { - u32 leading_null_bytes = 0; + struct v4l2_ext_controls ctrls = { V4L2_CTRL_CLASS_MPEG, 0 }; - /* If more cards start to need this, then this - should probably be added to the card definitions. */ - switch (dev->board) { - case SAA7134_BOARD_BEHOLD_M6: - case SAA7134_BOARD_BEHOLD_M63: - case SAA7134_BOARD_BEHOLD_M6_EXTRA: - leading_null_bytes = 1; - break; - } ts_reset_encoder(dev); - saa7134_i2c_call_clients(dev, VIDIOC_INT_INIT, &leading_null_bytes); + saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, &ctrls); dev->empress_started = 1; return 0; } @@ -89,11 +79,9 @@ static int ts_open(struct inode *inode, struct file *file) struct saa7134_dev *dev; int err; - lock_kernel(); list_for_each_entry(dev, &saa7134_devlist, devlist) if (dev->empress_dev && dev->empress_dev->minor == minor) goto found; - unlock_kernel(); return -ENODEV; found: @@ -115,7 +103,6 @@ static int ts_open(struct inode *inode, struct file *file) done_up: mutex_unlock(&dev->empress_tsq.vb_lock); done: - unlock_kernel(); return err; } @@ -303,6 +290,15 @@ static int empress_streamoff(struct file *file, void *priv, return videobuf_streamoff(&dev->empress_tsq); } +static int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; + return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, + cmd, arg); +} + static int empress_s_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { @@ -404,39 +400,6 @@ static int empress_querymenu(struct file *file, void *priv, return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c); } -static int empress_g_chip_ident(struct file *file, void *fh, - struct v4l2_chip_ident *chip) -{ - struct saa7134_dev *dev = file->private_data; - - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - if (dev->mpeg_i2c_client == NULL) - return -EINVAL; - if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER && - chip->match_chip == I2C_DRIVERID_SAA6752HS) - return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); - if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR && - chip->match_chip == dev->mpeg_i2c_client->addr) - return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip); - return -EINVAL; -} - -static int empress_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct saa7134_dev *dev = file->private_data; - - return saa7134_s_std_internal(dev, NULL, id); -} - -static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct saa7134_dev *dev = file->private_data; - - *id = dev->tvnorm->id; - return 0; -} - static const struct file_operations ts_fops = { .owner = THIS_MODULE, @@ -465,13 +428,11 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_enum_input = empress_enum_input, .vidioc_g_input = empress_g_input, .vidioc_s_input = empress_s_input, + .vidioc_queryctrl = empress_queryctrl, .vidioc_querymenu = empress_querymenu, .vidioc_g_ctrl = empress_g_ctrl, .vidioc_s_ctrl = empress_s_ctrl, - .vidioc_g_chip_ident = empress_g_chip_ident, - .vidioc_s_std = empress_s_std, - .vidioc_g_std = empress_g_std, }; /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/saa7134/saa7134-i2c.c b/trunk/drivers/media/video/saa7134/saa7134-i2c.c index 20c1b33caf7b..5f713e637683 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-i2c.c +++ b/trunk/drivers/media/video/saa7134/saa7134-i2c.c @@ -337,7 +337,6 @@ static int attach_inform(struct i2c_client *client) case 0x47: case 0x71: case 0x2d: - case 0x30: { struct IR_i2c *ir = i2c_get_clientdata(client); d1printk("%s i2c IR detected (%s).\n", @@ -428,16 +427,6 @@ void saa7134_i2c_call_clients(struct saa7134_dev *dev, i2c_clients_command(&dev->i2c_adap, cmd, arg); } -int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, - unsigned int cmd, void *arg) -{ - if (dev->mpeg_i2c_client == NULL) - return -EINVAL; - return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, - cmd, arg); -} -EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752); - int saa7134_i2c_register(struct saa7134_dev *dev) { dev->i2c_adap = saa7134_adap_template; diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c index c53fd5f9f6b5..ad08d13dffdd 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-input.c +++ b/trunk/drivers/media/video/saa7134/saa7134-input.c @@ -62,11 +62,8 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of " #define i2cdprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) -/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ +/** rc5 functions */ static int saa7134_rc5_irq(struct saa7134_dev *dev); -static int saa7134_nec_irq(struct saa7134_dev *dev); -static void nec_task(unsigned long data); -static void saa7134_nec_timer(unsigned long data); /* -------------------- GPIO generic keycode builder -------------------- */ @@ -118,53 +115,6 @@ static int build_key(struct saa7134_dev *dev) /* --------------------- Chip specific I2C key builders ----------------- */ -static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, - u32 *ir_raw) -{ - unsigned char b; - int gpio; - - /* is needed to access GPIO. Used by the saa_readl macro. */ - struct saa7134_dev *dev = ir->c.adapter->algo_data; - if (dev == NULL) { - dprintk("get_key_msi_tvanywhere_plus: " - "gir->c.adapter->algo_data is NULL!\n"); - return -EIO; - } - - /* rising SAA7134_GPIO_GPRESCAN reads the status */ - - saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); - saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); - - gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); - - /* GPIO&0x40 is pulsed low when a button is pressed. Don't do - I2C receive if gpio&0x40 is not low. */ - - if (gpio & 0x40) - return 0; /* No button press */ - - /* GPIO says there is a button press. Get it. */ - - if (1 != i2c_master_recv(&ir->c, &b, 1)) { - i2cdprintk("read error\n"); - return -EIO; - } - - /* No button press */ - - if (b == 0xff) - return 0; - - /* Button pressed */ - - dprintk("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b); - *ir_key = b; - *ir_raw = b; - return 1; -} - static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { unsigned char b; @@ -330,9 +280,7 @@ void saa7134_input_irq(struct saa7134_dev *dev) { struct card_ir *ir = dev->remote; - if (ir->nec_gpio) { - saa7134_nec_irq(dev); - } else if (!ir->polling && !ir->rc5_gpio) { + if (!ir->polling && !ir->rc5_gpio) { build_key(dev); } else if (ir->rc5_gpio) { saa7134_rc5_irq(dev); @@ -368,10 +316,6 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) ir->addr = 0x17; ir->rc5_key_timeout = ir_rc5_key_timeout; ir->rc5_remote_gap = ir_rc5_remote_gap; - } else if (ir->nec_gpio) { - setup_timer(&ir->timer_keyup, saa7134_nec_timer, - (unsigned long)dev); - tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); } } @@ -391,7 +335,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) u32 mask_keyup = 0; int polling = 0; int rc5_gpio = 0; - int nec_gpio = 0; int ir_type = IR_TYPE_OTHER; int err; @@ -448,12 +391,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPMODE0, 0x4); saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; - case SAA7134_BOARD_AVERMEDIA_M135A: - ir_codes = ir_codes_avermedia_m135a; - mask_keydown = 0x0040000; - mask_keycode = 0x00013f; - nec_gpio = 1; - break; case SAA7134_BOARD_AVERMEDIA_777: case SAA7134_BOARD_AVERMEDIA_A16AR: ir_codes = ir_codes_avermedia; @@ -562,12 +499,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keyup = 0x040000; polling = 50; // ms break; - case SAA7134_BOARD_ENCORE_ENLTV_FM53: - ir_codes = ir_codes_encore_enltv_fm53; - mask_keydown = 0x0040000; - mask_keycode = 0x00007f; - nec_gpio = 1; - break; case SAA7134_BOARD_10MOONSTVMASTER3: ir_codes = ir_codes_encore_enltv; mask_keycode = 0x5f80000; @@ -580,12 +511,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keydown = 0xf00000; polling = 50; /* ms */ break; - case SAA7134_BOARD_REAL_ANGEL_220: - ir_codes = ir_codes_real_audio_220_32_keys; - mask_keycode = 0x3f00; - mask_keyup = 0x4000; - polling = 50; /* ms */ - break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", @@ -608,7 +533,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) ir->mask_keyup = mask_keyup; ir->polling = polling; ir->rc5_gpio = rc5_gpio; - ir->nec_gpio = nec_gpio; /* init input device */ snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", @@ -688,11 +612,6 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) ir->get_key = get_key_purpletv; ir->ir_codes = ir_codes_purpletv; break; - case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: - snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus"); - ir->get_key = get_key_msi_tvanywhere_plus; - ir->ir_codes = ir_codes_msi_tvanywhere_plus; - break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); ir->get_key = get_key_hvr1110; @@ -756,125 +675,8 @@ static int saa7134_rc5_irq(struct saa7134_dev *dev) return 1; } - -/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms - The first pulse (start) has 9 + 4.5 ms +/* ---------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: */ - -static void saa7134_nec_timer(unsigned long data) -{ - struct saa7134_dev *dev = (struct saa7134_dev *) data; - struct card_ir *ir = dev->remote; - - dprintk("Cancel key repeat\n"); - - ir_input_nokey(ir->dev, &ir->ir); -} - -static void nec_task(unsigned long data) -{ - struct saa7134_dev *dev = (struct saa7134_dev *) data; - struct card_ir *ir; - struct timeval tv; - int count, pulse, oldpulse, gap; - u32 ircode = 0, not_code = 0; - int ngap = 0; - - if (!data) { - printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n"); - /* GPIO will be kept disabled */ - return; - } - - ir = dev->remote; - - /* rising SAA7134_GPIO_GPRESCAN reads the status */ - saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); - saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); - - oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; - pulse = oldpulse; - - do_gettimeofday(&tv); - ir->base_time = tv; - - /* Decode NEC pulsecode. This code can take up to 76.5 ms to run. - Unfortunately, using IRQ to decode pulse didn't work, since it uses - a pulse train of 38KHz. This means one pulse on each 52 us - */ - do { - /* Wait until the end of pulse/space or 5 ms */ - for (count = 0; count < 500; count++) { - udelay(10); - /* rising SAA7134_GPIO_GPRESCAN reads the status */ - saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); - saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); - pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) - & ir->mask_keydown; - if (pulse != oldpulse) - break; - } - - do_gettimeofday(&tv); - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - - if (!pulse) { - /* Bit 0 has 560 us, while bit 1 has 1120 us. - Do something only if bit == 1 - */ - if (ngap && (gap > 560 + 280)) { - unsigned int shift = ngap - 1; - - /* Address first, then command */ - if (shift < 8) { - shift += 8; - ircode |= 1 << shift; - } else if (shift < 16) { - not_code |= 1 << shift; - } else if (shift < 24) { - shift -= 16; - ircode |= 1 << shift; - } else { - shift -= 24; - not_code |= 1 << shift; - } - } - ngap++; - } - - - ir->base_time = tv; - - /* TIMEOUT - Long pulse */ - if (gap >= 5000) - break; - oldpulse = pulse; - } while (ngap < 32); - - if (ngap == 32) { - /* FIXME: should check if not_code == ~ircode */ - ir->code = ir_extract_bits(ircode, ir->mask_keycode); - - dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", - ir->code, ircode, not_code); - - ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); - } else - dprintk("Repeat last key\n"); - - /* Keep repeating the last key */ - mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150)); - - saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); -} - -static int saa7134_nec_irq(struct saa7134_dev *dev) -{ - struct card_ir *ir = dev->remote; - - saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); - tasklet_schedule(&ir->tlet); - - return 1; -} diff --git a/trunk/drivers/media/video/saa7134/saa7134-ts.c b/trunk/drivers/media/video/saa7134/saa7134-ts.c index ef55a59f0cda..eae72fd60cec 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-ts.c +++ b/trunk/drivers/media/video/saa7134/saa7134-ts.c @@ -66,29 +66,11 @@ static int buffer_activate(struct saa7134_dev *dev, saa7134_set_dmabits(dev); mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT); - - if (dev->ts_state == SAA7134_TS_BUFF_DONE) { - /* Clear TS cache */ - dev->buff_cnt = 0; - saa_writeb(SAA7134_TS_SERIAL1, 0x00); - saa_writeb(SAA7134_TS_SERIAL1, 0x03); - saa_writeb(SAA7134_TS_SERIAL1, 0x00); - saa_writeb(SAA7134_TS_SERIAL1, 0x01); - - /* TS clock non-inverted */ - saa_writeb(SAA7134_TS_SERIAL1, 0x00); - - /* Start TS stream */ - saa_writeb(SAA7134_TS_SERIAL0, 0x40); - saa_writeb(SAA7134_TS_PARALLEL, 0xEC); - dev->ts_state = SAA7134_TS_STARTED; - } - return 0; } static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) + enum v4l2_field field) { struct saa7134_dev *dev = q->priv_data; struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); @@ -128,22 +110,16 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, goto oops; } - dev->buff_cnt++; - - if (dev->buff_cnt == dev->ts.nr_bufs) { - dev->ts_state = SAA7134_TS_BUFF_DONE; - /* dma: setup channel 5 (= TS) */ - control = SAA7134_RS_CONTROL_BURST_16 | - SAA7134_RS_CONTROL_ME | - (buf->pt->dma >> 12); - - saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff); - saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff); - /* TSNOPIT=0, TSCOLAP=0 */ - saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00); - saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); - saa_writel(SAA7134_RS_CONTROL(5), control); - } + /* dma: setup channel 5 (= TS) */ + control = SAA7134_RS_CONTROL_BURST_16 | + SAA7134_RS_CONTROL_ME | + (buf->pt->dma >> 12); + + saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff)); + saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff)); + saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */ + saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE); + saa_writel(SAA7134_RS_CONTROL(5),control); buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; @@ -164,8 +140,6 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) if (0 == *count) *count = dev->ts.nr_bufs; *count = saa7134_buffer_count(*size,*count); - dev->buff_cnt = 0; - dev->ts_state = SAA7134_TS_STOPPED; return 0; } @@ -180,13 +154,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); - struct saa7134_dev *dev = q->priv_data; - if (dev->ts_state == SAA7134_TS_STARTED) { - /* Stop TS transport */ - saa_writeb(SAA7134_TS_PARALLEL, 0x6c); - dev->ts_state = SAA7134_TS_STOPPED; - } saa7134_dma_free(q,buf); } @@ -214,7 +182,7 @@ int saa7134_ts_init_hw(struct saa7134_dev *dev) /* deactivate TS softreset */ saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* TSSOP high active, TSVAL high active, TSLOCK ignored */ - saa_writeb(SAA7134_TS_PARALLEL, 0x6c); + saa_writeb(SAA7134_TS_PARALLEL, 0xec); saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1)); saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff)); saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff)); diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index 02bb6747a39c..68c268981861 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -628,9 +628,6 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev) if (card_in(dev, dev->ctl_input).tv) saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id); - /* Set the correct norm for the saa6752hs. This function - does nothing if there is no saa6752hs. */ - saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id); } static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) @@ -1333,8 +1330,6 @@ static int video_open(struct inode *inode, struct file *file) struct saa7134_fh *fh; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int radio = 0; - - lock_kernel(); list_for_each_entry(dev, &saa7134_devlist, devlist) { if (dev->video_dev && (dev->video_dev->minor == minor)) goto found; @@ -1347,7 +1342,6 @@ static int video_open(struct inode *inode, struct file *file) goto found; } } - unlock_kernel(); return -ENODEV; found: @@ -1356,10 +1350,8 @@ static int video_open(struct inode *inode, struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) { - unlock_kernel(); + if (NULL == fh) return -ENOMEM; - } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -1392,7 +1384,6 @@ static int video_open(struct inode *inode, struct file *file) /* switch to video/vbi mode */ video_mux(dev,dev->ctl_input); } - unlock_kernel(); return 0; } @@ -1799,25 +1790,18 @@ static int saa7134_querycap(struct file *file, void *priv, return 0; } -int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id) +static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) { + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; unsigned long flags; unsigned int i; v4l2_std_id fixup; int err; - /* When called from the empress code fh == NULL. - That needs to be fixed somehow, but for now this is - good enough. */ - if (fh) { - err = v4l2_prio_check(&dev->prio, &fh->prio); - if (0 != err) - return err; - } else if (res_locked(dev, RESOURCE_OVERLAY)) { - /* Don't change the std from the mpeg device - if overlay is active. */ - return -EBUSY; - } + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; for (i = 0; i < TVNORMS; i++) if (*id == tvnorms[i].id) @@ -1850,7 +1834,7 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_ *id = tvnorms[i].id; mutex_lock(&dev->lock); - if (fh && res_check(fh, RESOURCE_OVERLAY)) { + if (res_check(fh, RESOURCE_OVERLAY)) { spin_lock_irqsave(&dev->slock, flags); stop_preview(dev, fh); spin_unlock_irqrestore(&dev->slock, flags); @@ -1867,23 +1851,6 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_ mutex_unlock(&dev->lock); return 0; } -EXPORT_SYMBOL_GPL(saa7134_s_std_internal); - -static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct saa7134_fh *fh = priv; - - return saa7134_s_std_internal(fh->dev, fh, id); -} - -static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; - - *id = dev->tvnorm->id; - return 0; -} static int saa7134_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap) @@ -2110,6 +2077,18 @@ static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv, return 0; } +static int saa7134_enum_fmt_vbi_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (0 != f->index) + return -EINVAL; + + f->pixelformat = V4L2_PIX_FMT_GREY; + strcpy(f->description, "vbi data"); + + return 0; +} + static int saa7134_g_fbuf(struct file *file, void *f, struct v4l2_framebuffer *fb) { @@ -2400,6 +2379,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_g_fmt_vid_overlay = saa7134_g_fmt_vid_overlay, .vidioc_try_fmt_vid_overlay = saa7134_try_fmt_vid_overlay, .vidioc_s_fmt_vid_overlay = saa7134_s_fmt_vid_overlay, + .vidioc_enum_fmt_vbi_cap = saa7134_enum_fmt_vbi_cap, .vidioc_g_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, @@ -2411,7 +2391,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_qbuf = saa7134_qbuf, .vidioc_dqbuf = saa7134_dqbuf, .vidioc_s_std = saa7134_s_std, - .vidioc_g_std = saa7134_g_std, .vidioc_enum_input = saa7134_enum_input, .vidioc_g_input = saa7134_g_input, .vidioc_s_input = saa7134_s_input, diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index 491ab1f8fdd3..a0884f639f65 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -269,12 +269,6 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_M6_EXTRA 144 #define SAA7134_BOARD_AVERMEDIA_M103 145 #define SAA7134_BOARD_ASUSTeK_P7131_ANALOG 146 -#define SAA7134_BOARD_ASUSTeK_TIGER_3IN1 147 -#define SAA7134_BOARD_ENCORE_ENLTV_FM53 148 -#define SAA7134_BOARD_AVERMEDIA_M135A 149 -#define SAA7134_BOARD_REAL_ANGEL_220 150 -#define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151 -#define SAA7134_BOARD_ASUSTeK_TIGER 152 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 @@ -468,12 +462,6 @@ struct saa7134_mpeg_ops { void (*signal_change)(struct saa7134_dev *dev); }; -enum saa7134_ts_status { - SAA7134_TS_STOPPED, - SAA7134_TS_BUFF_DONE, - SAA7134_TS_STARTED, -}; - /* global device status */ struct saa7134_dev { struct list_head devlist; @@ -567,8 +555,6 @@ struct saa7134_dev { /* SAA7134_MPEG_* */ struct saa7134_ts ts; struct saa7134_dmaqueue ts_q; - enum saa7134_ts_status ts_state; - unsigned int buff_cnt; struct saa7134_mpeg_ops *mops; struct i2c_client *mpeg_i2c_client; @@ -658,7 +644,7 @@ extern struct pci_device_id __devinitdata saa7134_pci_tbl[]; extern int saa7134_board_init1(struct saa7134_dev *dev); extern int saa7134_board_init2(struct saa7134_dev *dev); -int saa7134_tuner_callback(void *priv, int component, int command, int arg); +int saa7134_tuner_callback(void *priv, int command, int arg); /* ----------------------------------------------------------- */ @@ -668,8 +654,6 @@ int saa7134_i2c_register(struct saa7134_dev *dev); int saa7134_i2c_unregister(struct saa7134_dev *dev); void saa7134_i2c_call_clients(struct saa7134_dev *dev, unsigned int cmd, void *arg); -int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, - unsigned int cmd, void *arg); /* ----------------------------------------------------------- */ @@ -682,7 +666,6 @@ extern struct video_device saa7134_radio_template; int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c); -int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id); int saa7134_videoport_init(struct saa7134_dev *dev); void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); diff --git a/trunk/drivers/media/video/se401.c b/trunk/drivers/media/video/se401.c index ae3949180c4e..acceed5d04ae 100644 --- a/trunk/drivers/media/video/se401.c +++ b/trunk/drivers/media/video/se401.c @@ -288,7 +288,7 @@ static void se401_button_irq(struct urb *urb) int status; if (!se401->dev) { - dev_info(&urb->dev->dev, "device vapourished\n"); + info("ohoh: device vapourished"); return; } @@ -328,7 +328,7 @@ static void se401_video_irq(struct urb *urb) return; if (!se401->dev) { - dev_info(&urb->dev->dev, "device vapourished\n"); + info ("ohoh: device vapourished"); return; } @@ -375,7 +375,7 @@ static void se401_video_irq(struct urb *urb) urb->status=0; urb->dev=se401->dev; if(usb_submit_urb(urb, GFP_KERNEL)) - dev_info(&urb->dev->dev, "urb burned down\n"); + info("urb burned down"); return; } @@ -860,8 +860,7 @@ static int se401_newframe(struct usb_se401 *se401, int framenr) ); if (se401->nullpackets > SE401_MAX_NULLPACKETS) { se401->nullpackets=0; - dev_info(&se401->dev->dev, - "too many null length packets, restarting capture\n"); + info("to many null length packets, restarting capture"); se401_stop_stream(se401); se401_start_stream(se401); } else { @@ -881,8 +880,7 @@ static int se401_newframe(struct usb_se401 *se401, int framenr) se401->scratch_use=0; if (errors > SE401_MAX_ERRORS) { errors=0; - dev_info(&se401->dev->dev, - "too many errors, restarting capture\n"); + info("to much errors, restarting capture"); se401_stop_stream(se401); se401_start_stream(se401); } @@ -915,7 +913,7 @@ static void usb_se401_remove_disconnected (struct usb_se401 *se401) usb_kill_urb(se401->inturb); usb_free_urb(se401->inturb); } - dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name); + info("%s disconnected", se401->camera_name); /* Free the memory */ kfree(se401->width); @@ -938,18 +936,14 @@ static int se401_open(struct inode *inode, struct file *file) struct usb_se401 *se401 = (struct usb_se401 *)dev; int err = 0; - lock_kernel(); - if (se401->user) { - unlock_kernel(); + if (se401->user) return -EBUSY; - } se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); if (se401->fbuf) file->private_data = dev; else err = -ENOMEM; se401->user = !err; - unlock_kernel(); return err; } @@ -962,8 +956,8 @@ static int se401_close(struct inode *inode, struct file *file) rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES); if (se401->removed) { - dev_info(&se401->dev->dev, "device unregistered\n"); usb_se401_remove_disconnected(se401); + info("device unregistered"); } else { for (i=0; iframe[i].grabstate=FRAME_UNUSED; @@ -1238,7 +1232,6 @@ static const struct file_operations se401_fops = { static struct video_device se401_template = { .name = "se401 USB camera", .fops = &se401_fops, - .release = video_device_release_empty, }; @@ -1278,7 +1271,7 @@ static int se401_init(struct usb_se401 *se401, int button) for (i=0; isizes; i++) { sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]); } - dev_info(&se401->dev->dev, "%s\n", temp); + info("%s", temp); se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3; rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); @@ -1312,8 +1305,7 @@ static int se401_init(struct usb_se401 *se401, int button) if (button) { se401->inturb=usb_alloc_urb(0, GFP_KERNEL); if (!se401->inturb) { - dev_info(&se401->dev->dev, - "Allocation of inturb failed\n"); + info("Allocation of inturb failed"); return 1; } usb_fill_int_urb(se401->inturb, se401->dev, @@ -1324,7 +1316,7 @@ static int se401_init(struct usb_se401 *se401, int button) 8 ); if (usb_submit_urb(se401->inturb, GFP_KERNEL)) { - dev_info(&se401->dev->dev, "int urb burned down\n"); + info("int urb burned down"); return 1; } } else @@ -1381,7 +1373,7 @@ static int se401_probe(struct usb_interface *intf, return -ENODEV; /* We found one */ - dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); + info("SE401 camera found: %s", camera_name); if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { err("couldn't kmalloc se401 struct"); @@ -1392,8 +1384,7 @@ static int se401_probe(struct usb_interface *intf, se401->iface = interface->bInterfaceNumber; se401->camera_name = camera_name; - dev_info(&intf->dev, "firmware version: %02x\n", - le16_to_cpu(dev->descriptor.bcdDevice) & 255); + info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255); if (se401_init(se401, button)) { kfree(se401); @@ -1411,8 +1402,7 @@ static int se401_probe(struct usb_interface *intf, err("video_register_device failed"); return -EIO; } - dev_info(&intf->dev, "registered new video device: video%d\n", - se401->vdev.minor); + info("registered new video device: video%d", se401->vdev.minor); usb_set_intfdata (intf, se401); return 0; @@ -1456,10 +1446,10 @@ static struct usb_driver se401_driver = { static int __init usb_se401_init(void) { - printk(KERN_INFO "SE401 usb camera driver version %s registering\n", version); + info("SE401 usb camera driver version %s registering", version); if (flickerless) if (flickerless!=50 && flickerless!=60) { - printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); + info("Invallid flickerless value, use 0, 50 or 60."); return -1; } return usb_register(&se401_driver); @@ -1468,7 +1458,7 @@ static int __init usb_se401_init(void) static void __exit usb_se401_exit(void) { usb_deregister(&se401_driver); - printk(KERN_INFO "SE401 driver deregistered\frame"); + info("SE401 driver deregistered"); } module_init(usb_se401_init); diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index 76838091dc66..318754e73132 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -304,6 +304,9 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) "SuperH Mobile CEU driver attached to camera %d\n", icd->devnum); + if (pcdev->pdata->enable_camera) + pcdev->pdata->enable_camera(); + ret = icd->ops->init(icd); if (ret) goto err; @@ -330,6 +333,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) ceu_write(pcdev, CEIER, 0); ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ icd->ops->release(icd); + if (pcdev->pdata->disable_camera) + pcdev->pdata->disable_camera(); dev_info(&icd->dev, "SuperH Mobile CEU driver detached from camera %d\n", diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_core.c b/trunk/drivers/media/video/sn9c102/sn9c102_core.c index 20e30bd9364b..2da6938718f2 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_core.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_core.c @@ -116,26 +116,6 @@ MODULE_PARM_DESC(debug, "\n"); #endif -/* - Add the probe entries to this table. Be sure to add the entry in the right - place, since, on failure, the next probing routine is called according to - the order of the list below, from top to bottom. -*/ -static int (*sn9c102_sensor_table[])(struct sn9c102_device *) = { - &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ - &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */ - &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ - &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */ - &sn9c102_probe_mt9v111, /* strong detection based on SENSOR ids */ - &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ - &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ - &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */ - &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */ - &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ - &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */ - &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ -}; - /*****************************************************************************/ static u32 @@ -1766,7 +1746,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp) if (!down_read_trylock(&sn9c102_dev_lock)) return -ERESTARTSYS; - cam = video_drvdata(filp); + cam = video_get_drvdata(video_devdata(filp)); if (wait_for_completion_interruptible(&cam->probe)) { up_read(&sn9c102_dev_lock); @@ -1863,7 +1843,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) down_write(&sn9c102_dev_lock); - cam = video_drvdata(filp); + cam = video_get_drvdata(video_devdata(filp)); sn9c102_stop_transfer(cam); sn9c102_release_buffers(cam); @@ -1883,7 +1863,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) static ssize_t sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) { - struct sn9c102_device *cam = video_drvdata(filp); + struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); struct sn9c102_frame_t* f, * i; unsigned long lock_flags; long timeout; @@ -2007,7 +1987,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) { - struct sn9c102_device *cam = video_drvdata(filp); + struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); struct sn9c102_frame_t* f; unsigned long lock_flags; unsigned int mask = 0; @@ -2083,7 +2063,7 @@ static struct vm_operations_struct sn9c102_vm_ops = { static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) { - struct sn9c102_device *cam = video_drvdata(filp); + struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, start = vma->vm_start; void *pos; @@ -3095,7 +3075,7 @@ sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg) static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, unsigned int cmd, void __user * arg) { - struct sn9c102_device *cam = video_drvdata(filp); + struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); switch (cmd) { @@ -3199,7 +3179,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, static int sn9c102_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg) { - struct sn9c102_device *cam = video_drvdata(filp); + struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); int err = 0; if (mutex_lock_interruptible(&cam->fileop_mutex)) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h b/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h index e23734f6d6e2..90a401dc3884 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -140,4 +140,24 @@ extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam); extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); +/* + Add the above entries to this table. Be sure to add the entry in the right + place, since, on failure, the next probing routine is called according to + the order of the list below, from top to bottom. +*/ +static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { + &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ + &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */ + &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */ + &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */ + &sn9c102_probe_mt9v111, /* strong detection based on SENSOR ids */ + &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ + &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ + &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */ + &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */ + &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ + &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */ + &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ +}; + #endif /* _SN9C102_DEVTABLE_H_ */ diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c index db2434948939..eaf9ad0dc8a6 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int hv7131d_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c index 4295887ff609..0fc401223cfc 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int hv7131r_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c b/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c index 1f5b09bec89c..00b134ca0a3d 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int mi0343_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c b/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c index d973fc1973d9..f8d81d82e8d5 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int mi0360_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_mt9v111.c b/trunk/drivers/media/video/sn9c102/sn9c102_mt9v111.c index 95986eb492e4..3b98ac3bbc38 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_mt9v111.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_mt9v111.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int mt9v111_init(struct sn9c102_device *cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c b/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c index 803712c29f02..e4856fd77982 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int ov7630_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c b/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c index 7977795d342b..8aae416ba8ec 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int ov7660_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c b/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c index 81cd969c1b7b..360f2a848bc0 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c @@ -21,7 +21,6 @@ #include #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int pas106b_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c index 2782f94cf6f8..ca4a1506ed3d 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c @@ -26,7 +26,6 @@ #include #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int pas202bcb_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c index 04cdfdde8564..e7d2de2bace1 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int tas5110c1b_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c index 9372e6f9fcff..d32fdbccdc5e 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int tas5110d_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c index a30bbc4389f5..56fb1d575a8a 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c @@ -20,7 +20,6 @@ ***************************************************************************/ #include "sn9c102_sensor.h" -#include "sn9c102_devtable.h" static int tas5130d1b_init(struct sn9c102_device* cam) diff --git a/trunk/drivers/media/video/stk-webcam.c b/trunk/drivers/media/video/stk-webcam.c index db69bc5556d6..ad36af30e099 100644 --- a/trunk/drivers/media/video/stk-webcam.c +++ b/trunk/drivers/media/video/stk-webcam.c @@ -65,6 +65,22 @@ static struct usb_device_id stkwebcam_table[] = { }; MODULE_DEVICE_TABLE(usb, stkwebcam_table); +static void stk_camera_cleanup(struct kref *kref) +{ + struct stk_camera *dev = to_stk_camera(kref); + + STK_INFO("Syntek USB2.0 Camera release resources" + " video device /dev/video%d\n", dev->vdev.minor); + video_unregister_device(&dev->vdev); + dev->vdev.priv = NULL; + + if (dev->sio_bufs != NULL || dev->isobufs != NULL) + STK_ERROR("We are leaking memory\n"); + usb_put_intf(dev->interface); + kfree(dev); +} + + /* * Basic stuff */ @@ -673,24 +689,34 @@ static int v4l_stk_open(struct inode *inode, struct file *fp) vdev = video_devdata(fp); dev = vdev_to_camera(vdev); - lock_kernel(); - if (dev == NULL || !is_present(dev)) { - unlock_kernel(); + if (dev == NULL || !is_present(dev)) return -ENXIO; - } - fp->private_data = dev; + fp->private_data = vdev; + kref_get(&dev->kref); usb_autopm_get_interface(dev->interface); - unlock_kernel(); return 0; } static int v4l_stk_release(struct inode *inode, struct file *fp) { - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev; + struct video_device *vdev; + + vdev = video_devdata(fp); + if (vdev == NULL) { + STK_ERROR("v4l_release called w/o video devdata\n"); + return -EFAULT; + } + dev = vdev_to_camera(vdev); + if (dev == NULL) { + STK_ERROR("v4l_release called on removed device\n"); + return -ENODEV; + } if (dev->owner != fp) { usb_autopm_put_interface(dev->interface); + kref_put(&dev->kref, stk_camera_cleanup); return 0; } @@ -701,6 +727,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) dev->owner = NULL; usb_autopm_put_interface(dev->interface); + kref_put(&dev->kref, stk_camera_cleanup); return 0; } @@ -711,8 +738,14 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, int i; int ret; unsigned long flags; + struct stk_camera *dev; + struct video_device *vdev; struct stk_sio_buffer *sbuf; - struct stk_camera *dev = fp->private_data; + + vdev = video_devdata(fp); + if (vdev == NULL) + return -EFAULT; + dev = vdev_to_camera(vdev); if (dev == NULL) return -EIO; @@ -771,8 +804,15 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf, static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) { - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev; + struct video_device *vdev; + + vdev = video_devdata(fp); + + if (vdev == NULL) + return -EFAULT; + dev = vdev_to_camera(vdev); if (dev == NULL) return -ENODEV; @@ -810,12 +850,16 @@ static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma) unsigned int i; int ret; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - struct stk_camera *dev = fp->private_data; + struct stk_camera *dev; + struct video_device *vdev; struct stk_sio_buffer *sbuf = NULL; if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) return -EINVAL; + vdev = video_devdata(fp); + dev = vdev_to_camera(vdev); + for (i = 0; i < dev->n_sbufs; i++) { if (dev->sio_bufs[i].v4lbuf.m.offset == offset) { sbuf = dev->sio_bufs + i; @@ -1311,12 +1355,6 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { static void stk_v4l_dev_release(struct video_device *vd) { - struct stk_camera *dev = vdev_to_camera(vd); - - if (dev->sio_bufs != NULL || dev->isobufs != NULL) - STK_ERROR("We are leaking memory\n"); - usb_put_intf(dev->interface); - kfree(dev); } static struct video_device stk_v4l_data = { @@ -1337,6 +1375,7 @@ static int stk_register_video_device(struct stk_camera *dev) dev->vdev = stk_v4l_data; dev->vdev.debug = debug; dev->vdev.parent = &dev->interface->dev; + dev->vdev.priv = dev; err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); if (err) STK_ERROR("v4l registration failed\n"); @@ -1353,7 +1392,7 @@ static int stk_camera_probe(struct usb_interface *interface, const struct usb_device_id *id) { int i; - int err = 0; + int err; struct stk_camera *dev = NULL; struct usb_device *udev = interface_to_usbdev(interface); @@ -1366,6 +1405,7 @@ static int stk_camera_probe(struct usb_interface *interface, return -ENOMEM; } + kref_init(&dev->kref); spin_lock_init(&dev->spinlock); init_waitqueue_head(&dev->wait_frame); @@ -1398,8 +1438,8 @@ static int stk_camera_probe(struct usb_interface *interface, } if (!dev->isoc_ep) { STK_ERROR("Could not find isoc-in endpoint"); - err = -ENODEV; - goto error; + kref_put(&dev->kref, stk_camera_cleanup); + return -ENODEV; } dev->vsettings.brightness = 0x7fff; dev->vsettings.palette = V4L2_PIX_FMT_RGB565; @@ -1413,17 +1453,14 @@ static int stk_camera_probe(struct usb_interface *interface, err = stk_register_video_device(dev); if (err) { - goto error; + kref_put(&dev->kref, stk_camera_cleanup); + return err; } stk_create_sysfs_files(&dev->vdev); usb_autopm_enable(dev->interface); return 0; - -error: - kfree(dev); - return err; } static void stk_camera_disconnect(struct usb_interface *interface) @@ -1436,10 +1473,7 @@ static void stk_camera_disconnect(struct usb_interface *interface) wake_up_interruptible(&dev->wait_frame); stk_remove_sysfs_files(&dev->vdev); - STK_INFO("Syntek USB2.0 Camera release resources" - "video device /dev/video%d\n", dev->vdev.minor); - - video_unregister_device(&dev->vdev); + kref_put(&dev->kref, stk_camera_cleanup); } #ifdef CONFIG_PM diff --git a/trunk/drivers/media/video/stk-webcam.h b/trunk/drivers/media/video/stk-webcam.h index 084a85bdd16e..df4dfefc5327 100644 --- a/trunk/drivers/media/video/stk-webcam.h +++ b/trunk/drivers/media/video/stk-webcam.h @@ -99,6 +99,7 @@ struct stk_camera { u8 isoc_ep; + struct kref kref; /* Not sure if this is right */ atomic_t urbs_used; @@ -120,6 +121,7 @@ struct stk_camera { unsigned sequence; }; +#define to_stk_camera(d) container_of(d, struct stk_camera, kref) #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) void stk_camera_delete(struct kref *); diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c index bbad54f85c83..276bded06ab3 100644 --- a/trunk/drivers/media/video/stradis.c +++ b/trunk/drivers/media/video/stradis.c @@ -1882,16 +1882,12 @@ static int saa_open(struct inode *inode, struct file *file) struct video_device *vdev = video_devdata(file); struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev); - lock_kernel(); file->private_data = saa; saa->user++; - if (saa->user > 1) { - unlock_kernel(); + if (saa->user > 1) return 0; /* device open already, don't reset */ - } saa->writemode = VID_WRITE_MPEG_VID; /* default to video */ - unlock_kernel(); return 0; } @@ -1925,7 +1921,6 @@ static struct video_device saa_template = { .name = "SAA7146A", .fops = &saa_fops, .minor = -1, - .release = video_device_release_empty, }; static int __devinit configure_saa7146(struct pci_dev *pdev, int num) diff --git a/trunk/drivers/media/video/stv680.c b/trunk/drivers/media/video/stv680.c index 9c549d935994..dce947439459 100644 --- a/trunk/drivers/media/video/stv680.c +++ b/trunk/drivers/media/video/stv680.c @@ -84,8 +84,7 @@ static unsigned int debug; #define PDEBUG(level, fmt, args...) \ do { \ if (debug >= level) \ - printk(KERN_INFO KBUILD_MODNAME " [%s:%d] \n" fmt, \ - __func__, __LINE__ , ## args); \ + info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ } while (0) @@ -1087,7 +1086,6 @@ static int stv_open (struct inode *inode, struct file *file) int err = 0; /* we are called with the BKL held */ - lock_kernel(); stv680->user = 1; err = stv_init (stv680); /* main initialization routine for camera */ @@ -1101,7 +1099,6 @@ static int stv_open (struct inode *inode, struct file *file) } if (err) stv680->user = 0; - unlock_kernel(); return err; } @@ -1553,8 +1550,7 @@ static int __init usb_stv680_init (void) } PDEBUG (0, "STV(i): usb camera driver version %s registering", DRIVER_VERSION); - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_DESC " " DRIVER_VERSION); return 0; } diff --git a/trunk/drivers/media/video/tda9840.c b/trunk/drivers/media/video/tda9840.c index 1c391f0328fd..2437c1a269c5 100644 --- a/trunk/drivers/media/video/tda9840.c +++ b/trunk/drivers/media/video/tda9840.c @@ -2,7 +2,6 @@ tda9840 - i2c-driver for the tda9840 by SGS Thomson Copyright (C) 1998-2003 Michael Hunold - Copyright (C) 2008 Hans Verkuil The tda9840 is a stereo/dual sound processor with digital identification. It can be found at address 0x84 on the i2c-bus. @@ -29,118 +28,59 @@ #include #include #include -#include -#include -#include "tda9840.h" -MODULE_AUTHOR("Michael Hunold "); -MODULE_DESCRIPTION("tda9840 driver"); -MODULE_LICENSE("GPL"); +#include "tda9840.h" -static int debug; +static int debug; /* insmod parameter */ module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(args...) \ + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) #define SWITCH 0x00 #define LEVEL_ADJUST 0x02 #define STEREO_ADJUST 0x03 #define TEST 0x04 -#define TDA9840_SET_MUTE 0x00 -#define TDA9840_SET_MONO 0x10 -#define TDA9840_SET_STEREO 0x2a -#define TDA9840_SET_LANG1 0x12 -#define TDA9840_SET_LANG2 0x1e -#define TDA9840_SET_BOTH 0x1a -#define TDA9840_SET_BOTH_R 0x16 -#define TDA9840_SET_EXTERNAL 0x7a - /* addresses to scan, found only at 0x42 (7-Bit) */ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; -static void tda9840_write(struct i2c_client *client, u8 reg, u8 val) -{ - if (i2c_smbus_write_byte_data(client, reg, val)) - v4l_dbg(1, debug, client, "error writing %02x to %02x\n", - val, reg); -} +static struct i2c_driver driver; +static struct i2c_client client_template; -static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) +static int command(struct i2c_client *client, unsigned int cmd, void *arg) { + int result; int byte = *(int *)arg; switch (cmd) { - case VIDIOC_S_TUNER: { - struct v4l2_tuner *t = arg; - int byte; - - if (t->index) + case TDA9840_SWITCH: + + dprintk("TDA9840_SWITCH: 0x%02x\n", byte); + + if (byte != TDA9840_SET_MONO + && byte != TDA9840_SET_MUTE + && byte != TDA9840_SET_STEREO + && byte != TDA9840_SET_LANG1 + && byte != TDA9840_SET_LANG2 + && byte != TDA9840_SET_BOTH + && byte != TDA9840_SET_BOTH_R + && byte != TDA9840_SET_EXTERNAL) { return -EINVAL; - - switch (t->audmode) { - case V4L2_TUNER_MODE_STEREO: - byte = TDA9840_SET_STEREO; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - byte = TDA9840_SET_BOTH; - break; - case V4L2_TUNER_MODE_LANG1: - byte = TDA9840_SET_LANG1; - break; - case V4L2_TUNER_MODE_LANG2: - byte = TDA9840_SET_LANG2; - break; - default: - byte = TDA9840_SET_MONO; - break; - } - v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte); - tda9840_write(client, SWITCH, byte); - break; - } - - case VIDIOC_G_TUNER: { - struct v4l2_tuner *t = arg; - u8 byte; - - t->rxsubchans = V4L2_TUNER_SUB_MONO; - if (1 != i2c_master_recv(client, &byte, 1)) { - v4l_dbg(1, debug, client, - "i2c_master_recv() failed\n"); - return -EIO; } - if (byte & 0x80) { - v4l_dbg(1, debug, client, - "TDA9840_DETECT: register contents invalid\n"); - return -EINVAL; - } - - v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", byte); - - switch (byte & 0x60) { - case 0x00: - t->rxsubchans = V4L2_TUNER_SUB_MONO; - break; - case 0x20: - t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - break; - case 0x40: - t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; - break; - default: /* Incorrect detect */ - t->rxsubchans = V4L2_TUNER_MODE_MONO; - break; - } + result = i2c_smbus_write_byte_data(client, SWITCH, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); break; - } case TDA9840_LEVEL_ADJUST: - v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte); + + dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte); /* check for correct range */ if (byte > 25 || byte < -20) @@ -152,11 +92,15 @@ static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) byte += 0x8; else byte = -byte; - tda9840_write(client, LEVEL_ADJUST, byte); + + result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); break; case TDA9840_STEREO_ADJUST: - v4l_dbg(1, debug, client, "TDA9840_STEREO_ADJUST: %d\n", byte); + + dprintk("TDA9840_STEREO_ADJUST: %d\n", byte); /* check for correct range */ if (byte > 25 || byte < -24) @@ -169,59 +113,143 @@ static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) else byte = -byte; - tda9840_write(client, STEREO_ADJUST, byte); + result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + break; + + case TDA9840_DETECT: { + int *ret = (int *)arg; + + byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST); + if (byte == -1) { + dprintk("i2c_smbus_read_byte_data() failed\n"); + return -EIO; + } + + if (0 != (byte & 0x80)) { + dprintk("TDA9840_DETECT: register contents invalid\n"); + return -EINVAL; + } + + dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte); + *ret = ((byte & 0x60) >> 5); + result = 0; + break; + } + case TDA9840_TEST: + dprintk("TDA9840_TEST: 0x%02x\n", byte); + + /* mask out irrelevant bits */ + byte &= 0x3; + + result = i2c_smbus_write_byte_data(client, TEST, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); break; default: return -ENOIOCTLCMD; } + if (result) + return -EIO; + return 0; } -static int tda9840_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int detect(struct i2c_adapter *adapter, int address, int kind) { - int result; - int byte; + struct i2c_client *client; + int result = 0; + + int byte = 0x0; /* let's see whether this adapter can support what we need */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA | - I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + if (0 == i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { return 0; + } + + /* allocate memory for client structure */ + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) { + printk("not enough kernel memory\n"); + return -ENOMEM; + } + + /* fill client structure */ + memcpy(client, &client_template, sizeof(struct i2c_client)); + client->addr = address; + client->adapter = adapter; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + /* tell the i2c layer a new client has arrived */ + if (0 != (result = i2c_attach_client(client))) { + kfree(client); + return result; + } /* set initial values for level & stereo - adjustment, mode */ byte = 0; - result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte); - result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte); - tda9840_write(client, SWITCH, TDA9840_SET_STEREO); + result = command(client, TDA9840_LEVEL_ADJUST, &byte); + result += command(client, TDA9840_STEREO_ADJUST, &byte); + byte = TDA9840_SET_MONO; + result = command(client, TDA9840_SWITCH, &byte); if (result) { - v4l_dbg(1, debug, client, "could not initialize tda9840\n"); + dprintk("could not initialize tda9840\n"); return -ENODEV; } + + printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); return 0; } -static int tda9840_legacy_probe(struct i2c_adapter *adapter) +static int attach(struct i2c_adapter *adapter) +{ + /* let's see whether this is a know adapter we can attach to */ + if (adapter->id != I2C_HW_SAA7146) { + dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); + return -ENODEV; + } + + return i2c_probe(adapter, &addr_data, &detect); +} + +static int detach(struct i2c_client *client) { - /* Let's see whether this is a known adapter we can attach to. - Prevents conflicts with tvaudio.c. */ - return adapter->id == I2C_HW_SAA7146; + int ret = i2c_detach_client(client); + kfree(client); + return ret; } -static const struct i2c_device_id tda9840_id[] = { - { "tda9840", 0 }, - { } + +static struct i2c_driver driver = { + .driver = { + .name = "tda9840", + }, + .id = I2C_DRIVERID_TDA9840, + .attach_adapter = attach, + .detach_client = detach, + .command = command, }; -MODULE_DEVICE_TABLE(i2c, tda9840_id); -static struct v4l2_i2c_driver_data v4l2_i2c_data = { +static struct i2c_client client_template = { .name = "tda9840", - .driverid = I2C_DRIVERID_TDA9840, - .command = tda9840_command, - .probe = tda9840_probe, - .legacy_probe = tda9840_legacy_probe, - .id_table = tda9840_id, + .driver = &driver, }; + +static int __init this_module_init(void) +{ + return i2c_add_driver(&driver); +} + +static void __exit this_module_exit(void) +{ + i2c_del_driver(&driver); +} + +module_init(this_module_init); +module_exit(this_module_exit); + +MODULE_AUTHOR("Michael Hunold "); +MODULE_DESCRIPTION("tda9840 driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/tda9840.h b/trunk/drivers/media/video/tda9840.h index dc12ae7caf6f..7da8432cdca7 100644 --- a/trunk/drivers/media/video/tda9840.h +++ b/trunk/drivers/media/video/tda9840.h @@ -3,6 +3,24 @@ #define I2C_ADDR_TDA9840 0x42 +#define TDA9840_DETECT _IOR('v',1,int) +/* return values for TDA9840_DETCT */ +#define TDA9840_MONO_DETECT 0x0 +#define TDA9840_DUAL_DETECT 0x1 +#define TDA9840_STEREO_DETECT 0x2 +#define TDA9840_INCORRECT_DETECT 0x3 + +#define TDA9840_SWITCH _IOW('v',2,int) +/* modes than can be set with TDA9840_SWITCH */ +#define TDA9840_SET_MUTE 0x00 +#define TDA9840_SET_MONO 0x10 +#define TDA9840_SET_STEREO 0x2a +#define TDA9840_SET_LANG1 0x12 +#define TDA9840_SET_LANG2 0x1e +#define TDA9840_SET_BOTH 0x1a +#define TDA9840_SET_BOTH_R 0x16 +#define TDA9840_SET_EXTERNAL 0x7a + /* values may range between +2.5 and -2.0; the value has to be multiplied with 10 */ #define TDA9840_LEVEL_ADJUST _IOW('v',3,int) @@ -11,4 +29,7 @@ the value has to be multiplied with 10 */ #define TDA9840_STEREO_ADJUST _IOW('v',4,int) +/* currently not implemented */ +#define TDA9840_TEST _IOW('v',5,int) + #endif diff --git a/trunk/drivers/media/video/tea6415c.c b/trunk/drivers/media/video/tea6415c.c index cde092adbb5a..421c1445e96c 100644 --- a/trunk/drivers/media/video/tea6415c.c +++ b/trunk/drivers/media/video/tea6415c.c @@ -2,7 +2,6 @@ tea6415c - i2c-driver for the tea6415c by SGS Thomson Copyright (C) 1998-2003 Michael Hunold - Copyright (C) 2008 Hans Verkuil The tea6415c is a bus controlled video-matrix-switch with 8 inputs and 6 outputs. @@ -31,18 +30,18 @@ #include #include #include -#include -#include -#include "tea6415c.h" -MODULE_AUTHOR("Michael Hunold "); -MODULE_DESCRIPTION("tea6415c driver"); -MODULE_LICENSE("GPL"); +#include "tea6415c.h" -static int debug; +static int debug; /* insmod parameter */ module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); + +#define dprintk(args...) \ + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) -MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define TEA6415C_NUM_INPUTS 8 +#define TEA6415C_NUM_OUTPUTS 6 /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; @@ -50,6 +49,60 @@ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIEN /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; +static struct i2c_driver driver; +static struct i2c_client client_template; + +/* this function is called by i2c_probe */ +static int detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *client = NULL; + int err = 0; + + /* let's see whether this adapter can support what we need */ + if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { + return 0; + } + + /* allocate memory for client structure */ + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) { + return -ENOMEM; + } + + /* fill client structure */ + memcpy(client, &client_template, sizeof(struct i2c_client)); + client->addr = address; + client->adapter = adapter; + + /* tell the i2c layer a new client has arrived */ + if (0 != (err = i2c_attach_client(client))) { + kfree(client); + return err; + } + + printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); + + return 0; +} + +static int attach(struct i2c_adapter *adapter) +{ + /* let's see whether this is a know adapter we can attach to */ + if (adapter->id != I2C_HW_SAA7146) { + dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); + return -ENODEV; + } + + return i2c_probe(adapter, &addr_data, &detect); +} + +static int detach(struct i2c_client *client) +{ + int ret = i2c_detach_client(client); + kfree(client); + return ret; +} + /* makes a connection between the input-pin 'i' and the output-pin 'o' for the tea6415c-client 'client' */ static int switch_matrix(struct i2c_client *client, int i, int o) @@ -57,7 +110,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) u8 byte = 0; int ret; - v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); + dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); /* check if the pins are valid */ if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) @@ -115,14 +168,14 @@ static int switch_matrix(struct i2c_client *client, int i, int o) ret = i2c_smbus_write_byte(client, byte); if (ret) { - v4l_dbg(1, debug, client, - "i2c_smbus_write_byte() failed, ret:%d\n", ret); + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } + return ret; } -static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) +static int command(struct i2c_client *client, unsigned int cmd, void *arg) { struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; int result = 0; @@ -134,40 +187,38 @@ static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) default: return -ENOIOCTLCMD; } + return result; } -/* this function is called by i2c_probe */ -static int tea6415c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - /* let's see whether this adapter can support what we need */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) - return 0; +static struct i2c_driver driver = { + .driver = { + .name = "tea6415c", + }, + .id = I2C_DRIVERID_TEA6415C, + .attach_adapter = attach, + .detach_client = detach, + .command = command, +}; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - return 0; +static struct i2c_client client_template = { + .name = "tea6415c", + .driver = &driver, +}; + +static int __init this_module_init(void) +{ + return i2c_add_driver(&driver); } -static int tea6415c_legacy_probe(struct i2c_adapter *adapter) +static void __exit this_module_exit(void) { - /* Let's see whether this is a known adapter we can attach to. - Prevents conflicts with tvaudio.c. */ - return adapter->id == I2C_HW_SAA7146; + i2c_del_driver(&driver); } -static const struct i2c_device_id tea6415c_id[] = { - { "tea6415c", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tea6415c_id); +module_init(this_module_init); +module_exit(this_module_exit); -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "tea6415c", - .driverid = I2C_DRIVERID_TEA6415C, - .command = tea6415c_command, - .probe = tea6415c_probe, - .legacy_probe = tea6415c_legacy_probe, - .id_table = tea6415c_id, -}; +MODULE_AUTHOR("Michael Hunold "); +MODULE_DESCRIPTION("tea6415c driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/tea6420.c b/trunk/drivers/media/video/tea6420.c index e50820969e64..b5c8957d130e 100644 --- a/trunk/drivers/media/video/tea6420.c +++ b/trunk/drivers/media/video/tea6420.c @@ -2,7 +2,6 @@ tea6420 - i2c-driver for the tea6420 by SGS Thomson Copyright (C) 1998-2003 Michael Hunold - Copyright (C) 2008 Hans Verkuil The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, 4 stereo outputs and gain control for each output. @@ -31,18 +30,15 @@ #include #include #include -#include -#include -#include "tea6420.h" -MODULE_AUTHOR("Michael Hunold "); -MODULE_DESCRIPTION("tea6420 driver"); -MODULE_LICENSE("GPL"); +#include "tea6420.h" -static int debug; +static int debug; /* insmod parameter */ module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define dprintk(args...) \ + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; @@ -50,20 +46,23 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; +static struct i2c_driver driver; +static struct i2c_client client_template; + /* make a connection between the input 'i' and the output 'o' with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) { - u8 byte; + u8 byte = 0; int ret; - v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g); + dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g); /* check if the parameters are valid */ if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) return -1; - byte = ((o - 1) << 5); + byte = ((o - 1) << 5); byte |= (i - 1); /* to understand this, have a look at the tea6420-specs (p.5) */ @@ -83,41 +82,40 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) ret = i2c_smbus_write_byte(client, byte); if (ret) { - v4l_dbg(1, debug, client, - "i2c_smbus_write_byte() failed, ret:%d\n", ret); + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } + return 0; } -static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg) +/* this function is called by i2c_probe */ +static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) { - struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; - int result = 0; + struct i2c_client *client; + int err = 0, i = 0; - switch (cmd) { - case TEA6420_SWITCH: - result = tea6420_switch(client, a->in, a->out, a->gain); - break; - default: - return -ENOIOCTLCMD; + /* let's see whether this adapter can support what we need */ + if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { + return 0; } - return result; -} + /* allocate memory for client structure */ + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) { + return -ENOMEM; + } -/* this function is called by i2c_probe */ -static int tea6420_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err, i; + /* fill client structure */ + memcpy(client, &client_template, sizeof(struct i2c_client)); + client->addr = address; + client->adapter = adapter; - /* let's see whether this adapter can support what we need */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) - return -EIO; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + /* tell the i2c layer a new client has arrived */ + if (0 != (err = i2c_attach_client(client))) { + kfree(client); + return err; + } /* set initial values: set "mute"-input to all outputs at gain 0 */ err = 0; @@ -125,31 +123,78 @@ static int tea6420_probe(struct i2c_client *client, err += tea6420_switch(client, 6, i, 0); } if (err) { - v4l_dbg(1, debug, client, "could not initialize tea6420\n"); + dprintk("could not initialize tea6420\n"); kfree(client); return -ENODEV; } + + printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); + return 0; } -static int tea6420_legacy_probe(struct i2c_adapter *adapter) +static int attach(struct i2c_adapter *adapter) { - /* Let's see whether this is a known adapter we can attach to. - Prevents conflicts with tvaudio.c. */ - return adapter->id == I2C_HW_SAA7146; + /* let's see whether this is a know adapter we can attach to */ + if (adapter->id != I2C_HW_SAA7146) { + dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); + return -ENODEV; + } + + return i2c_probe(adapter, &addr_data, &tea6420_detect); +} + +static int detach(struct i2c_client *client) +{ + int ret = i2c_detach_client(client); + kfree(client); + return ret; +} + +static int command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; + int result = 0; + + switch (cmd) { + case TEA6420_SWITCH: + result = tea6420_switch(client, a->in, a->out, a->gain); + break; + default: + return -ENOIOCTLCMD; + } + + return result; } -static const struct i2c_device_id tea6420_id[] = { - { "tea6420", 0 }, - { } +static struct i2c_driver driver = { + .driver = { + .name = "tea6420", + }, + .id = I2C_DRIVERID_TEA6420, + .attach_adapter = attach, + .detach_client = detach, + .command = command, }; -MODULE_DEVICE_TABLE(i2c, tea6420_id); -static struct v4l2_i2c_driver_data v4l2_i2c_data = { +static struct i2c_client client_template = { .name = "tea6420", - .driverid = I2C_DRIVERID_TEA6420, - .command = tea6420_command, - .probe = tea6420_probe, - .legacy_probe = tea6420_legacy_probe, - .id_table = tea6420_id, + .driver = &driver, }; + +static int __init this_module_init(void) +{ + return i2c_add_driver(&driver); +} + +static void __exit this_module_exit(void) +{ + i2c_del_driver(&driver); +} + +module_init(this_module_init); +module_exit(this_module_exit); + +MODULE_AUTHOR("Michael Hunold "); +MODULE_DESCRIPTION("tea6420 driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/tuner-3036.c b/trunk/drivers/media/video/tuner-3036.c new file mode 100644 index 000000000000..bdf506e6ae27 --- /dev/null +++ b/trunk/drivers/media/video/tuner-3036.c @@ -0,0 +1,214 @@ +/* + * Driver for Philips SAB3036 "CITAC" tuner control chip. + * + * Author: Phil Blundell + * + * The SAB3036 is just about different enough from the chips that + * tuner.c copes with to make it not worth the effort to crowbar + * the support into that file. So instead we have a separate driver. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +static int debug; /* insmod parameter */ +static int this_adap; + +static struct i2c_client client_template; + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END }; +static unsigned short ignore = I2C_CLIENT_END; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_i2c, + .probe = &ignore, + .ignore = &ignore, +}; + +/* ---------------------------------------------------------------------- */ + +static unsigned char +tuner_getstatus (struct i2c_client *c) +{ + unsigned char byte; + if (i2c_master_recv(c, &byte, 1) != 1) + printk(KERN_ERR "tuner-3036: I/O error.\n"); + return byte; +} + +#define TUNER_FL 0x80 + +static int +tuner_islocked (struct i2c_client *c) +{ + return (tuner_getstatus(c) & TUNER_FL); +} + +/* ---------------------------------------------------------------------- */ + +static void +set_tv_freq(struct i2c_client *c, int freq) +{ + u16 div = ((freq * 20) / 16); + unsigned long give_up = jiffies + HZ; + unsigned char buffer[2]; + + if (debug) + printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div); + + /* Select high tuning current */ + buffer[0] = 0x29; + buffer[1] = 0x3e; + + if (i2c_master_send(c, buffer, 2) != 2) + printk("tuner: i2c i/o error 1\n"); + + buffer[0] = 0x80 | ((div>>8) & 0x7f); + buffer[1] = div & 0xff; + + if (i2c_master_send(c, buffer, 2) != 2) + printk("tuner: i2c i/o error 2\n"); + + while (!tuner_islocked(c) && time_before(jiffies, give_up)) + schedule(); + + if (!tuner_islocked(c)) + printk(KERN_WARNING "tuner: failed to achieve PLL lock\n"); + + /* Select low tuning current and engage AFC */ + buffer[0] = 0x29; + buffer[1] = 0xb2; + + if (i2c_master_send(c, buffer, 2) != 2) + printk("tuner: i2c i/o error 3\n"); + + if (debug) + printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c)); +} + +/* ---------------------------------------------------------------------- */ + +static int +tuner_attach(struct i2c_adapter *adap, int addr, int kind) +{ + static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 }; + + struct i2c_client *client; + + if (this_adap > 0) + return -1; + this_adap++; + + client_template.adapter = adap; + client_template.addr = addr; + + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + memcpy(client, &client_template, sizeof(struct i2c_client)); + + printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client)); + + i2c_attach_client(client); + + if (i2c_master_send(client, buffer, 2) != 2) + printk("tuner: i2c i/o error 1\n"); + if (i2c_master_send(client, buffer+2, 2) != 2) + printk("tuner: i2c i/o error 2\n"); + if (i2c_master_send(client, buffer+4, 2) != 2) + printk("tuner: i2c i/o error 3\n"); + return 0; +} + +static int +tuner_detach(struct i2c_client *c) +{ + return 0; +} + +static int +tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + int *iarg = (int*)arg; + + switch (cmd) + { + case VIDIOCSFREQ: + set_tv_freq(client, *iarg); + break; + + default: + return -EINVAL; + } + return 0; +} + +static int +tuner_probe(struct i2c_adapter *adap) +{ + this_adap = 0; + if (adap->id == I2C_HW_B_LP) + return i2c_probe(adap, &addr_data, tuner_attach); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static struct i2c_driver +i2c_driver_tuner = +{ + .driver = { + .name = "sab3036", + }, + .id = I2C_DRIVERID_SAB3036, + .attach_adapter = tuner_probe, + .detach_client = tuner_detach, + .command = tuner_command +}; + +static struct i2c_client client_template = +{ + .driver = &i2c_driver_tuner, + .name = "SAB3036", +}; + +static int __init +tuner3036_init(void) +{ + return i2c_add_driver(&i2c_driver_tuner); +} + +static void __exit +tuner3036_exit(void) +{ + i2c_del_driver(&i2c_driver_tuner); +} + +MODULE_DESCRIPTION("SAB3036 tuner driver"); +MODULE_AUTHOR("Philip Blundell "); +MODULE_LICENSE("GPL"); + +module_param(debug, int, 0); +MODULE_PARM_DESC(debug,"Enable debugging output"); + +module_init(tuner3036_init); +module_exit(tuner3036_exit); diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 4a7735c6c1a6..d806a3556eed 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -92,6 +92,7 @@ struct tuner { unsigned int type; /* chip type id */ unsigned int config; + int (*tuner_callback) (void *dev, int command, int arg); const char *name; }; @@ -345,7 +346,7 @@ static struct xc5000_config xc5000_cfg; static void set_type(struct i2c_client *c, unsigned int type, unsigned int new_mode_mask, unsigned int new_config, - int (*tuner_callback) (void *dev, int component, int cmd, int arg)) + int (*tuner_callback) (void *dev, int command,int arg)) { struct tuner *t = i2c_get_clientdata(c); struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; @@ -361,7 +362,7 @@ static void set_type(struct i2c_client *c, unsigned int type, t->config = new_config; if (tuner_callback != NULL) { tuner_dbg("defining GPIO callback\n"); - t->fe.callback = tuner_callback; + t->tuner_callback = tuner_callback; } if (t->mode == T_UNINITIALIZED) { @@ -384,6 +385,7 @@ static void set_type(struct i2c_client *c, unsigned int type, { struct tda829x_config cfg = { .lna_cfg = t->config, + .tuner_callback = t->tuner_callback, }; if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter, t->i2c->addr, &cfg)) @@ -431,6 +433,7 @@ static void set_type(struct i2c_client *c, unsigned int type, struct xc2028_config cfg = { .i2c_adap = t->i2c->adapter, .i2c_addr = t->i2c->addr, + .callback = t->tuner_callback, }; if (!dvb_attach(xc2028_attach, &t->fe, &cfg)) goto attach_failed; @@ -447,8 +450,10 @@ static void set_type(struct i2c_client *c, unsigned int type, xc5000_cfg.i2c_address = t->i2c->addr; xc5000_cfg.if_khz = 5380; + xc5000_cfg.tuner_callback = t->tuner_callback; if (!dvb_attach(xc5000_attach, - &t->fe, t->i2c->adapter, &xc5000_cfg)) + &t->fe, t->i2c->adapter, &xc5000_cfg, + c->adapter->algo_data)) goto attach_failed; xc_tuner_ops = &t->fe.ops.tuner_ops; @@ -1220,7 +1225,7 @@ static int tuner_probe(struct i2c_client *client, } else { t->mode = V4L2_TUNER_DIGITAL_TV; } - set_type(client, t->type, t->mode_mask, t->config, t->fe.callback); + set_type(client, t->type, t->mode_mask, t->config, t->tuner_callback); list_add_tail(&t->list, &tuner_list); return 0; } diff --git a/trunk/drivers/media/video/usbvideo/ibmcam.c b/trunk/drivers/media/video/usbvideo/ibmcam.c index 28421d386f1e..cc27efe121dd 100644 --- a/trunk/drivers/media/video/usbvideo/ibmcam.c +++ b/trunk/drivers/media/video/usbvideo/ibmcam.c @@ -258,9 +258,7 @@ static enum ParseState ibmcam_find_header(struct uvd *uvd) /* FIXME: Add frame h (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00)) { #if 0 /* This code helps to detect new frame markers */ - dev_info(&uvd->dev->dev, - "Header sig: 00 FF 00 %02X\n", - RING_QUEUE_PEEK(&uvd->dp, 3)); + info("Header sig: 00 FF 00 %02X", RING_QUEUE_PEEK(&uvd->dp, 3)); #endif frame->header = RING_QUEUE_PEEK(&uvd->dp, 3); if ((frame->header == HDRSIG_MODEL1_128x96) || @@ -268,8 +266,7 @@ static enum ParseState ibmcam_find_header(struct uvd *uvd) /* FIXME: Add frame h (frame->header == HDRSIG_MODEL1_352x288)) { #if 0 - dev_info(&uvd->dev->dev, - "Header found.\n"); + info("Header found."); #endif RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len); icam->has_hdr = 1; @@ -298,7 +295,7 @@ case IBMCAM_MODEL_4: (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF)) { #if 0 - dev_info(&uvd->dev->dev, "Header found.\n"); + info("Header found."); #endif RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len); icam->has_hdr = 1; @@ -341,7 +338,7 @@ case IBMCAM_MODEL_4: byte4 = RING_QUEUE_PEEK(&uvd->dp, 3); frame->header = (byte3 << 8) | byte4; #if 0 - dev_info(&uvd->dev->dev, "Header found.\n"); + info("Header found."); #endif RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len); icam->has_hdr = 1; @@ -357,8 +354,7 @@ case IBMCAM_MODEL_4: } if (!icam->has_hdr) { if (uvd->debug > 2) - dev_info(&uvd->dev->dev, - "Skipping frame, no header\n"); + info("Skipping frame, no header"); return scan_EndParse; } @@ -885,9 +881,7 @@ static enum ParseState ibmcam_model3_parse_lines( */ if ((frame->curline + 1) >= data_h) { if (uvd->debug >= 3) - dev_info(&uvd->dev->dev, - "Reached line %d. (frame is done)\n", - frame->curline); + info("Reached line %d. (frame is done)", frame->curline); return scan_NextFrame; } @@ -960,9 +954,8 @@ static enum ParseState ibmcam_model3_parse_lines( if (frame->curline >= VIDEOSIZE_Y(frame->request)) { if (uvd->debug >= 3) { - dev_info(&uvd->dev->dev, - "All requested lines (%ld.) done.\n", - VIDEOSIZE_Y(frame->request)); + info("All requested lines (%ld.) done.", + VIDEOSIZE_Y(frame->request)); } return scan_NextFrame; } else @@ -1007,9 +1000,7 @@ static enum ParseState ibmcam_model4_128x96_parse_lines( */ if ((frame->curline + 1) >= data_h) { if (uvd->debug >= 3) - dev_info(&uvd->dev->dev, - "Reached line %d. (frame is done)\n", - frame->curline); + info("Reached line %d. (frame is done)", frame->curline); return scan_NextFrame; } @@ -1058,9 +1049,8 @@ static enum ParseState ibmcam_model4_128x96_parse_lines( if (frame->curline >= VIDEOSIZE_Y(frame->request)) { if (uvd->debug >= 3) { - dev_info(&uvd->dev->dev, - "All requested lines (%ld.) done.\n", - VIDEOSIZE_Y(frame->request)); + info("All requested lines (%ld.) done.", + VIDEOSIZE_Y(frame->request)); } return scan_NextFrame; } else @@ -1181,11 +1171,10 @@ static int ibmcam_veio( sizeof(cp), 1000); #if 0 - dev_info(&uvd->dev->dev, - "USB => %02x%02x%02x%02x%02x%02x%02x%02x " - "(req=$%02x val=$%04x ind=$%04x)\n", - cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], - req, value, index); + info("USB => %02x%02x%02x%02x%02x%02x%02x%02x " + "(req=$%02x val=$%04x ind=$%04x)", + cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], + req, value, index); #endif } else { i = usb_control_msg( @@ -1460,9 +1449,10 @@ static void ibmcam_adjust_contrast(struct uvd *uvd) */ static void ibmcam_change_lighting_conditions(struct uvd *uvd) { + static const char proc[] = "ibmcam_change_lighting_conditions"; + if (debug > 0) - dev_info(&uvd->dev->dev, - "%s: Set lighting to %hu.\n", __func__, lighting); + info("%s: Set lighting to %hu.", proc, lighting); switch (IBMCAM_T(uvd)->camera_model) { case IBMCAM_MODEL_1: @@ -1505,6 +1495,8 @@ static void ibmcam_change_lighting_conditions(struct uvd *uvd) */ static void ibmcam_set_sharpness(struct uvd *uvd) { + static const char proc[] = "ibmcam_set_sharpness"; + switch (IBMCAM_T(uvd)->camera_model) { case IBMCAM_MODEL_1: { @@ -1513,8 +1505,7 @@ static void ibmcam_set_sharpness(struct uvd *uvd) RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX); if (debug > 0) - dev_info(&uvd->dev->dev, "%s: Set sharpness to %hu.\n", - __func__, sharpness); + info("%s: Set sharpness to %hu.", proc, sharpness); sv = sa[sharpness - SHARPNESS_MIN]; for (i=0; i < 2; i++) { @@ -1573,11 +1564,11 @@ static void ibmcam_set_sharpness(struct uvd *uvd) */ static void ibmcam_set_brightness(struct uvd *uvd) { + static const char proc[] = "ibmcam_set_brightness"; static const unsigned short n = 1; if (debug > 0) - dev_info(&uvd->dev->dev, "%s: Set brightness to %hu.\n", - __func__, uvd->vpic.brightness); + info("%s: Set brightness to %hu.", proc, uvd->vpic.brightness); switch (IBMCAM_T(uvd)->camera_model) { case IBMCAM_MODEL_1: @@ -2124,8 +2115,7 @@ static void ibmcam_model2_setup_after_video_if(struct uvd *uvd) break; } if (uvd->debug > 0) - dev_info(&uvd->dev->dev, "Framerate (hardware): %hd.\n", - hw_fps); + info("Framerate (hardware): %hd.", hw_fps); RESTRICT_TO_RANGE(hw_fps, 0, 31); ibmcam_model2_Packet1(uvd, mod2_set_framerate, hw_fps); } @@ -3497,7 +3487,7 @@ static void ibmcam_model3_setup_after_video_if(struct uvd *uvd) /* 01.01.08 - Added for RCA video in support -LO */ if(init_model3_input) { if (debug > 0) - dev_info(&uvd->dev->dev, "Setting input to RCA.\n"); + info("Setting input to RCA."); for (i=0; i < ARRAY_SIZE(initData); i++) { ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); } @@ -3695,7 +3685,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * unsigned char video_ep = 0; if (debug >= 1) - dev_info(&uvd->dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); + info("ibmcam_probe(%p,%u.)", intf, ifnum); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) @@ -3746,16 +3736,14 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ break; } - dev_info(&uvd->dev->dev, - "%s USB camera found (model %d, rev. 0x%04x)\n", - brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); + info("%s USB camera found (model %d, rev. 0x%04x)", + brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); } while (0); /* Validate found interface: must have one ISO endpoint */ nas = intf->num_altsetting; if (debug > 0) - dev_info(&uvd->dev->dev, "Number of alternate settings=%d.\n", - nas); + info("Number of alternate settings=%d.", nas); if (nas < 2) { err("Too few alternate settings for this camera!"); return -ENODEV; @@ -3799,9 +3787,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * actInterface = i; maxPS = le16_to_cpu(endpoint->wMaxPacketSize); if (debug > 0) - dev_info(&uvd->dev->dev, - "Active setting=%d. " - "maxPS=%d.\n", i, maxPS); + info("Active setting=%d. maxPS=%d.", i, maxPS); } else err("More than one active alt. setting! Ignoring #%d.", i); } @@ -3840,7 +3826,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * RESTRICT_TO_RANGE(framerate, 0, 5); break; default: - dev_info(&uvd->dev->dev, "IBM camera: using 320x240\n"); + info("IBM camera: using 320x240"); size = SIZE_320x240; /* No break here */ case SIZE_320x240: @@ -3869,7 +3855,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * canvasY = 120; break; default: - dev_info(&uvd->dev->dev, "IBM NetCamera: using 176x144\n"); + info("IBM NetCamera: using 176x144"); size = SIZE_176x144; /* No break here */ case SIZE_176x144: diff --git a/trunk/drivers/media/video/usbvideo/konicawc.c b/trunk/drivers/media/video/usbvideo/konicawc.c index e986c28b7bb0..1c180284ec6c 100644 --- a/trunk/drivers/media/video/usbvideo/konicawc.c +++ b/trunk/drivers/media/video/usbvideo/konicawc.c @@ -337,8 +337,7 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur } if((sts > 0x01) && (sts < 0x80)) { - dev_info(&uvd->dev->dev, "unknown status %2.2x\n", - sts); + info("unknown status %2.2x", sts); bad++; continue; } @@ -569,12 +568,8 @@ static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) fdrops = (0x80 + curframe - cam->lastframe) & 0x7F; fdrops--; if(fdrops) { - dev_info(&uvd->dev->dev, - "Dropped %d frames " - "(%d -> %d)\n", - fdrops, - cam->lastframe, - curframe); + info("Dropped %d frames (%d -> %d)", fdrops, + cam->lastframe, curframe); } } cam->lastframe = curframe; @@ -789,8 +784,7 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id if (dev->descriptor.bNumConfigurations != 1) return -ENODEV; - dev_info(&intf->dev, "Konica Webcam (rev. 0x%04x)\n", - le16_to_cpu(dev->descriptor.bcdDevice)); + info("Konica Webcam (rev. 0x%04x)", le16_to_cpu(dev->descriptor.bcdDevice)); RESTRICT_TO_RANGE(speed, 0, MAX_SPEED); /* Validate found interface: must have one ISO endpoint */ @@ -931,8 +925,7 @@ static struct usb_device_id id_table[] = { static int __init konicawc_init(void) { struct usbvideo_cb cbTbl; - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_DESC " " DRIVER_VERSION); memset(&cbTbl, 0, sizeof(cbTbl)); cbTbl.probe = konicawc_probe; cbTbl.setupOnOpen = konicawc_setup_on_open; diff --git a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c index 05c61b523115..3d26a30abe1e 100644 --- a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c @@ -1080,8 +1080,7 @@ static struct usbvideo_cb qcm_driver = { static int __init qcm_init(void) { - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + info(DRIVER_DESC " " DRIVER_VERSION); return usbvideo_register( &cams, diff --git a/trunk/drivers/media/video/usbvideo/ultracam.c b/trunk/drivers/media/video/usbvideo/ultracam.c index 9714baab7833..9544e644bf0d 100644 --- a/trunk/drivers/media/video/usbvideo/ultracam.c +++ b/trunk/drivers/media/video/usbvideo/ultracam.c @@ -156,11 +156,10 @@ static int ultracam_veio( sizeof(cp), 1000); #if 1 - dev_info(&uvd->dev->dev, - "USB => %02x%02x%02x%02x%02x%02x%02x%02x " - "(req=$%02x val=$%04x ind=$%04x)\n", - cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], - req, value, index); + info("USB => %02x%02x%02x%02x%02x%02x%02x%02x " + "(req=$%02x val=$%04x ind=$%04x)", + cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], + req, value, index); #endif } else { i = usb_control_msg( @@ -518,20 +517,19 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id unsigned char video_ep = 0; if (debug >= 1) - dev_info(&intf->dev, "ultracam_probe\n"); + info("ultracam_probe(%p)", intf); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) return -ENODEV; - dev_info(&intf->dev, "IBM Ultra camera found (rev. 0x%04x)\n", - le16_to_cpu(dev->descriptor.bcdDevice)); + info("IBM Ultra camera found (rev. 0x%04x)", + le16_to_cpu(dev->descriptor.bcdDevice)); /* Validate found interface: must have one ISO endpoint */ nas = intf->num_altsetting; if (debug > 0) - dev_info(&intf->dev, "Number of alternate settings=%d.\n", - nas); + info("Number of alternate settings=%d.", nas); if (nas < 8) { err("Too few alternate settings for this camera!"); return -ENODEV; @@ -578,9 +576,7 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id actInterface = i; maxPS = le16_to_cpu(endpoint->wMaxPacketSize); if (debug > 0) - dev_info(&intf->dev, - "Active setting=%d. " - "maxPS=%d.\n", i, maxPS); + info("Active setting=%d. maxPS=%d.", i, maxPS); } else { /* Got another active alt. setting */ if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) { @@ -588,11 +584,8 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id actInterface = i; maxPS = le16_to_cpu(endpoint->wMaxPacketSize); if (debug > 0) { - dev_info(&intf->dev, - "Even better ctive " - "setting=%d. " - "maxPS=%d.\n", - i, maxPS); + info("Even better ctive setting=%d. maxPS=%d.", + i, maxPS); } } } diff --git a/trunk/drivers/media/video/usbvideo/usbvideo.c b/trunk/drivers/media/video/usbvideo/usbvideo.c index 07cd87d16f69..bf1bc2f69b02 100644 --- a/trunk/drivers/media/video/usbvideo/usbvideo.c +++ b/trunk/drivers/media/video/usbvideo/usbvideo.c @@ -468,9 +468,8 @@ static void usbvideo_ReportStatistics(const struct uvd *uvd) percent = (100 * goodPackets) / allPackets; else percent = goodPackets / (allPackets / 100); - dev_info(&uvd->dev->dev, - "Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%\n", - allPackets, badPackets, percent); + info("Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%", + allPackets, badPackets, percent); if (uvd->iso_packet_len > 0) { unsigned long allBytes, xferBytes; char multiplier = ' '; @@ -498,9 +497,8 @@ static void usbvideo_ReportStatistics(const struct uvd *uvd) } } } - dev_info(&uvd->dev->dev, - "Transfer Statistics: Transferred=%lu%cB Usage=%lu%%\n", - xferBytes, multiplier, percent); + info("Transfer Statistics: Transferred=%lu%cB Usage=%lu%%", + xferBytes, multiplier, percent); } } } @@ -547,7 +545,7 @@ void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) { /* For debugging purposes only */ char tmp[20]; usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request); - dev_info(&uvd->dev->dev, "testpattern: frame=%s\n", tmp); + info("testpattern: frame=%s", tmp); } #endif /* Form every scan line */ @@ -856,7 +854,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) usbvideo_ClientIncModCount(uvd); if (uvd->debug > 0) - dev_info(&intf->dev, "%s(%p.)\n", __func__, intf); + info("%s(%p.)", __func__, intf); mutex_lock(&uvd->lock); uvd->remove_pending = 1; /* Now all ISO data will be ignored */ @@ -872,15 +870,14 @@ static void usbvideo_Disconnect(struct usb_interface *intf) video_unregister_device(&uvd->vdev); if (uvd->debug > 0) - dev_info(&intf->dev, "%s: Video unregistered.\n", __func__); + info("%s: Video unregistered.", __func__); if (uvd->user) - dev_info(&intf->dev, "%s: In use, disconnect pending.\n", - __func__); + info("%s: In use, disconnect pending.", __func__); else usbvideo_CameraRelease(uvd); mutex_unlock(&uvd->lock); - dev_info(&intf->dev, "USB camera disconnected.\n"); + info("USB camera disconnected."); usbvideo_ClientDecModCount(uvd); } @@ -1018,17 +1015,14 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) return -EINVAL; } if (uvd->video_endp == 0) { - dev_info(&uvd->dev->dev, - "%s: No video endpoint specified; data pump disabled.\n", - __func__); + info("%s: No video endpoint specified; data pump disabled.", __func__); } if (uvd->paletteBits == 0) { err("%s: No palettes specified!", __func__); return -EINVAL; } if (uvd->defaultPalette == 0) { - dev_info(&uvd->dev->dev, "%s: No default palette!\n", - __func__); + info("%s: No default palette!", __func__); } uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) * @@ -1037,29 +1031,25 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas); if (uvd->debug > 0) { - dev_info(&uvd->dev->dev, - "%s: iface=%d. endpoint=$%02x paletteBits=$%08lx\n", - __func__, uvd->iface, uvd->video_endp, - uvd->paletteBits); + info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx", + __func__, uvd->iface, uvd->video_endp, uvd->paletteBits); } if (uvd->dev == NULL) { err("%s: uvd->dev == NULL", __func__); return -EINVAL; } uvd->vdev.parent = &uvd->dev->dev; - uvd->vdev.release = video_device_release_empty; - if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { + if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { err("%s: video_register_device failed", __func__); return -EPIPE; } if (uvd->debug > 1) { - dev_info(&uvd->dev->dev, - "%s: video_register_device() successful\n", __func__); + info("%s: video_register_device() successful", __func__); } - dev_info(&uvd->dev->dev, "%s on /dev/video%d: canvas=%s videosize=%s\n", - (uvd->handle != NULL) ? uvd->handle->drvName : "???", - uvd->vdev.minor, tmp2, tmp1); + info("%s on /dev/video%d: canvas=%s videosize=%s", + (uvd->handle != NULL) ? uvd->handle->drvName : "???", + uvd->vdev.minor, tmp2, tmp1); usb_get_dev(uvd->dev); return 0; @@ -1121,7 +1111,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) int i, errCode = 0; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev); + info("%s($%p)", __func__, dev); if (0 < usbvideo_ClientIncModCount(uvd)) return -ENODEV; @@ -1188,25 +1178,19 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) if (errCode == 0) { if (VALID_CALLBACK(uvd, setupOnOpen)) { if (uvd->debug > 1) - dev_info(&uvd->dev->dev, - "%s: setupOnOpen callback\n", - __func__); + info("%s: setupOnOpen callback", __func__); errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd); if (errCode < 0) { err("%s: setupOnOpen callback failed (%d.).", __func__, errCode); } else if (uvd->debug > 1) { - dev_info(&uvd->dev->dev, - "%s: setupOnOpen callback successful\n", - __func__); + info("%s: setupOnOpen callback successful", __func__); } } if (errCode == 0) { uvd->settingsAdjusted = 0; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, - "%s: Open succeeded.\n", - __func__); + info("%s: Open succeeded.", __func__); uvd->user++; file->private_data = uvd; } @@ -1216,8 +1200,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) if (errCode != 0) usbvideo_ClientDecModCount(uvd); if (uvd->debug > 0) - dev_info(&uvd->dev->dev, "%s: Returning %d.\n", __func__, - errCode); + info("%s: Returning %d.", __func__, errCode); return errCode; } @@ -1240,7 +1223,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) int i; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev); + info("%s($%p)", __func__, dev); mutex_lock(&uvd->lock); GET_CALLBACK(uvd, stopDataPump)(uvd); @@ -1260,15 +1243,14 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) uvd->user--; if (uvd->remove_pending) { if (uvd->debug > 0) - dev_info(&uvd->dev->dev, "%s: Final disconnect.\n", - __func__); + info("usbvideo_v4l_close: Final disconnect."); usbvideo_CameraRelease(uvd); } mutex_unlock(&uvd->lock); usbvideo_ClientDecModCount(uvd); if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "%s: Completed.\n", __func__); + info("%s: Completed.", __func__); file->private_data = NULL; return 0; } @@ -1382,9 +1364,8 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, struct video_mmap *vm = arg; if (uvd->debug >= 1) { - dev_info(&uvd->dev->dev, - "VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.\n", - vm->frame, vm->width, vm->height, vm->format); + info("VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.", + vm->frame, vm->width, vm->height, vm->format); } /* * Check if the requested size is supported. If the requestor @@ -1402,24 +1383,18 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, if ((vm->width > VIDEOSIZE_X(uvd->canvas)) || (vm->height > VIDEOSIZE_Y(uvd->canvas))) { if (uvd->debug > 0) { - dev_info(&uvd->dev->dev, - "VIDIOCMCAPTURE: Size=%dx%d " - "too large; allowed only up " - "to %ldx%ld\n", vm->width, - vm->height, - VIDEOSIZE_X(uvd->canvas), - VIDEOSIZE_Y(uvd->canvas)); + info("VIDIOCMCAPTURE: Size=%dx%d too large; " + "allowed only up to %ldx%ld", vm->width, vm->height, + VIDEOSIZE_X(uvd->canvas), VIDEOSIZE_Y(uvd->canvas)); } return -EINVAL; } /* Check if the palette is supported */ if (((1L << vm->format) & uvd->paletteBits) == 0) { if (uvd->debug > 0) { - dev_info(&uvd->dev->dev, - "VIDIOCMCAPTURE: format=%d. " - "not supported " - "(paletteBits=$%08lx)\n", - vm->format, uvd->paletteBits); + info("VIDIOCMCAPTURE: format=%d. not supported" + " (paletteBits=$%08lx)", + vm->format, uvd->paletteBits); } return -EINVAL; } @@ -1447,9 +1422,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (uvd->debug >= 1) - dev_info(&uvd->dev->dev, - "VIDIOCSYNC: syncing to frame %d.\n", - *frameNum); + info("VIDIOCSYNC: syncing to frame %d.", *frameNum); if (uvd->flags & FLAGS_NO_DECODING) ret = usbvideo_GetFrame(uvd, *frameNum); else if (VALID_CALLBACK(uvd, getFrame)) { @@ -1531,9 +1504,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, return -EFAULT; if (uvd->debug >= 1) - dev_info(&uvd->dev->dev, - "%s: %Zd. bytes, noblock=%d.\n", - __func__, count, noblock); + info("%s: %Zd. bytes, noblock=%d.", __func__, count, noblock); mutex_lock(&uvd->lock); @@ -1714,21 +1685,18 @@ static void usbvideo_IsocIrq(struct urb *urb) return; #if 0 if (urb->actual_length > 0) { - dev_info(&uvd->dev->dev, - "urb=$%p status=%d. errcount=%d. length=%d.\n", - urb, urb->status, urb->error_count, - urb->actual_length); + info("urb=$%p status=%d. errcount=%d. length=%d.", + urb, urb->status, urb->error_count, urb->actual_length); } else { static int c = 0; if (c++ % 100 == 0) - dev_info(&uvd->dev->dev, "No Isoc data\n"); + info("No Isoc data"); } #endif if (!uvd->streaming) { if (uvd->debug >= 1) - dev_info(&uvd->dev->dev, - "Not streaming, but interrupt!\n"); + info("Not streaming, but interrupt!"); return; } @@ -1773,7 +1741,7 @@ static int usbvideo_StartDataPump(struct uvd *uvd) int i, errFlag; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd); + info("%s($%p)", __func__, uvd); if (!CAMERA_IS_OPERATIONAL(uvd)) { err("%s: Camera is not operational", __func__); @@ -1821,9 +1789,7 @@ static int usbvideo_StartDataPump(struct uvd *uvd) uvd->streaming = 1; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, - "%s: streaming=1 video_endp=$%02x\n", __func__, - uvd->video_endp); + info("%s: streaming=1 video_endp=$%02x", __func__, uvd->video_endp); return 0; } @@ -1845,14 +1811,14 @@ static void usbvideo_StopDataPump(struct uvd *uvd) return; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd); + info("%s($%p)", __func__, uvd); /* Unschedule all of the iso td's */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { usb_kill_urb(uvd->sbuf[i].urb); } if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "%s: streaming=0\n", __func__); + info("%s: streaming=0", __func__); uvd->streaming = 0; if (!uvd->remove_pending) { @@ -1884,8 +1850,7 @@ static int usbvideo_NewFrame(struct uvd *uvd, int framenum) int n; if (uvd->debug > 1) - dev_info(&uvd->dev->dev, "usbvideo_NewFrame($%p,%d.)\n", uvd, - framenum); + info("usbvideo_NewFrame($%p,%d.)", uvd, framenum); /* If we're not grabbing a frame right now and the other frame is */ /* ready to be grabbed into, then use it instead */ @@ -1990,14 +1955,12 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) struct usbvideo_frame *frame = &uvd->frame[frameNum]; if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, "%s($%p,%d.)\n", __func__, uvd, - frameNum); + info("%s($%p,%d.)", __func__, uvd, frameNum); switch (frame->frameState) { case FrameState_Unused: if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, "%s: FrameState_Unused\n", - __func__); + info("%s: FrameState_Unused", __func__); return -EINVAL; case FrameState_Ready: case FrameState_Grabbing: @@ -2007,9 +1970,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) redo: if (!CAMERA_IS_OPERATIONAL(uvd)) { if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: Camera is not operational (1)\n", - __func__); + info("%s: Camera is not operational (1)", __func__); return -EIO; } ntries = 0; @@ -2018,33 +1979,24 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) signalPending = signal_pending(current); if (!CAMERA_IS_OPERATIONAL(uvd)) { if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: Camera is not " - "operational (2)\n", __func__); + info("%s: Camera is not operational (2)", __func__); return -EIO; } assert(uvd->fbuf != NULL); if (signalPending) { if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: Signal=$%08x\n", __func__, - signalPending); + info("%s: Signal=$%08x", __func__, signalPending); if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) { usbvideo_TestPattern(uvd, 1, 0); uvd->curframe = -1; uvd->stats.frame_num++; if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: Forced test " - "pattern screen\n", - __func__); + info("%s: Forced test pattern screen", __func__); return 0; } else { /* Standard answer: Interrupted! */ if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: Interrupted!\n", - __func__); + info("%s: Interrupted!", __func__); return -EINTR; } } else { @@ -2058,10 +2010,8 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) } } while (frame->frameState == FrameState_Grabbing); if (uvd->debug >= 2) { - dev_info(&uvd->dev->dev, - "%s: Grabbing done; state=%d. (%lu. bytes)\n", - __func__, frame->frameState, - frame->seqRead_Length); + info("%s: Grabbing done; state=%d. (%lu. bytes)", + __func__, frame->frameState, frame->seqRead_Length); } if (frame->frameState == FrameState_Error) { int ret = usbvideo_NewFrame(uvd, frameNum); @@ -2098,9 +2048,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) } frame->frameState = FrameState_Done_Hold; if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: Entered FrameState_Done_Hold state.\n", - __func__); + info("%s: Entered FrameState_Done_Hold state.", __func__); return 0; case FrameState_Done_Hold: @@ -2111,9 +2059,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) * it will be released back into the wild to roam freely. */ if (uvd->debug >= 2) - dev_info(&uvd->dev->dev, - "%s: FrameState_Done_Hold state.\n", - __func__); + info("%s: FrameState_Done_Hold state.", __func__); return 0; } diff --git a/trunk/drivers/media/video/usbvideo/vicam.c b/trunk/drivers/media/video/usbvideo/vicam.c index 7a127d6bfdee..2eb45829791c 100644 --- a/trunk/drivers/media/video/usbvideo/vicam.c +++ b/trunk/drivers/media/video/usbvideo/vicam.c @@ -472,8 +472,9 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign static int vicam_open(struct inode *inode, struct file *file) { - struct vicam_camera *cam = video_drvdata(file); - + struct video_device *dev = video_devdata(file); + struct vicam_camera *cam = + (struct vicam_camera *) dev->priv; DBG("open\n"); if (!cam) { @@ -487,24 +488,20 @@ vicam_open(struct inode *inode, struct file *file) * rely on this fact forever. */ - lock_kernel(); if (cam->open_count > 0) { printk(KERN_INFO "vicam_open called on already opened camera"); - unlock_kernel(); return -EBUSY; } cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); if (!cam->raw_image) { - unlock_kernel(); return -ENOMEM; } cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); if (!cam->framebuf) { kfree(cam->raw_image); - unlock_kernel(); return -ENOMEM; } @@ -512,7 +509,6 @@ vicam_open(struct inode *inode, struct file *file) if (!cam->cntrlbuf) { kfree(cam->raw_image); rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); - unlock_kernel(); return -ENOMEM; } @@ -530,7 +526,6 @@ vicam_open(struct inode *inode, struct file *file) cam->open_count++; file->private_data = cam; - unlock_kernel(); return 0; } @@ -800,7 +795,6 @@ static struct video_device vicam_template = { .name = "ViCam-based USB Camera", .fops = &vicam_fops, .minor = -1, - .release = video_device_release_empty, }; /* table of devices that work with this driver */ @@ -865,8 +859,9 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) mutex_init(&cam->cam_lock); - memcpy(&cam->vdev, &vicam_template, sizeof(vicam_template)); - video_set_drvdata(&cam->vdev, cam); + memcpy(&cam->vdev, &vicam_template, + sizeof (vicam_template)); + cam->vdev.priv = cam; // sort of a reverse mapping for those functions that get vdev only cam->udev = dev; cam->bulkEndpoint = bulkEndpoint; diff --git a/trunk/drivers/media/video/usbvision/usbvision-core.c b/trunk/drivers/media/video/usbvision/usbvision-core.c index 9e4f50639975..c317ed7a8482 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-core.c +++ b/trunk/drivers/media/video/usbvision/usbvision-core.c @@ -45,6 +45,10 @@ #include +#ifdef CONFIG_KMOD +#include +#endif + #include "usbvision.h" static unsigned int core_debug; @@ -80,8 +84,7 @@ MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]"); #ifdef USBVISION_DEBUG #define PDEBUG(level, fmt, args...) { \ if (core_debug & (level)) \ - printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \ - __func__, __LINE__ , ## args); \ + info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ } #else #define PDEBUG(level, fmt, args...) do {} while(0) diff --git a/trunk/drivers/media/video/usbvision/usbvision-i2c.c b/trunk/drivers/media/video/usbvision/usbvision-i2c.c index 92427fdc1459..a6d00858b07e 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-i2c.c +++ b/trunk/drivers/media/video/usbvision/usbvision-i2c.c @@ -47,8 +47,7 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); #define PDEBUG(level, fmt, args...) { \ if (i2c_debug & (level)) \ - printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \ - __func__, __LINE__ , ## args); \ + info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ } static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c index 77aeb39b2750..b977116a0dd9 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-video.c +++ b/trunk/drivers/media/video/usbvision/usbvision-video.c @@ -69,6 +69,10 @@ #include +#ifdef CONFIG_KMOD +#include +#endif + #include "usbvision.h" #include "usbvision-cards.h" @@ -94,8 +98,7 @@ USBVISION_DRIVER_VERSION_PATCHLEVEL) #ifdef USBVISION_DEBUG #define PDEBUG(level, fmt, args...) { \ if (video_debug & (level)) \ - printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \ - __func__, __LINE__ , ## args); \ + info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ } #else #define PDEBUG(level, fmt, args...) do {} while(0) @@ -357,12 +360,13 @@ static void usbvision_remove_sysfs(struct video_device *vdev) */ static int usbvision_v4l2_open(struct inode *inode, struct file *file) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int errCode = 0; PDEBUG(DBG_IO, "open"); - lock_kernel(); usbvision_reset_powerOffTimer(usbvision); if (usbvision->user) @@ -420,7 +424,6 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) usbvision_empty_framequeues(usbvision); PDEBUG(DBG_IO, "success"); - unlock_kernel(); return errCode; } @@ -434,7 +437,9 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) */ static int usbvision_v4l2_close(struct inode *inode, struct file *file) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); PDEBUG(DBG_IO, "close"); mutex_lock(&usbvision->lock); @@ -479,7 +484,9 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) static int vidioc_g_register (struct file *file, void *priv, struct v4l2_register *reg) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int errCode; if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) @@ -498,7 +505,9 @@ static int vidioc_g_register (struct file *file, void *priv, static int vidioc_s_register (struct file *file, void *priv, struct v4l2_register *reg) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int errCode; if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) @@ -517,7 +526,9 @@ static int vidioc_s_register (struct file *file, void *priv, static int vidioc_querycap (struct file *file, void *priv, struct v4l2_capability *vc) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); strlcpy(vc->driver, "USBVision", sizeof(vc->driver)); strlcpy(vc->card, @@ -537,7 +548,9 @@ static int vidioc_querycap (struct file *file, void *priv, static int vidioc_enum_input (struct file *file, void *priv, struct v4l2_input *vi) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int chan; if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) ) @@ -590,7 +603,9 @@ static int vidioc_enum_input (struct file *file, void *priv, static int vidioc_g_input (struct file *file, void *priv, unsigned int *input) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); *input = usbvision->ctl_input; return 0; @@ -598,7 +613,9 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *input) static int vidioc_s_input (struct file *file, void *priv, unsigned int input) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); if ((input >= usbvision->video_inputs) || (input < 0) ) return -EINVAL; @@ -615,8 +632,9 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int input) static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) { - struct usb_usbvision *usbvision = video_drvdata(file); - + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); usbvision->tvnormId=*id; mutex_lock(&usbvision->lock); @@ -632,7 +650,9 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *vt) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); if (!usbvision->have_tuner || vt->index) // Only tuner 0 return -EINVAL; @@ -651,7 +671,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, static int vidioc_s_tuner (struct file *file, void *priv, struct v4l2_tuner *vt) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); // Only no or one tuner for now if (!usbvision->have_tuner || vt->index) @@ -665,7 +687,9 @@ static int vidioc_s_tuner (struct file *file, void *priv, static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *freq) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); freq->tuner = 0; // Only one tuner if(usbvision->radio) { @@ -681,7 +705,9 @@ static int vidioc_g_frequency (struct file *file, void *priv, static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *freq) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); // Only no or one tuner for now if (!usbvision->have_tuner || freq->tuner) @@ -695,7 +721,9 @@ static int vidioc_s_frequency (struct file *file, void *priv, static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); memset(a,0,sizeof(*a)); if(usbvision->radio) { @@ -720,7 +748,9 @@ static int vidioc_s_audio (struct file *file, void *fh, static int vidioc_queryctrl (struct file *file, void *priv, struct v4l2_queryctrl *ctrl) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int id=ctrl->id; memset(ctrl,0,sizeof(*ctrl)); @@ -737,7 +767,9 @@ static int vidioc_queryctrl (struct file *file, void *priv, static int vidioc_g_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); return 0; @@ -746,7 +778,9 @@ static int vidioc_g_ctrl (struct file *file, void *priv, static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl); return 0; @@ -755,7 +789,9 @@ static int vidioc_s_ctrl (struct file *file, void *priv, static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *vr) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int ret; RESTRICT_TO_RANGE(vr->count,1,USBVISION_NUMFRAMES); @@ -783,7 +819,9 @@ static int vidioc_reqbufs (struct file *file, static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *vb) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); struct usbvision_frame *frame; /* FIXME : must control @@ -819,7 +857,9 @@ static int vidioc_querybuf (struct file *file, static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); struct usbvision_frame *frame; unsigned long lock_flags; @@ -856,7 +896,9 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb) static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int ret; struct usbvision_frame *f; unsigned long lock_flags; @@ -897,7 +939,9 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; usbvision->streaming = Stream_On; @@ -909,7 +953,9 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -942,7 +988,9 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *vf) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); vf->fmt.pix.width = usbvision->curwidth; vf->fmt.pix.height = usbvision->curheight; vf->fmt.pix.pixelformat = usbvision->palette.format; @@ -958,7 +1006,9 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *vf) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int formatIdx; /* Find requested format in available ones */ @@ -986,7 +1036,9 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int ret; if( 0 != (ret=vidioc_try_fmt_vid_cap (file, priv, vf)) ) { @@ -1014,7 +1066,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int noblock = file->f_flags & O_NONBLOCK; unsigned long lock_flags; @@ -1123,7 +1177,10 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) start = vma->vm_start; void *pos; u32 i; - struct usb_usbvision *usbvision = video_drvdata(file); + + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); PDEBUG(DBG_MMAP, "mmap"); @@ -1180,7 +1237,9 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) */ static int usbvision_radio_open(struct inode *inode, struct file *file) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int errCode = 0; PDEBUG(DBG_IO, "%s:", __func__); @@ -1230,7 +1289,9 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) static int usbvision_radio_close(struct inode *inode, struct file *file) { - struct usb_usbvision *usbvision = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct usb_usbvision *usbvision = + (struct usb_usbvision *) video_get_drvdata(dev); int errCode = 0; PDEBUG(DBG_IO, ""); diff --git a/trunk/drivers/media/video/uvc/uvc_ctrl.c b/trunk/drivers/media/video/uvc/uvc_ctrl.c index f16aafe9cf14..feab12aa2c7b 100644 --- a/trunk/drivers/media/video/uvc/uvc_ctrl.c +++ b/trunk/drivers/media/video/uvc/uvc_ctrl.c @@ -81,22 +81,6 @@ static struct uvc_control_info uvc_ctrls[] = { .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE | UVC_CONTROL_RESTORE, }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, - .index = 6, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, - .index = 7, - .size = 4, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, { .entity = UVC_GUID_UVC_PROCESSING, .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, @@ -129,60 +113,6 @@ static struct uvc_control_info uvc_ctrls[] = { .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, - .index = 12, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, - .index = 13, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_DIGITAL_MULTIPLIER_CONTROL, - .index = 14, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, - .index = 15, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_ANALOG_VIDEO_STANDARD_CONTROL, - .index = 16, - .size = 1, - .flags = UVC_CONTROL_GET_CUR, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_ANALOG_LOCK_STATUS_CONTROL, - .index = 17, - .size = 1, - .flags = UVC_CONTROL_GET_CUR, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_SCANNING_MODE_CONTROL, - .index = 0, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_RESTORE, - }, { .entity = UVC_GUID_UVC_CAMERA, .selector = CT_AE_MODE_CONTROL, @@ -208,14 +138,6 @@ static struct uvc_control_info uvc_ctrls[] = { .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE | UVC_CONTROL_RESTORE, }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_EXPOSURE_TIME_RELATIVE_CONTROL, - .index = 4, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_RESTORE, - }, { .entity = UVC_GUID_UVC_CAMERA, .selector = CT_FOCUS_ABSOLUTE_CONTROL, @@ -226,90 +148,42 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_RELATIVE_CONTROL, - .index = 6, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_IRIS_ABSOLUTE_CONTROL, - .index = 7, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_IRIS_RELATIVE_CONTROL, - .index = 8, + .selector = CT_FOCUS_AUTO_CONTROL, + .index = 17, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ZOOM_ABSOLUTE_CONTROL, - .index = 9, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ZOOM_RELATIVE_CONTROL, - .index = 10, - .size = 3, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PANTILT_ABSOLUTE_CONTROL, - .index = 11, - .size = 8, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, + | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, }, { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PANTILT_RELATIVE_CONTROL, + .entity = UVC_GUID_UVC_PROCESSING, + .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, .index = 12, - .size = 4, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_AUTO_UPDATE, + .size = 1, + .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR + | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, }, { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ROLL_ABSOLUTE_CONTROL, - .index = 13, + .entity = UVC_GUID_UVC_PROCESSING, + .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, + .index = 6, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, }, { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ROLL_RELATIVE_CONTROL, - .index = 14, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_AUTO_CONTROL, - .index = 17, + .entity = UVC_GUID_UVC_PROCESSING, + .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, + .index = 13, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, }, { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PRIVACY_CONTROL, - .index = 18, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR + .entity = UVC_GUID_UVC_PROCESSING, + .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, + .index = 7, + .size = 4, + .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, }, }; @@ -837,17 +711,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, for (i = 0; i < entity->ncontrols; ++i) { ctrl = &entity->controls[i]; - if (ctrl->info == NULL) - continue; - - /* Reset the loaded flag for auto-update controls that were - * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent - * uvc_ctrl_get from using the cached value. - */ - if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) - ctrl->loaded = 0; - - if (!ctrl->dirty) + if (ctrl->info == NULL || !ctrl->dirty) continue; if (!rollback) @@ -863,6 +727,9 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), ctrl->info->size); + if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) + ctrl->loaded = 0; + ctrl->dirty = 0; if (ret < 0) @@ -920,7 +787,8 @@ int uvc_ctrl_get(struct uvc_video_device *video, if (ret < 0) return ret; - ctrl->loaded = 1; + if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0) + ctrl->loaded = 1; } xctrl->value = uvc_get_le_value( @@ -971,7 +839,8 @@ int uvc_ctrl_set(struct uvc_video_device *video, return ret; } - ctrl->loaded = 1; + if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0) + ctrl->loaded = 1; } if (!ctrl->dirty) { diff --git a/trunk/drivers/media/video/uvc/uvc_driver.c b/trunk/drivers/media/video/uvc/uvc_driver.c index d7ad060640bc..7e102034d38d 100644 --- a/trunk/drivers/media/video/uvc/uvc_driver.c +++ b/trunk/drivers/media/video/uvc/uvc_driver.c @@ -1663,7 +1663,7 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message) return uvc_video_suspend(&dev->video); } -static int __uvc_resume(struct usb_interface *intf, int reset) +static int uvc_resume(struct usb_interface *intf) { struct uvc_device *dev = usb_get_intfdata(intf); int ret; @@ -1672,7 +1672,7 @@ static int __uvc_resume(struct usb_interface *intf, int reset) intf->cur_altsetting->desc.bInterfaceNumber); if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) { - if (reset && (ret = uvc_ctrl_resume_device(dev)) < 0) + if ((ret = uvc_ctrl_resume_device(dev)) < 0) return ret; return uvc_status_resume(dev); @@ -1687,16 +1687,6 @@ static int __uvc_resume(struct usb_interface *intf, int reset) return uvc_video_resume(&dev->video); } -static int uvc_resume(struct usb_interface *intf) -{ - return __uvc_resume(intf, 0); -} - -static int uvc_reset_resume(struct usb_interface *intf) -{ - return __uvc_resume(intf, 1); -} - /* ------------------------------------------------------------------------ * Driver initialization and cleanup */ @@ -1912,24 +1902,6 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Compaq Presario B1200 - Bison Electronics */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0104, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Acer Travelmate 7720 - Bison Electronics */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0105, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Medion Akoya Mini E1210 - Bison Electronics */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1948,24 +1920,6 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Fujitsu Amilo SI2636 - Bison Electronics */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0202, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Advent 4211 - Bison Electronics */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0203, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Bison Electronics */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1998,7 +1952,6 @@ struct uvc_driver uvc_driver = { .disconnect = uvc_disconnect, .suspend = uvc_suspend, .resume = uvc_resume, - .reset_resume = uvc_reset_resume, .id_table = uvc_ids, .supports_autosuspend = 1, }, diff --git a/trunk/drivers/media/video/uvc/uvc_status.c b/trunk/drivers/media/video/uvc/uvc_status.c index 5d60b264d59a..75e678ac54eb 100644 --- a/trunk/drivers/media/video/uvc/uvc_status.c +++ b/trunk/drivers/media/video/uvc/uvc_status.c @@ -177,15 +177,9 @@ int uvc_status_init(struct uvc_device *dev) uvc_input_init(dev); - dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL); - if (dev->status == NULL) - return -ENOMEM; - dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); - if (dev->int_urb == NULL) { - kfree(dev->status); + if (dev->int_urb == NULL) return -ENOMEM; - } pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); @@ -198,7 +192,7 @@ int uvc_status_init(struct uvc_device *dev) interval = fls(interval) - 1; usb_fill_int_urb(dev->int_urb, dev->udev, pipe, - dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, + dev->status, sizeof dev->status, uvc_status_complete, dev, interval); return usb_submit_urb(dev->int_urb, GFP_KERNEL); @@ -208,7 +202,6 @@ void uvc_status_cleanup(struct uvc_device *dev) { usb_kill_urb(dev->int_urb); usb_free_urb(dev->int_urb); - kfree(dev->status); uvc_input_cleanup(dev); } diff --git a/trunk/drivers/media/video/uvc/uvc_v4l2.c b/trunk/drivers/media/video/uvc/uvc_v4l2.c index 78e4c4e09d89..d7bd71be40a9 100644 --- a/trunk/drivers/media/video/uvc/uvc_v4l2.c +++ b/trunk/drivers/media/video/uvc/uvc_v4l2.c @@ -400,13 +400,15 @@ static int uvc_has_privileges(struct uvc_fh *handle) static int uvc_v4l2_open(struct inode *inode, struct file *file) { + struct video_device *vdev; struct uvc_video_device *video; struct uvc_fh *handle; int ret = 0; uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); mutex_lock(&uvc_driver.open_mutex); - video = video_drvdata(file); + vdev = video_devdata(file); + video = video_get_drvdata(vdev); if (video->dev->state & UVC_DEV_DISCONNECTED) { ret = -ENODEV; @@ -438,7 +440,8 @@ static int uvc_v4l2_open(struct inode *inode, struct file *file) static int uvc_v4l2_release(struct inode *inode, struct file *file) { - struct uvc_video_device *video = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + struct uvc_video_device *video = video_get_drvdata(vdev); struct uvc_fh *handle = (struct uvc_fh *)file->private_data; uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); @@ -842,6 +845,10 @@ static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file, if (ret < 0) return ret; + if (!(video->streaming->cur_format->flags & + UVC_FMT_FLAG_COMPRESSED)) + video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; + rb->count = ret; ret = 0; break; @@ -1024,7 +1031,8 @@ static struct vm_operations_struct uvc_vm_ops = { static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) { - struct uvc_video_device *video = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + struct uvc_video_device *video = video_get_drvdata(vdev); struct uvc_buffer *uninitialized_var(buffer); struct page *page; unsigned long addr, start, size; @@ -1077,7 +1085,8 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) { - struct uvc_video_device *video = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + struct uvc_video_device *video = video_get_drvdata(vdev); uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n"); diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c index b7bb23820d80..6854ac78a161 100644 --- a/trunk/drivers/media/video/uvc/uvc_video.c +++ b/trunk/drivers/media/video/uvc/uvc_video.c @@ -455,8 +455,7 @@ static void uvc_video_decode_isoc(struct urb *urb, urb->iso_frame_desc[i].actual_length - ret); /* Process the header again. */ - uvc_video_decode_end(video, buf, mem, - urb->iso_frame_desc[i].actual_length); + uvc_video_decode_end(video, buf, mem, ret); if (buf->state == UVC_BUF_STATE_DONE || buf->state == UVC_BUF_STATE_ERROR) @@ -513,7 +512,7 @@ static void uvc_video_decode_bulk(struct urb *urb, video->bulk.payload_size >= video->bulk.max_payload_size) { if (!video->bulk.skip_payload && buf != NULL) { uvc_video_decode_end(video, buf, video->bulk.header, - video->bulk.payload_size); + video->bulk.header_size); if (buf->state == UVC_BUF_STATE_DONE || buf->state == UVC_BUF_STATE_ERROR) buf = uvc_queue_next_buffer(&video->queue, buf); @@ -656,7 +655,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, if (size > UVC_MAX_FRAME_SIZE) return -EINVAL; - npackets = DIV_ROUND_UP(size, psize); + npackets = (size + psize - 1) / psize; if (npackets > UVC_MAX_ISO_PACKETS) npackets = UVC_MAX_ISO_PACKETS; @@ -971,11 +970,6 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) return 0; } - if (video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) - video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; - else - video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; - if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) return ret; diff --git a/trunk/drivers/media/video/uvc/uvcvideo.h b/trunk/drivers/media/video/uvc/uvcvideo.h index 9a6bc1aafb16..bafe3406e305 100644 --- a/trunk/drivers/media/video/uvc/uvcvideo.h +++ b/trunk/drivers/media/video/uvc/uvcvideo.h @@ -303,8 +303,6 @@ struct uvc_xu_control { #define UVC_MAX_FRAME_SIZE (16*1024*1024) /* Maximum number of video buffers. */ #define UVC_MAX_VIDEO_BUFFERS 32 -/* Maximum status buffer size in bytes of interrupt URB. */ -#define UVC_MAX_STATUS_SIZE 16 #define UVC_CTRL_CONTROL_TIMEOUT 300 #define UVC_CTRL_STREAMING_TIMEOUT 1000 @@ -636,7 +634,7 @@ struct uvc_device { /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; - __u8 *status; + __u8 status[16]; struct input_dev *input; /* Video Streaming interfaces */ diff --git a/trunk/drivers/media/video/v4l1-compat.c b/trunk/drivers/media/video/v4l1-compat.c index 928cb4037372..79937d1031fc 100644 --- a/trunk/drivers/media/video/v4l1-compat.c +++ b/trunk/drivers/media/video/v4l1-compat.c @@ -36,6 +36,10 @@ #include #include +#ifdef CONFIG_KMOD +#include +#endif + static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages"); diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index 846763d7349e..88ca13104417 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -60,6 +60,10 @@ #include #include +#ifdef CONFIG_KMOD +#include +#endif + #include MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr"); @@ -183,11 +187,9 @@ const char **v4l2_ctrl_get_menu(u32 id) NULL }; static const char *mpeg_audio_encoding[] = { - "MPEG-1/2 Layer I", - "MPEG-1/2 Layer II", - "MPEG-1/2 Layer III", - "MPEG-2/4 AAC", - "AC-3", + "Layer I", + "Layer II", + "Layer III", NULL }; static const char *mpeg_audio_l1_bitrate[] = { @@ -241,28 +243,6 @@ const char **v4l2_ctrl_get_menu(u32 id) "320 kbps", NULL }; - static const char *mpeg_audio_ac3_bitrate[] = { - "32 kbps", - "40 kbps", - "48 kbps", - "56 kbps", - "64 kbps", - "80 kbps", - "96 kbps", - "112 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "320 kbps", - "384 kbps", - "448 kbps", - "512 kbps", - "576 kbps", - "640 kbps", - NULL - }; static const char *mpeg_audio_mode[] = { "Stereo", "Joint Stereo", @@ -291,7 +271,6 @@ const char **v4l2_ctrl_get_menu(u32 id) static const char *mpeg_video_encoding[] = { "MPEG-1", "MPEG-2", - "MPEG-4 AVC", NULL }; static const char *mpeg_video_aspect[] = { @@ -332,8 +311,6 @@ const char **v4l2_ctrl_get_menu(u32 id) return mpeg_audio_l2_bitrate; case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return mpeg_audio_l3_bitrate; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - return mpeg_audio_ac3_bitrate; case V4L2_CID_MPEG_AUDIO_MODE: return mpeg_audio_mode; case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: @@ -358,73 +335,62 @@ const char **v4l2_ctrl_get_menu(u32 id) } EXPORT_SYMBOL(v4l2_ctrl_get_menu); -/* Return the control name. */ -const char *v4l2_ctrl_get_name(u32 id) +/* Fill in a struct v4l2_queryctrl */ +int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) { - switch (id) { + const char *name; + + qctrl->flags = 0; + switch (qctrl->id) { /* USER controls */ - case V4L2_CID_USER_CLASS: return "User Controls"; - case V4L2_CID_AUDIO_VOLUME: return "Volume"; - case V4L2_CID_AUDIO_MUTE: return "Mute"; - case V4L2_CID_AUDIO_BALANCE: return "Balance"; - case V4L2_CID_AUDIO_BASS: return "Bass"; - case V4L2_CID_AUDIO_TREBLE: return "Treble"; - case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; - case V4L2_CID_BRIGHTNESS: return "Brightness"; - case V4L2_CID_CONTRAST: return "Contrast"; - case V4L2_CID_SATURATION: return "Saturation"; - case V4L2_CID_HUE: return "Hue"; + case V4L2_CID_USER_CLASS: name = "User Controls"; break; + case V4L2_CID_AUDIO_VOLUME: name = "Volume"; break; + case V4L2_CID_AUDIO_MUTE: name = "Mute"; break; + case V4L2_CID_AUDIO_BALANCE: name = "Balance"; break; + case V4L2_CID_AUDIO_BASS: name = "Bass"; break; + case V4L2_CID_AUDIO_TREBLE: name = "Treble"; break; + case V4L2_CID_AUDIO_LOUDNESS: name = "Loudness"; break; + case V4L2_CID_BRIGHTNESS: name = "Brightness"; break; + case V4L2_CID_CONTRAST: name = "Contrast"; break; + case V4L2_CID_SATURATION: name = "Saturation"; break; + case V4L2_CID_HUE: name = "Hue"; break; /* MPEG controls */ - case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency"; - case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding"; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; - case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; - case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis"; - case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC"; - case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; - case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; - case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size"; - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; - case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; - case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; - case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute"; - case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; - case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type"; - case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID"; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID"; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID"; - case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID"; - case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID"; - case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; - case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; + case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break; + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break; + case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding Layer"; break; + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break; + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break; + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break; + case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break; + case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break; + case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break; + case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break; + case V4L2_CID_MPEG_AUDIO_MUTE: name = "Audio Mute"; break; + case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break; + case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break; + case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: name = "Video GOP Size"; break; + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: name = "Video GOP Closure"; break; + case V4L2_CID_MPEG_VIDEO_PULLDOWN: name = "Video Pulldown"; break; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: name = "Video Bitrate Mode"; break; + case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break; + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break; + case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break; + case V4L2_CID_MPEG_VIDEO_MUTE: name = "Video Mute"; break; + case V4L2_CID_MPEG_VIDEO_MUTE_YUV: name = "Video Mute YUV"; break; + case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break; + case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break; + case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break; + case V4L2_CID_MPEG_STREAM_PID_VIDEO: name = "Stream Video Program ID"; break; + case V4L2_CID_MPEG_STREAM_PID_PCR: name = "Stream PCR Program ID"; break; + case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: name = "Stream PES Audio ID"; break; + case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: name = "Stream PES Video ID"; break; + case V4L2_CID_MPEG_STREAM_VBI_FMT: name = "Stream VBI Format"; break; default: - return NULL; - } -} -EXPORT_SYMBOL(v4l2_ctrl_get_name); - -/* Fill in a struct v4l2_queryctrl */ -int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) -{ - const char *name = v4l2_ctrl_get_name(qctrl->id); - - qctrl->flags = 0; - if (name == NULL) return -EINVAL; - + } switch (qctrl->id) { case V4L2_CID_AUDIO_MUTE: case V4L2_CID_AUDIO_LOUDNESS: @@ -441,7 +407,6 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_MPEG_AUDIO_L1_BITRATE: case V4L2_CID_MPEG_AUDIO_L2_BITRATE: case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: case V4L2_CID_MPEG_AUDIO_MODE: case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: case V4L2_CID_MPEG_AUDIO_EMPHASIS: @@ -528,7 +493,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) case V4L2_CID_MPEG_AUDIO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_1, - V4L2_MPEG_AUDIO_ENCODING_AC3, 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_3, 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2); case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return v4l2_ctrl_query_fill(qctrl, @@ -545,13 +510,6 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) V4L2_MPEG_AUDIO_L3_BITRATE_32K, V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1, V4L2_MPEG_AUDIO_L3_BITRATE_192K); - case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: - return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000); - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_AC3_BITRATE_32K, - V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1, - V4L2_MPEG_AUDIO_AC3_BITRATE_384K); case V4L2_CID_MPEG_AUDIO_MODE: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_MODE_STEREO, @@ -577,7 +535,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) case V4L2_CID_MPEG_VIDEO_ENCODING: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, V4L2_MPEG_VIDEO_ENCODING_MPEG_2); case V4L2_CID_MPEG_VIDEO_ASPECT: return v4l2_ctrl_query_fill(qctrl, @@ -636,17 +594,12 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and - the menu. The qctrl pointer may be NULL, in which case it is ignored. - If menu_items is NULL, then the menu items are retrieved using - v4l2_ctrl_get_menu. */ + the menu. The qctrl pointer may be NULL, in which case it is ignored. */ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, const char **menu_items) { int i; - qmenu->reserved = 0; - if (menu_items == NULL) - menu_items = v4l2_ctrl_get_menu(qmenu->id); if (menu_items == NULL || (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) return -EINVAL; @@ -654,31 +607,11 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc if (menu_items[i] == NULL || menu_items[i][0] == '\0') return -EINVAL; snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]); + qmenu->reserved = 0; return 0; } EXPORT_SYMBOL(v4l2_ctrl_query_menu); -/* Fill in a struct v4l2_querymenu based on the specified array of valid - menu items (terminated by V4L2_CTRL_MENU_IDS_END). - Use this if there are 'holes' in the list of valid menu items. */ -int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids) -{ - const char **menu_items = v4l2_ctrl_get_menu(qmenu->id); - - qmenu->reserved = 0; - if (menu_items == NULL || ids == NULL) - return -EINVAL; - while (*ids != V4L2_CTRL_MENU_IDS_END) { - if (*ids++ == qmenu->index) { - snprintf(qmenu->name, sizeof(qmenu->name), - menu_items[qmenu->index]); - return 0; - } - } - return -EINVAL; -} -EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items); - /* ctrl_classes points to an array of u32 pointers, the last element is a NULL pointer. Each u32 array is a 0-terminated array of control IDs. Each array must be sorted low to high and belong to the same control diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index ccd6566a515e..155fdec9ac7d 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -42,7 +42,6 @@ static ssize_t show_index(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vfd = container_of(cd, struct video_device, dev); - return sprintf(buf, "%i\n", vfd->index); } @@ -50,7 +49,6 @@ static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vfd = container_of(cd, struct video_device, dev); - return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); } @@ -60,16 +58,12 @@ static struct device_attribute video_device_attrs[] = { __ATTR_NULL }; -/* - * Active devices - */ -static struct video_device *video_device[VIDEO_NUM_DEVICES]; -static DEFINE_MUTEX(videodev_lock); -static DECLARE_BITMAP(video_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES); - struct video_device *video_device_alloc(void) { - return kzalloc(sizeof(struct video_device), GFP_KERNEL); + struct video_device *vfd; + + vfd = kzalloc(sizeof(*vfd), GFP_KERNEL); + return vfd; } EXPORT_SYMBOL(video_device_alloc); @@ -79,52 +73,16 @@ void video_device_release(struct video_device *vfd) } EXPORT_SYMBOL(video_device_release); -void video_device_release_empty(struct video_device *vfd) -{ - /* Do nothing */ - /* Only valid when the video_device struct is a static. */ -} -EXPORT_SYMBOL(video_device_release_empty); - -/* Called when the last user of the character device is gone. */ -static void v4l2_chardev_release(struct kobject *kobj) -{ - struct video_device *vfd = container_of(kobj, struct video_device, cdev.kobj); - - mutex_lock(&videodev_lock); - if (video_device[vfd->minor] != vfd) { - mutex_unlock(&videodev_lock); - BUG(); - return; - } - - /* Free up this device for reuse */ - video_device[vfd->minor] = NULL; - clear_bit(vfd->num, video_nums[vfd->vfl_type]); - mutex_unlock(&videodev_lock); - - /* Release the character device */ - vfd->cdev_release(kobj); - /* Release video_device and perform other - cleanups as needed. */ - if (vfd->release) - vfd->release(vfd); -} - -/* The new kobj_type for the character device */ -static struct kobj_type v4l2_ktype_cdev_default = { - .release = v4l2_chardev_release, -}; - static void video_release(struct device *cd) { struct video_device *vfd = container_of(cd, struct video_device, dev); - /* It's now safe to delete the char device. - This will either trigger the v4l2_chardev_release immediately (if - the refcount goes to 0) or later when the last user of the - character device closes it. */ - cdev_del(&vfd->cdev); +#if 1 + /* needed until all drivers are fixed */ + if (!vfd->release) + return; +#endif + vfd->release(vfd); } static struct class video_class = { @@ -133,12 +91,87 @@ static struct class video_class = { .dev_release = video_release, }; +/* + * Active devices + */ + +static struct video_device *video_device[VIDEO_NUM_DEVICES]; +static DEFINE_MUTEX(videodev_lock); + struct video_device *video_devdata(struct file *file) { return video_device[iminor(file->f_path.dentry->d_inode)]; } EXPORT_SYMBOL(video_devdata); +/* + * Open a video device - FIXME: Obsoleted + */ +static int video_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + int err = 0; + struct video_device *vfl; + const struct file_operations *old_fops; + + if (minor >= VIDEO_NUM_DEVICES) + return -ENODEV; + lock_kernel(); + mutex_lock(&videodev_lock); + vfl = video_device[minor]; + if (vfl == NULL) { + mutex_unlock(&videodev_lock); + request_module("char-major-%d-%d", VIDEO_MAJOR, minor); + mutex_lock(&videodev_lock); + vfl = video_device[minor]; + if (vfl == NULL) { + mutex_unlock(&videodev_lock); + unlock_kernel(); + return -ENODEV; + } + } + old_fops = file->f_op; + file->f_op = fops_get(vfl->fops); + if (file->f_op->open) + err = file->f_op->open(inode, file); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + fops_put(old_fops); + mutex_unlock(&videodev_lock); + unlock_kernel(); + return err; +} + +/* + * open/release helper functions -- handle exclusive opens + * Should be removed soon + */ +int video_exclusive_open(struct inode *inode, struct file *file) +{ + struct video_device *vfl = video_devdata(file); + int retval = 0; + + mutex_lock(&vfl->lock); + if (vfl->users) + retval = -EBUSY; + else + vfl->users++; + mutex_unlock(&vfl->lock); + return retval; +} +EXPORT_SYMBOL(video_exclusive_open); + +int video_exclusive_release(struct inode *inode, struct file *file) +{ + struct video_device *vfl = video_devdata(file); + + vfl->users--; + return 0; +} +EXPORT_SYMBOL(video_exclusive_release); + /** * get_index - assign stream number based on parent device * @vdev: video_device to assign index number to, vdev->dev should be assigned @@ -219,29 +252,33 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, int index) { int i = 0; + int base; + int end; int ret; - int minor_offset = 0; - int minor_cnt = VIDEO_NUM_DEVICES; - const char *name_base; - void *priv = video_get_drvdata(vfd); - - /* the release callback MUST be present */ - BUG_ON(!vfd->release); + char *name_base; if (vfd == NULL) return -EINVAL; switch (type) { case VFL_TYPE_GRABBER: + base = MINOR_VFL_TYPE_GRABBER_MIN; + end = MINOR_VFL_TYPE_GRABBER_MAX+1; name_base = "video"; break; case VFL_TYPE_VTX: + base = MINOR_VFL_TYPE_VTX_MIN; + end = MINOR_VFL_TYPE_VTX_MAX+1; name_base = "vtx"; break; case VFL_TYPE_VBI: + base = MINOR_VFL_TYPE_VBI_MIN; + end = MINOR_VFL_TYPE_VBI_MAX+1; name_base = "vbi"; break; case VFL_TYPE_RADIO: + base = MINOR_VFL_TYPE_RADIO_MIN; + end = MINOR_VFL_TYPE_RADIO_MAX+1; name_base = "radio"; break; default: @@ -250,70 +287,28 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, return -EINVAL; } - vfd->vfl_type = type; - -#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES - /* Keep the ranges for the first four types for historical - * reasons. - * Newer devices (not yet in place) should use the range - * of 128-191 and just pick the first free minor there - * (new style). */ - switch (type) { - case VFL_TYPE_GRABBER: - minor_offset = 0; - minor_cnt = 64; - break; - case VFL_TYPE_RADIO: - minor_offset = 64; - minor_cnt = 64; - break; - case VFL_TYPE_VTX: - minor_offset = 192; - minor_cnt = 32; - break; - case VFL_TYPE_VBI: - minor_offset = 224; - minor_cnt = 32; - break; - default: - minor_offset = 128; - minor_cnt = 64; - break; - } -#endif - - /* Initialize the character device */ - cdev_init(&vfd->cdev, vfd->fops); - vfd->cdev.owner = vfd->fops->owner; /* pick a minor number */ mutex_lock(&videodev_lock); - nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); - if (nr == minor_cnt) - nr = find_first_zero_bit(video_nums[type], minor_cnt); - if (nr == minor_cnt) { - printk(KERN_ERR "could not get a free kernel number\n"); - mutex_unlock(&videodev_lock); - return -ENFILE; - } -#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES - /* 1-on-1 mapping of kernel number to minor number */ - i = nr; -#else - /* The kernel number and minor numbers are independent */ - for (i = 0; i < VIDEO_NUM_DEVICES; i++) - if (video_device[i] == NULL) - break; - if (i == VIDEO_NUM_DEVICES) { - mutex_unlock(&videodev_lock); - printk(KERN_ERR "could not get a free minor\n"); - return -ENFILE; + if (nr >= 0 && nr < end-base) { + /* use the one the driver asked for */ + i = base + nr; + if (NULL != video_device[i]) { + mutex_unlock(&videodev_lock); + return -ENFILE; + } + } else { + /* use first free */ + for (i = base; i < end; i++) + if (NULL == video_device[i]) + break; + if (i == end) { + mutex_unlock(&videodev_lock); + return -ENFILE; + } } -#endif - vfd->minor = i + minor_offset; - vfd->num = nr; - set_bit(nr, video_nums[type]); - BUG_ON(video_device[vfd->minor]); - video_device[vfd->minor] = vfd; + video_device[i] = vfd; + vfd->vfl_type = type; + vfd->minor = i; ret = get_index(vfd, index); vfd->index = ret; @@ -325,41 +320,35 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, goto fail_minor; } - ret = cdev_add(&vfd->cdev, MKDEV(VIDEO_MAJOR, vfd->minor), 1); - if (ret < 0) { - printk(KERN_ERR "%s: cdev_add failed\n", __func__); - goto fail_minor; - } + mutex_init(&vfd->lock); + /* sysfs class */ - memset(&vfd->dev, 0, sizeof(vfd->dev)); - /* The memset above cleared the device's drvdata, so - put back the copy we made earlier. */ - video_set_drvdata(vfd, priv); + memset(&vfd->dev, 0x00, sizeof(vfd->dev)); vfd->dev.class = &video_class; vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); if (vfd->parent) vfd->dev.parent = vfd->parent; - sprintf(vfd->dev.bus_id, "%s%d", name_base, nr); + sprintf(vfd->dev.bus_id, "%s%d", name_base, i - base); ret = device_register(&vfd->dev); if (ret < 0) { printk(KERN_ERR "%s: device_register failed\n", __func__); - goto del_cdev; + goto fail_minor; } - /* Remember the cdev's release function */ - vfd->cdev_release = vfd->cdev.kobj.ktype->release; - /* Install our own */ - vfd->cdev.kobj.ktype = &v4l2_ktype_cdev_default; - return 0; -del_cdev: - cdev_del(&vfd->cdev); +#if 1 + /* needed until all drivers are fixed */ + if (!vfd->release) + printk(KERN_WARNING "videodev: \"%s\" has no release callback. " + "Please fix your driver for proper sysfs support, see " + "http://lwn.net/Articles/36850/\n", vfd->name); +#endif + return 0; fail_minor: mutex_lock(&videodev_lock); video_device[vfd->minor] = NULL; - clear_bit(vfd->num, video_nums[type]); - mutex_unlock(&videodev_lock); vfd->minor = -1; + mutex_unlock(&videodev_lock); return ret; } EXPORT_SYMBOL(video_register_device_index); @@ -374,29 +363,42 @@ EXPORT_SYMBOL(video_register_device_index); void video_unregister_device(struct video_device *vfd) { + mutex_lock(&videodev_lock); + if (video_device[vfd->minor] != vfd) + panic("videodev: bad unregister"); + + video_device[vfd->minor] = NULL; device_unregister(&vfd->dev); + mutex_unlock(&videodev_lock); } EXPORT_SYMBOL(video_unregister_device); +/* + * Video fs operations + */ +static const struct file_operations video_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = video_open, +}; + /* * Initialise video for linux */ + static int __init videodev_init(void) { - dev_t dev = MKDEV(VIDEO_MAJOR, 0); int ret; printk(KERN_INFO "Linux video capture interface: v2.00\n"); - ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME); - if (ret < 0) { - printk(KERN_WARNING "videodev: unable to get major %d\n", - VIDEO_MAJOR); - return ret; + if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { + printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); + return -EIO; } ret = class_register(&video_class); if (ret < 0) { - unregister_chrdev_region(dev, VIDEO_NUM_DEVICES); + unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); printk(KERN_WARNING "video_dev: class_register failed\n"); return -EIO; } @@ -406,10 +408,8 @@ static int __init videodev_init(void) static void __exit videodev_exit(void) { - dev_t dev = MKDEV(VIDEO_MAJOR, 0); - class_unregister(&video_class); - unregister_chrdev_region(dev, VIDEO_NUM_DEVICES); + unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); } module_init(videodev_init) diff --git a/trunk/drivers/media/video/v4l2-ioctl.c b/trunk/drivers/media/video/v4l2-ioctl.c index 155c9d77a463..140ef92c19c1 100644 --- a/trunk/drivers/media/video/v4l2-ioctl.c +++ b/trunk/drivers/media/video/v4l2-ioctl.c @@ -746,6 +746,18 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, f); break; +#if 1 + /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT + * according to the spec. The bttv and saa7134 drivers support + * it though, so just warn that this is deprecated and will be + * removed in the near future. */ + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (ops->vidioc_enum_fmt_vbi_cap) { + printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); + ret = ops->vidioc_enum_fmt_vbi_cap(file, fh, f); + } + break; +#endif case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (ops->vidioc_enum_fmt_vid_out) ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); diff --git a/trunk/drivers/media/video/zoran/videocodec.c b/trunk/drivers/media/video/videocodec.c similarity index 100% rename from trunk/drivers/media/video/zoran/videocodec.c rename to trunk/drivers/media/video/videocodec.c diff --git a/trunk/drivers/media/video/zoran/videocodec.h b/trunk/drivers/media/video/videocodec.h similarity index 100% rename from trunk/drivers/media/video/zoran/videocodec.h rename to trunk/drivers/media/video/videocodec.h diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c index 1efc5f3462c6..1edda456fc64 100644 --- a/trunk/drivers/media/video/vino.c +++ b/trunk/drivers/media/video/vino.c @@ -30,12 +30,16 @@ #include #include #include + +#ifdef CONFIG_KMOD #include +#endif #include #include #include +#include #include #include #include @@ -806,7 +810,7 @@ static void vino_free_buffer_with_count(struct vino_framebuffer *fb, dprintk("vino_free_buffer_with_count(): count = %d\n", count); for (i = 0; i < count; i++) { - ClearPageReserved(virt_to_page((void *)fb->desc_table.virtual[i])); + ClearPageReserved(virt_to_page(fb->desc_table.virtual[i])); dma_unmap_single(NULL, fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], PAGE_SIZE, DMA_FROM_DEVICE); @@ -884,7 +888,7 @@ static int vino_allocate_buffer(struct vino_framebuffer *fb, dma_data_addr + VINO_PAGE_SIZE * j; } - SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i])); + SetPageReserved(virt_to_page(fb->desc_table.virtual[i])); } /* page_count needs to be set anyway, because the descriptor table has @@ -971,7 +975,7 @@ static int vino_prepare_user_buffer(struct vino_framebuffer *fb, dma_data_addr + VINO_PAGE_SIZE * j; } - SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i])); + SetPageReserved(virt_to_page(fb->desc_table.virtual[i])); } /* page_count needs to be set anyway, because the descriptor table has @@ -4021,7 +4025,8 @@ static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs, static int vino_open(struct inode *inode, struct file *file) { - struct vino_channel_settings *vcs = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); int ret = 0; dprintk("open(): channel = %c\n", (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B'); @@ -4052,7 +4057,8 @@ static int vino_open(struct inode *inode, struct file *file) static int vino_close(struct inode *inode, struct file *file) { - struct vino_channel_settings *vcs = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); dprintk("close():\n"); mutex_lock(&vcs->mutex); @@ -4095,7 +4101,8 @@ static struct vm_operations_struct vino_vm_ops = { static int vino_mmap(struct file *file, struct vm_area_struct *vma) { - struct vino_channel_settings *vcs = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); unsigned long start = vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start; @@ -4200,7 +4207,8 @@ static int vino_mmap(struct file *file, struct vm_area_struct *vma) static unsigned int vino_poll(struct file *file, poll_table *pt) { - struct vino_channel_settings *vcs = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); unsigned int outgoing; unsigned int ret = 0; @@ -4240,7 +4248,8 @@ static unsigned int vino_poll(struct file *file, poll_table *pt) static int vino_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct vino_channel_settings *vcs = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); #ifdef VINO_DEBUG switch (_IOC_TYPE(cmd)) { @@ -4347,7 +4356,8 @@ static int vino_do_ioctl(struct inode *inode, struct file *file, static int vino_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct vino_channel_settings *vcs = video_drvdata(file); + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); int ret; if (mutex_lock_interruptible(&vcs->mutex)) @@ -4631,7 +4641,7 @@ static int __init vino_module_init(void) } vino_init_stage++; -#ifdef MODULE +#if defined(CONFIG_KMOD) && defined(MODULE) request_module("saa7191"); request_module("indycam"); #endif diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 65c8af18e767..8ba8daafd7ea 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -898,11 +898,9 @@ static int vivi_open(struct inode *inode, struct file *file) printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); - lock_kernel(); list_for_each_entry(dev, &vivi_devlist, vivi_devlist) if (dev->vfd->minor == minor) goto found; - unlock_kernel(); return -ENODEV; found: @@ -927,10 +925,8 @@ static int vivi_open(struct inode *inode, struct file *file) } unlock: mutex_unlock(&dev->mutex); - if (retval) { - unlock_kernel(); + if (retval) return retval; - } file->private_data = fh; fh->dev = dev; @@ -959,7 +955,6 @@ static int vivi_open(struct inode *inode, struct file *file) sizeof(struct vivi_buffer), fh); vivi_start_thread(fh); - unlock_kernel(); return 0; } diff --git a/trunk/drivers/media/video/vpx3220.c b/trunk/drivers/media/video/vpx3220.c index 45be9ec8edc4..35293029da02 100644 --- a/trunk/drivers/media/video/vpx3220.c +++ b/trunk/drivers/media/video/vpx3220.c @@ -24,6 +24,8 @@ #include #include +#include + #include #include diff --git a/trunk/drivers/media/video/w9966.c b/trunk/drivers/media/video/w9966.c index b2dbe48a92bb..2ff00bc5ad64 100644 --- a/trunk/drivers/media/video/w9966.c +++ b/trunk/drivers/media/video/w9966.c @@ -113,7 +113,6 @@ struct w9966_dev { signed char contrast; signed char color; signed char hue; - unsigned long in_use; }; /* @@ -185,25 +184,10 @@ static int w9966_v4l_ioctl(struct inode *inode, struct file *file, static ssize_t w9966_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); -static int w9966_exclusive_open(struct inode *inode, struct file *file) -{ - struct w9966_dev *cam = video_drvdata(file); - - return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0; -} - -static int w9966_exclusive_release(struct inode *inode, struct file *file) -{ - struct w9966_dev *cam = video_drvdata(file); - - clear_bit(0, &cam->in_use); - return 0; -} - static const struct file_operations w9966_fops = { .owner = THIS_MODULE, - .open = w9966_exclusive_open, - .release = w9966_exclusive_release, + .open = video_exclusive_open, + .release = video_exclusive_release, .ioctl = w9966_v4l_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = v4l_compat_ioctl32, @@ -214,7 +198,6 @@ static const struct file_operations w9966_fops = { static struct video_device w9966_template = { .name = W9966_DRIVERNAME, .fops = &w9966_fops, - .release = video_device_release_empty, }; /* @@ -349,7 +332,7 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port) // Fill in the video_device struct and register us to v4l memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device)); - video_set_drvdata(&cam->vdev, cam); + cam->vdev.priv = cam; if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) return -1; @@ -730,7 +713,8 @@ static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data) static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct w9966_dev *cam = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + struct w9966_dev *cam = vdev->priv; switch(cmd) { @@ -888,7 +872,8 @@ static int w9966_v4l_ioctl(struct inode *inode, struct file *file, static ssize_t w9966_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct w9966_dev *cam = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + struct w9966_dev *cam = vdev->priv; unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000 unsigned char __user *dest = (unsigned char __user *)buf; unsigned long dleft = count; diff --git a/trunk/drivers/media/video/w9968cf.c b/trunk/drivers/media/video/w9968cf.c index dcd45dbd82dc..11edf79f57be 100644 --- a/trunk/drivers/media/video/w9968cf.c +++ b/trunk/drivers/media/video/w9968cf.c @@ -111,7 +111,7 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG; static unsigned int param_nv[24]; /* number of values per parameter */ -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD module_param(ovmod_load, bool, 0644); #endif module_param(simcams, ushort, 0644); @@ -144,7 +144,7 @@ module_param(debug, ushort, 0644); module_param(specific_debug, bool, 0644); #endif -#ifdef CONFIG_MODULES +#ifdef CONFIG_KMOD MODULE_PARM_DESC(ovmod_load, "\n<0|1> Automatic 'ovcamchip' module loading." "\n0 disabled, 1 enabled." diff --git a/trunk/drivers/media/video/zc0301/zc0301_core.c b/trunk/drivers/media/video/zc0301/zc0301_core.c index 6a0902bcba6b..0c3287734c93 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_core.c +++ b/trunk/drivers/media/video/zc0301/zc0301_core.c @@ -657,7 +657,7 @@ static int zc0301_open(struct inode* inode, struct file* filp) if (!down_read_trylock(&zc0301_dev_lock)) return -EAGAIN; - cam = video_drvdata(filp); + cam = video_get_drvdata(video_devdata(filp)); if (wait_for_completion_interruptible(&cam->probe)) { up_read(&zc0301_dev_lock); @@ -739,7 +739,7 @@ static int zc0301_release(struct inode* inode, struct file* filp) down_write(&zc0301_dev_lock); - cam = video_drvdata(filp); + cam = video_get_drvdata(video_devdata(filp)); zc0301_stop_transfer(cam); zc0301_release_buffers(cam); @@ -759,7 +759,7 @@ static int zc0301_release(struct inode* inode, struct file* filp) static ssize_t zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) { - struct zc0301_device *cam = video_drvdata(filp); + struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); struct zc0301_frame_t* f, * i; unsigned long lock_flags; long timeout; @@ -866,7 +866,7 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) static unsigned int zc0301_poll(struct file *filp, poll_table *wait) { - struct zc0301_device *cam = video_drvdata(filp); + struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); struct zc0301_frame_t* f; unsigned long lock_flags; unsigned int mask = 0; @@ -941,7 +941,7 @@ static struct vm_operations_struct zc0301_vm_ops = { static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma) { - struct zc0301_device *cam = video_drvdata(filp); + struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, start = vma->vm_start; void *pos; @@ -1796,7 +1796,7 @@ zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg) static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, unsigned int cmd, void __user * arg) { - struct zc0301_device *cam = video_drvdata(filp); + struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); switch (cmd) { @@ -1891,7 +1891,7 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, static int zc0301_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg) { - struct zc0301_device *cam = video_drvdata(filp); + struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); int err = 0; if (mutex_lock_interruptible(&cam->fileop_mutex)) diff --git a/trunk/drivers/media/video/zoran/zoran.h b/trunk/drivers/media/video/zoran.h similarity index 100% rename from trunk/drivers/media/video/zoran/zoran.h rename to trunk/drivers/media/video/zoran.h diff --git a/trunk/drivers/media/video/zoran/Kconfig b/trunk/drivers/media/video/zoran/Kconfig deleted file mode 100644 index 4ea5fa71de89..000000000000 --- a/trunk/drivers/media/video/zoran/Kconfig +++ /dev/null @@ -1,73 +0,0 @@ -config VIDEO_ZORAN - tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS - help - Say Y for support for MJPEG capture cards based on the Zoran - 36057/36067 PCI controller chipset. This includes the Iomega - Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is - a driver homepage at . For - more information, check . - - To compile this driver as a module, choose M here: the - module will be called zr36067. - -config VIDEO_ZORAN_DC30 - tristate "Pinnacle/Miro DC30(+) support" - depends on VIDEO_ZORAN - select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO - help - Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback - card. This also supports really old DC10 cards based on the - zr36050 MJPEG codec and zr36016 VFE. - -config VIDEO_ZORAN_ZR36060 - tristate "Zoran ZR36060" - depends on VIDEO_ZORAN - help - Say Y to support Zoran boards based on 36060 chips. - This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 - and 33 R10 and AverMedia 6 boards. - -config VIDEO_ZORAN_BUZ - tristate "Iomega Buz support" - depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO - help - Support for the Iomega Buz MJPEG capture/playback card. - -config VIDEO_ZORAN_DC10 - tristate "Pinnacle/Miro DC10(+) support" - depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO - help - Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback - card. - -config VIDEO_ZORAN_LML33 - tristate "Linux Media Labs LML33 support" - depends on VIDEO_ZORAN_ZR36060 - select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO - help - Support for the Linux Media Labs LML33 MJPEG capture/playback - card. - -config VIDEO_ZORAN_LML33R10 - tristate "Linux Media Labs LML33R10 support" - depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO - help - support for the Linux Media Labs LML33R10 MJPEG capture/playback - card. - -config VIDEO_ZORAN_AVS6EYES - tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 - select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO - help - Support for the AverMedia 6 Eyes video surveillance card. diff --git a/trunk/drivers/media/video/zoran/Makefile b/trunk/drivers/media/video/zoran/Makefile deleted file mode 100644 index 44cc13352c88..000000000000 --- a/trunk/drivers/media/video/zoran/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -zr36067-objs := zoran_procfs.o zoran_device.o \ - zoran_driver.o zoran_card.o - -obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o -obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o -obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o diff --git a/trunk/drivers/media/video/zoran/zoran_card.c b/trunk/drivers/media/video/zoran_card.c similarity index 100% rename from trunk/drivers/media/video/zoran/zoran_card.c rename to trunk/drivers/media/video/zoran_card.c diff --git a/trunk/drivers/media/video/zoran/zoran_card.h b/trunk/drivers/media/video/zoran_card.h similarity index 100% rename from trunk/drivers/media/video/zoran/zoran_card.h rename to trunk/drivers/media/video/zoran_card.h diff --git a/trunk/drivers/media/video/zoran/zoran_device.c b/trunk/drivers/media/video/zoran_device.c similarity index 99% rename from trunk/drivers/media/video/zoran/zoran_device.c rename to trunk/drivers/media/video/zoran_device.c index 5d948ff7faf0..88d369708e4c 100644 --- a/trunk/drivers/media/video/zoran/zoran_device.c +++ b/trunk/drivers/media/video/zoran_device.c @@ -58,6 +58,8 @@ ZR36057_ISR_GIRQ1 | \ ZR36057_ISR_JPEGRepIRQ ) +extern const struct zoran_format zoran_formats[]; + static int lml33dpath; /* default = 0 * 1 will use digital path in capture * mode instead of analog. It can be @@ -375,7 +377,7 @@ zr36057_set_vfe (struct zoran *zr, /* horizontal */ VidWinWid = video_width; - X = DIV_ROUND_UP(VidWinWid * 64, tvn->Wa); + X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa; We = (VidWinWid * 64) / X; HorDcm = 64 - X; hcrop1 = 2 * ((tvn->Wa - We) / 4); @@ -401,7 +403,7 @@ zr36057_set_vfe (struct zoran *zr, /* Vertical */ DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); VidWinHt = DispMode ? video_height : video_height / 2; - Y = DIV_ROUND_UP(VidWinHt * 64 * 2, tvn->Ha); + Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha; He = (VidWinHt * 64) / Y; VerDcm = 64 - Y; vcrop1 = (tvn->Ha / 2 - He) / 2; diff --git a/trunk/drivers/media/video/zoran/zoran_device.h b/trunk/drivers/media/video/zoran_device.h similarity index 94% rename from trunk/drivers/media/video/zoran/zoran_device.h rename to trunk/drivers/media/video/zoran_device.h index 74c6c8edb7d0..37fa86a34083 100644 --- a/trunk/drivers/media/video/zoran/zoran_device.h +++ b/trunk/drivers/media/video/zoran_device.h @@ -78,14 +78,6 @@ extern void zoran_set_pci_master(struct zoran *zr, extern void zoran_init_hardware(struct zoran *zr); extern void zr36057_restart(struct zoran *zr); -extern const struct zoran_format zoran_formats[]; - -extern int v4l_nbufs; -extern int v4l_bufsize; -extern int jpg_nbufs; -extern int jpg_bufsize; -extern int pass_through; - /* i2c */ extern int decoder_command(struct zoran *zr, int cmd, diff --git a/trunk/drivers/media/video/zoran/zoran_driver.c b/trunk/drivers/media/video/zoran_driver.c similarity index 99% rename from trunk/drivers/media/video/zoran/zoran_driver.c rename to trunk/drivers/media/video/zoran_driver.c index 25de7631443e..2dab9eea4def 100644 --- a/trunk/drivers/media/video/zoran/zoran_driver.c +++ b/trunk/drivers/media/video/zoran_driver.c @@ -194,6 +194,12 @@ const struct zoran_format zoran_formats[] = { // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined +extern int v4l_nbufs; +extern int v4l_bufsize; +extern int jpg_nbufs; +extern int jpg_bufsize; +extern int pass_through; + static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ module_param(lock_norm, int, 0644); MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); @@ -1205,7 +1211,6 @@ zoran_open (struct inode *inode, struct zoran_fh *fh; int i, res, first_open = 0, have_module_locks = 0; - lock_kernel(); /* find the device */ for (i = 0; i < zoran_num; i++) { if (zoran[i]->video_dev->minor == minor) { @@ -1316,7 +1321,6 @@ zoran_open (struct inode *inode, file->private_data = fh; fh->zr = zr; zoran_open_init_session(file); - unlock_kernel(); return 0; @@ -1334,7 +1338,6 @@ zoran_open (struct inode *inode, if (zr) { /*mutex_unlock(&zr->resource_lock);*/ } - unlock_kernel(); return res; } @@ -2917,8 +2920,6 @@ zoran_do_ioctl (struct inode *inode, fmt->fmt.pix.bytesperline = 0; fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; /* we hereby abuse this variable to show that * we're gonna do mjpeg capture */ @@ -2978,8 +2979,6 @@ zoran_do_ioctl (struct inode *inode, fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) fmt->fmt.pix.field = diff --git a/trunk/drivers/media/video/zoran/zoran_procfs.c b/trunk/drivers/media/video/zoran_procfs.c similarity index 100% rename from trunk/drivers/media/video/zoran/zoran_procfs.c rename to trunk/drivers/media/video/zoran_procfs.c diff --git a/trunk/drivers/media/video/zoran/zoran_procfs.h b/trunk/drivers/media/video/zoran_procfs.h similarity index 100% rename from trunk/drivers/media/video/zoran/zoran_procfs.h rename to trunk/drivers/media/video/zoran_procfs.h diff --git a/trunk/drivers/media/video/zoran/zr36016.c b/trunk/drivers/media/video/zr36016.c similarity index 100% rename from trunk/drivers/media/video/zoran/zr36016.c rename to trunk/drivers/media/video/zr36016.c diff --git a/trunk/drivers/media/video/zoran/zr36016.h b/trunk/drivers/media/video/zr36016.h similarity index 100% rename from trunk/drivers/media/video/zoran/zr36016.h rename to trunk/drivers/media/video/zr36016.h diff --git a/trunk/drivers/media/video/zoran/zr36050.c b/trunk/drivers/media/video/zr36050.c similarity index 100% rename from trunk/drivers/media/video/zoran/zr36050.c rename to trunk/drivers/media/video/zr36050.c diff --git a/trunk/drivers/media/video/zoran/zr36050.h b/trunk/drivers/media/video/zr36050.h similarity index 100% rename from trunk/drivers/media/video/zoran/zr36050.h rename to trunk/drivers/media/video/zr36050.h diff --git a/trunk/drivers/media/video/zoran/zr36057.h b/trunk/drivers/media/video/zr36057.h similarity index 100% rename from trunk/drivers/media/video/zoran/zr36057.h rename to trunk/drivers/media/video/zr36057.h diff --git a/trunk/drivers/media/video/zoran/zr36060.c b/trunk/drivers/media/video/zr36060.c similarity index 100% rename from trunk/drivers/media/video/zoran/zr36060.c rename to trunk/drivers/media/video/zr36060.c diff --git a/trunk/drivers/media/video/zoran/zr36060.h b/trunk/drivers/media/video/zr36060.h similarity index 100% rename from trunk/drivers/media/video/zoran/zr36060.h rename to trunk/drivers/media/video/zr36060.h diff --git a/trunk/drivers/media/video/zr364xx.c b/trunk/drivers/media/video/zr364xx.c index 7cdac99deea6..18d1c4ba79fb 100644 --- a/trunk/drivers/media/video/zr364xx.c +++ b/trunk/drivers/media/video/zr364xx.c @@ -52,7 +52,7 @@ /* Debug macro */ -#define DBG(x...) if (debug) printk(KERN_INFO KBUILD_MODNAME x) +#define DBG(x...) if (debug) info(x) /* Init methods, need to find nicer names for these @@ -116,7 +116,6 @@ struct zr364xx_camera { int height; int method; struct mutex lock; - int users; }; @@ -128,7 +127,7 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); if (!transfer_buffer) { - dev_err(&udev->dev, "kmalloc(%d) failed\n", size); + info("kmalloc(%d) failed", size); return -ENOMEM; } @@ -144,8 +143,7 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, kfree(transfer_buffer); if (status < 0) - dev_err(&udev->dev, - "Failed sending control message, error %d.\n", status); + info("Failed sending control message, error %d.", status); return status; } @@ -305,11 +303,11 @@ static int read_frame(struct zr364xx_camera *cam, int framenum) DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]); DBG("bulk : n=%d size=%d", n, actual_length); if (n < 0) { - dev_err(&cam->udev->dev, "error reading bulk msg\n"); + info("error reading bulk msg"); return 0; } if (actual_length < 0 || actual_length > BUFFER_SIZE) { - dev_err(&cam->udev->dev, "wrong number of bytes\n"); + info("wrong number of bytes"); return 0; } @@ -643,47 +641,42 @@ static int zr364xx_open(struct inode *inode, struct file *file) DBG("zr364xx_open"); - mutex_lock(&cam->lock); + cam->skip = 2; - if (cam->users) { - err = -EBUSY; - goto out; - } + err = video_exclusive_open(inode, file); + if (err < 0) + return err; if (!cam->framebuf) { cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES); if (!cam->framebuf) { - dev_err(&cam->udev->dev, "vmalloc_32 failed!\n"); - err = -ENOMEM; - goto out; + info("vmalloc_32 failed!"); + return -ENOMEM; } } + mutex_lock(&cam->lock); for (i = 0; init[cam->method][i].size != -1; i++) { err = send_control_msg(udev, 1, init[cam->method][i].value, 0, init[cam->method][i].bytes, init[cam->method][i].size); if (err < 0) { - dev_err(&cam->udev->dev, - "error during open sequence: %d\n", i); - goto out; + info("error during open sequence: %d", i); + mutex_unlock(&cam->lock); + return err; } } - cam->skip = 2; - cam->users++; file->private_data = vdev; /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam */ mdelay(100); - err = 0; -out: mutex_unlock(&cam->lock); - return err; + return 0; } @@ -704,30 +697,28 @@ static int zr364xx_release(struct inode *inode, struct file *file) udev = cam->udev; mutex_lock(&cam->lock); - - cam->users--; - file->private_data = NULL; - for (i = 0; i < 2; i++) { err = send_control_msg(udev, 1, init[cam->method][i].value, 0, init[i][cam->method].bytes, init[cam->method][i].size); if (err < 0) { - dev_err(&udev->dev, "error during release sequence\n"); - goto out; + info("error during release sequence"); + mutex_unlock(&cam->lock); + return err; } } + file->private_data = NULL; + video_exclusive_release(inode, file); + /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam */ mdelay(100); - err = 0; -out: mutex_unlock(&cam->lock); - return err; + return 0; } @@ -810,14 +801,13 @@ static int zr364xx_probe(struct usb_interface *intf, DBG("probing..."); - dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n"); - dev_info(&intf->dev, "model %04x:%04x detected\n", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); + info(DRIVER_DESC " compatible webcam plugged"); + info("model %04x:%04x detected", udev->descriptor.idVendor, + udev->descriptor.idProduct); cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL); if (cam == NULL) { - dev_err(&udev->dev, "cam: out of memory !\n"); + info("cam: out of memory !"); return -ENOMEM; } /* save the init method used by this camera */ @@ -825,7 +815,7 @@ static int zr364xx_probe(struct usb_interface *intf, cam->vdev = video_device_alloc(); if (cam->vdev == NULL) { - dev_err(&udev->dev, "cam->vdev: out of memory !\n"); + info("cam->vdev: out of memory !"); kfree(cam); return -ENOMEM; } @@ -837,7 +827,7 @@ static int zr364xx_probe(struct usb_interface *intf, cam->udev = udev; if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) { - dev_info(&udev->dev, "cam->buffer: out of memory !\n"); + info("cam->buffer: out of memory !"); video_device_release(cam->vdev); kfree(cam); return -ENODEV; @@ -845,17 +835,17 @@ static int zr364xx_probe(struct usb_interface *intf, switch (mode) { case 1: - dev_info(&udev->dev, "160x120 mode selected\n"); + info("160x120 mode selected"); cam->width = 160; cam->height = 120; break; case 2: - dev_info(&udev->dev, "640x480 mode selected\n"); + info("640x480 mode selected"); cam->width = 640; cam->height = 480; break; default: - dev_info(&udev->dev, "320x240 mode selected\n"); + info("320x240 mode selected"); cam->width = 320; cam->height = 240; break; @@ -875,7 +865,7 @@ static int zr364xx_probe(struct usb_interface *intf, err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1); if (err) { - dev_err(&udev->dev, "video_register_device failed\n"); + info("video_register_device failed"); video_device_release(cam->vdev); kfree(cam->buffer); kfree(cam); @@ -884,8 +874,7 @@ static int zr364xx_probe(struct usb_interface *intf, usb_set_intfdata(intf, cam); - dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n", - cam->vdev->minor); + info(DRIVER_DESC " controlling video device %d", cam->vdev->minor); return 0; } @@ -895,7 +884,7 @@ static void zr364xx_disconnect(struct usb_interface *intf) struct zr364xx_camera *cam = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); dev_set_drvdata(&intf->dev, NULL); - dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); + info(DRIVER_DESC " webcam unplugged"); if (cam->vdev) video_unregister_device(cam->vdev); cam->vdev = NULL; @@ -924,16 +913,16 @@ static int __init zr364xx_init(void) int retval; retval = usb_register(&zr364xx_driver); if (retval) - printk(KERN_ERR KBUILD_MODNAME ": usb_register failed!\n"); + info("usb_register failed!"); else - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); + info(DRIVER_DESC " module loaded"); return retval; } static void __exit zr364xx_exit(void) { - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC " module unloaded\n"); + info(DRIVER_DESC " module unloaded"); usb_deregister(&zr364xx_driver); } diff --git a/trunk/drivers/message/i2o/Makefile b/trunk/drivers/message/i2o/Makefile index b0982dacfd0a..2c2e39aa1efa 100644 --- a/trunk/drivers/message/i2o/Makefile +++ b/trunk/drivers/message/i2o/Makefile @@ -5,7 +5,7 @@ # In the future, some of these should be built conditionally. # -i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o memory.o +i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o i2o_bus-y += bus-osm.o i2o_config-y += config-osm.o obj-$(CONFIG_I2O) += i2o_core.o diff --git a/trunk/drivers/message/i2o/device.c b/trunk/drivers/message/i2o/device.c index 54c2e9ae23e5..8774c670e668 100644 --- a/trunk/drivers/message/i2o/device.c +++ b/trunk/drivers/message/i2o/device.c @@ -467,7 +467,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, res.virt = NULL; - if (i2o_dma_alloc(dev, &res, reslen)) + if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL)) return -ENOMEM; msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); diff --git a/trunk/drivers/message/i2o/exec-osm.c b/trunk/drivers/message/i2o/exec-osm.c index 56faef1a1d55..6cbcc21de518 100644 --- a/trunk/drivers/message/i2o/exec-osm.c +++ b/trunk/drivers/message/i2o/exec-osm.c @@ -388,8 +388,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) dev = &c->pdev->dev; - if (i2o_dma_realloc(dev, &c->dlct, - le32_to_cpu(sb->expected_lct_size))) + if (i2o_dma_realloc + (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL)) return -ENOMEM; msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); diff --git a/trunk/drivers/message/i2o/i2o_config.c b/trunk/drivers/message/i2o/i2o_config.c index a3fabdbe6ca6..4238de98d4a6 100644 --- a/trunk/drivers/message/i2o/i2o_config.c +++ b/trunk/drivers/message/i2o/i2o_config.c @@ -260,7 +260,7 @@ static int i2o_cfg_swdl(unsigned long arg) if (IS_ERR(msg)) return PTR_ERR(msg); - if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) { + if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { i2o_msg_nop(c, msg); return -ENOMEM; } @@ -339,7 +339,7 @@ static int i2o_cfg_swul(unsigned long arg) if (IS_ERR(msg)) return PTR_ERR(msg); - if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) { + if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { i2o_msg_nop(c, msg); return -ENOMEM; } @@ -634,7 +634,9 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, sg_size = sg[i].flag_count & 0xffffff; p = &(sg_list[sg_index]); /* Allocate memory for the transfer */ - if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) { + if (i2o_dma_alloc + (&c->pdev->dev, p, sg_size, + PCI_DMA_BIDIRECTIONAL)) { printk(KERN_DEBUG "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", c->name, sg_size, i, sg_count); @@ -778,11 +780,12 @@ static int i2o_cfg_passthru(unsigned long arg) u32 size = 0; u32 reply_size = 0; u32 rcode = 0; - struct i2o_dma sg_list[SG_TABLESIZE]; + void *sg_list[SG_TABLESIZE]; u32 sg_offset = 0; u32 sg_count = 0; int sg_index = 0; u32 i = 0; + void *p = NULL; i2o_status_block *sb; struct i2o_message *msg; unsigned int iop; @@ -839,7 +842,6 @@ static int i2o_cfg_passthru(unsigned long arg) memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); if (sg_offset) { struct sg_simple_element *sg; - struct i2o_dma *p; if (sg_offset * 4 >= size) { rcode = -EFAULT; @@ -869,22 +871,22 @@ static int i2o_cfg_passthru(unsigned long arg) goto sg_list_cleanup; } sg_size = sg[i].flag_count & 0xffffff; - p = &(sg_list[sg_index]); - if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) { /* Allocate memory for the transfer */ + p = kmalloc(sg_size, GFP_KERNEL); + if (!p) { printk(KERN_DEBUG "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", c->name, sg_size, i, sg_count); rcode = -ENOMEM; goto sg_list_cleanup; } - sg_index++; + sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. /* Copy in the user's SG buffer if necessary */ if (sg[i]. flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { // TODO 64bit fix if (copy_from_user - (p->virt, (void __user *)sg[i].addr_bus, + (p, (void __user *)sg[i].addr_bus, sg_size)) { printk(KERN_DEBUG "%s: Could not copy SG buf %d FROM user\n", @@ -893,7 +895,8 @@ static int i2o_cfg_passthru(unsigned long arg) goto sg_list_cleanup; } } - sg[i].addr_bus = p->phys; + //TODO 64bit fix + sg[i].addr_bus = virt_to_bus(p); } } @@ -905,7 +908,7 @@ static int i2o_cfg_passthru(unsigned long arg) } if (sg_offset) { - u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE]; + u32 rmsg[128]; /* Copy back the Scatter Gather buffers back to user space */ u32 j; // TODO 64bit fix @@ -939,11 +942,11 @@ static int i2o_cfg_passthru(unsigned long arg) sg_size = sg[j].flag_count & 0xffffff; // TODO 64bit fix if (copy_to_user - ((void __user *)sg[j].addr_bus, sg_list[j].virt, + ((void __user *)sg[j].addr_bus, sg_list[j], sg_size)) { printk(KERN_WARNING "%s: Could not copy %p TO user %x\n", - c->name, sg_list[j].virt, + c->name, sg_list[j], sg[j].addr_bus); rcode = -EFAULT; goto sg_list_cleanup; @@ -970,7 +973,7 @@ static int i2o_cfg_passthru(unsigned long arg) } for (i = 0; i < sg_index; i++) - i2o_dma_free(&c->pdev->dev, &sg_list[i]); + kfree(sg_list[i]); cleanup: kfree(reply); diff --git a/trunk/drivers/message/i2o/iop.c b/trunk/drivers/message/i2o/iop.c index be2b5926d26c..da715e11c1b2 100644 --- a/trunk/drivers/message/i2o/iop.c +++ b/trunk/drivers/message/i2o/iop.c @@ -1004,7 +1004,7 @@ static int i2o_hrt_get(struct i2o_controller *c) size = hrt->num_entries * hrt->entry_len << 2; if (size > c->hrt.len) { - if (i2o_dma_realloc(dev, &c->hrt, size)) + if (i2o_dma_realloc(dev, &c->hrt, size, GFP_KERNEL)) return -ENOMEM; else hrt = c->hrt.virt; diff --git a/trunk/drivers/message/i2o/memory.c b/trunk/drivers/message/i2o/memory.c deleted file mode 100644 index f5cc95c564e2..000000000000 --- a/trunk/drivers/message/i2o/memory.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Functions to handle I2O memory - * - * Pulled from the inlines in i2o headers and uninlined - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include "core.h" - -/* Protects our 32/64bit mask switching */ -static DEFINE_MUTEX(mem_lock); - -/** - * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL - * @c: I2O controller for which the calculation should be done - * @body_size: maximum body size used for message in 32-bit words. - * - * Return the maximum number of SG elements in a SG list. - */ -u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size) -{ - i2o_status_block *sb = c->status_block.virt; - u16 sg_count = - (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) - - body_size; - - if (c->pae_support) { - /* - * for 64-bit a SG attribute element must be added and each - * SG element needs 12 bytes instead of 8. - */ - sg_count -= 2; - sg_count /= 3; - } else - sg_count /= 2; - - if (c->short_req && (sg_count > 8)) - sg_count = 8; - - return sg_count; -} -EXPORT_SYMBOL_GPL(i2o_sg_tablesize); - - -/** - * i2o_dma_map_single - Map pointer to controller and fill in I2O message. - * @c: I2O controller - * @ptr: pointer to the data which should be mapped - * @size: size of data in bytes - * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE - * @sg_ptr: pointer to the SG list inside the I2O message - * - * This function does all necessary DMA handling and also writes the I2O - * SGL elements into the I2O message. For details on DMA handling see also - * dma_map_single(). The pointer sg_ptr will only be set to the end of the - * SG list if the allocation was successful. - * - * Returns DMA address which must be checked for failures using - * dma_mapping_error(). - */ -dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, - size_t size, - enum dma_data_direction direction, - u32 ** sg_ptr) -{ - u32 sg_flags; - u32 *mptr = *sg_ptr; - dma_addr_t dma_addr; - - switch (direction) { - case DMA_TO_DEVICE: - sg_flags = 0xd4000000; - break; - case DMA_FROM_DEVICE: - sg_flags = 0xd0000000; - break; - default: - return 0; - } - - dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) { - *mptr++ = cpu_to_le32(0x7C020002); - *mptr++ = cpu_to_le32(PAGE_SIZE); - } -#endif - - *mptr++ = cpu_to_le32(sg_flags | size); - *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr)); -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) - *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr)); -#endif - *sg_ptr = mptr; - } - return dma_addr; -} -EXPORT_SYMBOL_GPL(i2o_dma_map_single); - -/** - * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message. - * @c: I2O controller - * @sg: SG list to be mapped - * @sg_count: number of elements in the SG list - * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE - * @sg_ptr: pointer to the SG list inside the I2O message - * - * This function does all necessary DMA handling and also writes the I2O - * SGL elements into the I2O message. For details on DMA handling see also - * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG - * list if the allocation was successful. - * - * Returns 0 on failure or 1 on success. - */ -int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg, - int sg_count, enum dma_data_direction direction, u32 ** sg_ptr) -{ - u32 sg_flags; - u32 *mptr = *sg_ptr; - - switch (direction) { - case DMA_TO_DEVICE: - sg_flags = 0x14000000; - break; - case DMA_FROM_DEVICE: - sg_flags = 0x10000000; - break; - default: - return 0; - } - - sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction); - if (!sg_count) - return 0; - -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) { - *mptr++ = cpu_to_le32(0x7C020002); - *mptr++ = cpu_to_le32(PAGE_SIZE); - } -#endif - - while (sg_count-- > 0) { - if (!sg_count) - sg_flags |= 0xC0000000; - *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg)); - *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg))); -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) - *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg))); -#endif - sg = sg_next(sg); - } - *sg_ptr = mptr; - - return 1; -} -EXPORT_SYMBOL_GPL(i2o_dma_map_sg); - -/** - * i2o_dma_alloc - Allocate DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: i2o_dma struct which should get the DMA buffer - * @len: length of the new DMA memory - * - * Allocate a coherent DMA memory and write the pointers into addr. - * - * Returns 0 on success or -ENOMEM on failure. - */ -int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len) -{ - struct pci_dev *pdev = to_pci_dev(dev); - int dma_64 = 0; - - mutex_lock(&mem_lock); - if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) { - dma_64 = 1; - if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { - mutex_unlock(&mem_lock); - return -ENOMEM; - } - } - - addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL); - - if ((sizeof(dma_addr_t) > 4) && dma_64) - if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)) - printk(KERN_WARNING "i2o: unable to set 64-bit DMA"); - mutex_unlock(&mem_lock); - - if (!addr->virt) - return -ENOMEM; - - memset(addr->virt, 0, len); - addr->len = len; - - return 0; -} -EXPORT_SYMBOL_GPL(i2o_dma_alloc); - - -/** - * i2o_dma_free - Free DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: i2o_dma struct which contains the DMA buffer - * - * Free a coherent DMA memory and set virtual address of addr to NULL. - */ -void i2o_dma_free(struct device *dev, struct i2o_dma *addr) -{ - if (addr->virt) { - if (addr->phys) - dma_free_coherent(dev, addr->len, addr->virt, - addr->phys); - else - kfree(addr->virt); - addr->virt = NULL; - } -} -EXPORT_SYMBOL_GPL(i2o_dma_free); - - -/** - * i2o_dma_realloc - Realloc DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: pointer to a i2o_dma struct DMA buffer - * @len: new length of memory - * - * If there was something allocated in the addr, free it first. If len > 0 - * than try to allocate it and write the addresses back to the addr - * structure. If len == 0 set the virtual address to NULL. - * - * Returns the 0 on success or negative error code on failure. - */ -int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len) -{ - i2o_dma_free(dev, addr); - - if (len) - return i2o_dma_alloc(dev, addr, len); - - return 0; -} -EXPORT_SYMBOL_GPL(i2o_dma_realloc); - -/* - * i2o_pool_alloc - Allocate an slab cache and mempool - * @mempool: pointer to struct i2o_pool to write data into. - * @name: name which is used to identify cache - * @size: size of each object - * @min_nr: minimum number of objects - * - * First allocates a slab cache with name and size. Then allocates a - * mempool which uses the slab cache for allocation and freeing. - * - * Returns 0 on success or negative error code on failure. - */ -int i2o_pool_alloc(struct i2o_pool *pool, const char *name, - size_t size, int min_nr) -{ - pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL); - if (!pool->name) - goto exit; - strcpy(pool->name, name); - - pool->slab = - kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL); - if (!pool->slab) - goto free_name; - - pool->mempool = mempool_create_slab_pool(min_nr, pool->slab); - if (!pool->mempool) - goto free_slab; - - return 0; - -free_slab: - kmem_cache_destroy(pool->slab); - -free_name: - kfree(pool->name); - -exit: - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(i2o_pool_alloc); - -/* - * i2o_pool_free - Free slab cache and mempool again - * @mempool: pointer to struct i2o_pool which should be freed - * - * Note that you have to return all objects to the mempool again before - * calling i2o_pool_free(). - */ -void i2o_pool_free(struct i2o_pool *pool) -{ - mempool_destroy(pool->mempool); - kmem_cache_destroy(pool->slab); - kfree(pool->name); -}; -EXPORT_SYMBOL_GPL(i2o_pool_free); diff --git a/trunk/drivers/message/i2o/pci.c b/trunk/drivers/message/i2o/pci.c index 610ef1204e68..685a89547a51 100644 --- a/trunk/drivers/message/i2o/pci.c +++ b/trunk/drivers/message/i2o/pci.c @@ -186,29 +186,31 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) } } - if (i2o_dma_alloc(dev, &c->status, 8)) { + if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) { + if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt), GFP_KERNEL)) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->dlct, 8192)) { + if (i2o_dma_alloc(dev, &c->dlct, 8192, GFP_KERNEL)) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) { + if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block), + GFP_KERNEL)) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->out_queue, - I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE * - sizeof(u32))) { + if (i2o_dma_alloc + (dev, &c->out_queue, + I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE * + sizeof(u32), GFP_KERNEL)) { i2o_pci_free(c); return -ENOMEM; } diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index 5eff8ad834d6..0dae245c6259 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -87,44 +87,6 @@ config MFD_TC6393XB help Support for Toshiba Mobile IO Controller TC6393XB -config MFD_WM8400 - tristate "Support Wolfson Microelectronics WM8400" - help - Support for the Wolfson Microelecronics WM8400 PMIC and audio - CODEC. This driver adds provides common support for accessing - the device, additional drivers must be enabled in order to use - the functionality of the device. - -config MFD_WM8350 - tristate - -config MFD_WM8350_CONFIG_MODE_0 - bool - depends on MFD_WM8350 - -config MFD_WM8350_CONFIG_MODE_1 - bool - depends on MFD_WM8350 - -config MFD_WM8350_CONFIG_MODE_2 - bool - depends on MFD_WM8350 - -config MFD_WM8350_CONFIG_MODE_3 - bool - depends on MFD_WM8350 - -config MFD_WM8350_I2C - tristate "Support Wolfson Microelectronics WM8350 with I2C" - select MFD_WM8350 - depends on I2C - help - The WM8350 is an integrated audio and power management - subsystem with watchdog and RTC functionality for embedded - systems. This option enables core support for the WM8350 with - I2C as the control interface. Additional options must be - selected to enable support for the functionality of the chip. - endmenu menu "Multimedia Capabilities Port drivers" diff --git a/trunk/drivers/mfd/Makefile b/trunk/drivers/mfd/Makefile index 759b1fe1c891..6abebe364419 100644 --- a/trunk/drivers/mfd/Makefile +++ b/trunk/drivers/mfd/Makefile @@ -12,11 +12,6 @@ obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o -obj-$(CONFIG_MFD_WM8400) += wm8400-core.o -wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o -obj-$(CONFIG_MFD_WM8350) += wm8350.o -obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o - obj-$(CONFIG_MFD_CORE) += mfd-core.o obj-$(CONFIG_MCP) += mcp-core.o diff --git a/trunk/drivers/mfd/wm8350-core.c b/trunk/drivers/mfd/wm8350-core.c deleted file mode 100644 index 25a7a5d08bce..000000000000 --- a/trunk/drivers/mfd/wm8350-core.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* - * wm8350-core.c -- Device access for Wolfson WM8350 - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood, Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WM8350_UNLOCK_KEY 0x0013 -#define WM8350_LOCK_KEY 0x0000 - -#define WM8350_CLOCK_CONTROL_1 0x28 -#define WM8350_AIF_TEST 0x74 - -/* debug */ -#define WM8350_BUS_DEBUG 0 -#if WM8350_BUS_DEBUG -#define dump(regs, src) do { \ - int i_; \ - u16 *src_ = src; \ - printk(KERN_DEBUG); \ - for (i_ = 0; i_ < regs; i_++) \ - printk(" 0x%4.4x", *src_++); \ - printk("\n"); \ -} while (0); -#else -#define dump(bytes, src) -#endif - -#define WM8350_LOCK_DEBUG 0 -#if WM8350_LOCK_DEBUG -#define ldbg(format, arg...) printk(format, ## arg) -#else -#define ldbg(format, arg...) -#endif - -/* - * WM8350 Device IO - */ -static DEFINE_MUTEX(io_mutex); -static DEFINE_MUTEX(reg_lock_mutex); -static DEFINE_MUTEX(auxadc_mutex); - -/* Perform a physical read from the device. - */ -static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs, - u16 *dest) -{ - int i, ret; - int bytes = num_regs * 2; - - dev_dbg(wm8350->dev, "volatile read\n"); - ret = wm8350->read_dev(wm8350, reg, bytes, (char *)dest); - - for (i = reg; i < reg + num_regs; i++) { - /* Cache is CPU endian */ - dest[i - reg] = be16_to_cpu(dest[i - reg]); - - /* Satisfy non-volatile bits from cache */ - dest[i - reg] &= wm8350_reg_io_map[i].vol; - dest[i - reg] |= wm8350->reg_cache[i]; - - /* Mask out non-readable bits */ - dest[i - reg] &= wm8350_reg_io_map[i].readable; - } - - dump(num_regs, dest); - - return ret; -} - -static int wm8350_read(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *dest) -{ - int i; - int end = reg + num_regs; - int ret = 0; - int bytes = num_regs * 2; - - if (wm8350->read_dev == NULL) - return -ENODEV; - - if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { - dev_err(wm8350->dev, "invalid reg %x\n", - reg + num_regs - 1); - return -EINVAL; - } - - dev_dbg(wm8350->dev, - "%s R%d(0x%2.2x) %d regs\n", __func__, reg, reg, num_regs); - -#if WM8350_BUS_DEBUG - /* we can _safely_ read any register, but warn if read not supported */ - for (i = reg; i < end; i++) { - if (!wm8350_reg_io_map[i].readable) - dev_warn(wm8350->dev, - "reg R%d is not readable\n", i); - } -#endif - - /* if any volatile registers are required, then read back all */ - for (i = reg; i < end; i++) - if (wm8350_reg_io_map[i].vol) - return wm8350_phys_read(wm8350, reg, num_regs, dest); - - /* no volatiles, then cache is good */ - dev_dbg(wm8350->dev, "cache read\n"); - memcpy(dest, &wm8350->reg_cache[reg], bytes); - dump(num_regs, dest); - return ret; -} - -static inline int is_reg_locked(struct wm8350 *wm8350, u8 reg) -{ - if (reg == WM8350_SECURITY || - wm8350->reg_cache[WM8350_SECURITY] == WM8350_UNLOCK_KEY) - return 0; - - if ((reg == WM8350_GPIO_CONFIGURATION_I_O) || - (reg >= WM8350_GPIO_FUNCTION_SELECT_1 && - reg <= WM8350_GPIO_FUNCTION_SELECT_4) || - (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 && - reg <= WM8350_BATTERY_CHARGER_CONTROL_3)) - return 1; - return 0; -} - -static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src) -{ - int i; - int end = reg + num_regs; - int bytes = num_regs * 2; - - if (wm8350->write_dev == NULL) - return -ENODEV; - - if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { - dev_err(wm8350->dev, "invalid reg %x\n", - reg + num_regs - 1); - return -EINVAL; - } - - /* it's generally not a good idea to write to RO or locked registers */ - for (i = reg; i < end; i++) { - if (!wm8350_reg_io_map[i].writable) { - dev_err(wm8350->dev, - "attempted write to read only reg R%d\n", i); - return -EINVAL; - } - - if (is_reg_locked(wm8350, i)) { - dev_err(wm8350->dev, - "attempted write to locked reg R%d\n", i); - return -EINVAL; - } - - src[i - reg] &= wm8350_reg_io_map[i].writable; - - wm8350->reg_cache[i] = - (wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable) - | src[i - reg]; - - src[i - reg] = cpu_to_be16(src[i - reg]); - } - - /* Actually write it out */ - return wm8350->write_dev(wm8350, reg, bytes, (char *)src); -} - -/* - * Safe read, modify, write methods - */ -int wm8350_clear_bits(struct wm8350 *wm8350, u16 reg, u16 mask) -{ - u16 data; - int err; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, reg, 1, &data); - if (err) { - dev_err(wm8350->dev, "read from reg R%d failed\n", reg); - goto out; - } - - data &= ~mask; - err = wm8350_write(wm8350, reg, 1, &data); - if (err) - dev_err(wm8350->dev, "write to reg R%d failed\n", reg); -out: - mutex_unlock(&io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(wm8350_clear_bits); - -int wm8350_set_bits(struct wm8350 *wm8350, u16 reg, u16 mask) -{ - u16 data; - int err; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, reg, 1, &data); - if (err) { - dev_err(wm8350->dev, "read from reg R%d failed\n", reg); - goto out; - } - - data |= mask; - err = wm8350_write(wm8350, reg, 1, &data); - if (err) - dev_err(wm8350->dev, "write to reg R%d failed\n", reg); -out: - mutex_unlock(&io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(wm8350_set_bits); - -u16 wm8350_reg_read(struct wm8350 *wm8350, int reg) -{ - u16 data; - int err; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, reg, 1, &data); - if (err) - dev_err(wm8350->dev, "read from reg R%d failed\n", reg); - - mutex_unlock(&io_mutex); - return data; -} -EXPORT_SYMBOL_GPL(wm8350_reg_read); - -int wm8350_reg_write(struct wm8350 *wm8350, int reg, u16 val) -{ - int ret; - u16 data = val; - - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, reg, 1, &data); - if (ret) - dev_err(wm8350->dev, "write to reg R%d failed\n", reg); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_reg_write); - -int wm8350_block_read(struct wm8350 *wm8350, int start_reg, int regs, - u16 *dest) -{ - int err = 0; - - mutex_lock(&io_mutex); - err = wm8350_read(wm8350, start_reg, regs, dest); - if (err) - dev_err(wm8350->dev, "block read starting from R%d failed\n", - start_reg); - mutex_unlock(&io_mutex); - return err; -} -EXPORT_SYMBOL_GPL(wm8350_block_read); - -int wm8350_block_write(struct wm8350 *wm8350, int start_reg, int regs, - u16 *src) -{ - int ret = 0; - - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, start_reg, regs, src); - if (ret) - dev_err(wm8350->dev, "block write starting at R%d failed\n", - start_reg); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_block_write); - -int wm8350_reg_lock(struct wm8350 *wm8350) -{ - u16 key = WM8350_LOCK_KEY; - int ret; - - ldbg(__func__); - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, WM8350_SECURITY, 1, &key); - if (ret) - dev_err(wm8350->dev, "lock failed\n"); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_reg_lock); - -int wm8350_reg_unlock(struct wm8350 *wm8350) -{ - u16 key = WM8350_UNLOCK_KEY; - int ret; - - ldbg(__func__); - mutex_lock(&io_mutex); - ret = wm8350_write(wm8350, WM8350_SECURITY, 1, &key); - if (ret) - dev_err(wm8350->dev, "unlock failed\n"); - mutex_unlock(&io_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_reg_unlock); - -static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq) -{ - mutex_lock(&wm8350->irq_mutex); - - if (wm8350->irq[irq].handler) - wm8350->irq[irq].handler(wm8350, irq, wm8350->irq[irq].data); - else { - dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n", - irq); - wm8350_mask_irq(wm8350, irq); - } - - mutex_unlock(&wm8350->irq_mutex); -} - -/* - * wm8350_irq_worker actually handles the interrupts. Since all - * interrupts are clear on read the IRQ line will be reasserted and - * the physical IRQ will be handled again if another interrupt is - * asserted while we run - in the normal course of events this is a - * rare occurrence so we save I2C/SPI reads. - */ -static void wm8350_irq_worker(struct work_struct *work) -{ - struct wm8350 *wm8350 = container_of(work, struct wm8350, irq_work); - u16 level_one, status1, status2, comp; - - /* TODO: Use block reads to improve performance? */ - level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS) - & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK); - status1 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_1) - & ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_1_MASK); - status2 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_2) - & ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_2_MASK); - comp = wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS) - & ~wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK); - - /* over current */ - if (level_one & WM8350_OC_INT) { - u16 oc; - - oc = wm8350_reg_read(wm8350, WM8350_OVER_CURRENT_INT_STATUS); - oc &= ~wm8350_reg_read(wm8350, - WM8350_OVER_CURRENT_INT_STATUS_MASK); - - if (oc & WM8350_OC_LS_EINT) /* limit switch */ - wm8350_irq_call_handler(wm8350, WM8350_IRQ_OC_LS); - } - - /* under voltage */ - if (level_one & WM8350_UV_INT) { - u16 uv; - - uv = wm8350_reg_read(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS); - uv &= ~wm8350_reg_read(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK); - - if (uv & WM8350_UV_DC1_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC1); - if (uv & WM8350_UV_DC2_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC2); - if (uv & WM8350_UV_DC3_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC3); - if (uv & WM8350_UV_DC4_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC4); - if (uv & WM8350_UV_DC5_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC5); - if (uv & WM8350_UV_DC6_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC6); - if (uv & WM8350_UV_LDO1_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO1); - if (uv & WM8350_UV_LDO2_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO2); - if (uv & WM8350_UV_LDO3_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO3); - if (uv & WM8350_UV_LDO4_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO4); - } - - /* charger, RTC */ - if (status1) { - if (status1 & WM8350_CHG_BAT_HOT_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_BAT_HOT); - if (status1 & WM8350_CHG_BAT_COLD_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_BAT_COLD); - if (status1 & WM8350_CHG_BAT_FAIL_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_BAT_FAIL); - if (status1 & WM8350_CHG_TO_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_TO); - if (status1 & WM8350_CHG_END_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_END); - if (status1 & WM8350_CHG_START_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_START); - if (status1 & WM8350_CHG_FAST_RDY_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_FAST_RDY); - if (status1 & WM8350_CHG_VBATT_LT_3P9_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_VBATT_LT_3P9); - if (status1 & WM8350_CHG_VBATT_LT_3P1_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_VBATT_LT_3P1); - if (status1 & WM8350_CHG_VBATT_LT_2P85_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CHG_VBATT_LT_2P85); - if (status1 & WM8350_RTC_ALM_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_ALM); - if (status1 & WM8350_RTC_SEC_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_SEC); - if (status1 & WM8350_RTC_PER_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_PER); - } - - /* current sink, system, aux adc */ - if (status2) { - if (status2 & WM8350_CS1_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS1); - if (status2 & WM8350_CS2_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS2); - - if (status2 & WM8350_SYS_HYST_COMP_FAIL_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_SYS_HYST_COMP_FAIL); - if (status2 & WM8350_SYS_CHIP_GT115_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_SYS_CHIP_GT115); - if (status2 & WM8350_SYS_CHIP_GT140_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_SYS_CHIP_GT140); - if (status2 & WM8350_SYS_WDOG_TO_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_SYS_WDOG_TO); - - if (status2 & WM8350_AUXADC_DATARDY_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_AUXADC_DATARDY); - if (status2 & WM8350_AUXADC_DCOMP4_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_AUXADC_DCOMP4); - if (status2 & WM8350_AUXADC_DCOMP3_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_AUXADC_DCOMP3); - if (status2 & WM8350_AUXADC_DCOMP2_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_AUXADC_DCOMP2); - if (status2 & WM8350_AUXADC_DCOMP1_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_AUXADC_DCOMP1); - - if (status2 & WM8350_USB_LIMIT_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_USB_LIMIT); - } - - /* wake, codec, ext */ - if (comp) { - if (comp & WM8350_WKUP_OFF_STATE_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_WKUP_OFF_STATE); - if (comp & WM8350_WKUP_HIB_STATE_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_WKUP_HIB_STATE); - if (comp & WM8350_WKUP_CONV_FAULT_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_WKUP_CONV_FAULT); - if (comp & WM8350_WKUP_WDOG_RST_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_WKUP_WDOG_RST); - if (comp & WM8350_WKUP_GP_PWR_ON_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_WKUP_GP_PWR_ON); - if (comp & WM8350_WKUP_ONKEY_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_WKUP_ONKEY); - if (comp & WM8350_WKUP_GP_WAKEUP_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_WKUP_GP_WAKEUP); - - if (comp & WM8350_CODEC_JCK_DET_L_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CODEC_JCK_DET_L); - if (comp & WM8350_CODEC_JCK_DET_R_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CODEC_JCK_DET_R); - if (comp & WM8350_CODEC_MICSCD_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_CODEC_MICSCD); - if (comp & WM8350_CODEC_MICD_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_CODEC_MICD); - - if (comp & WM8350_EXT_USB_FB_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_USB_FB); - if (comp & WM8350_EXT_WALL_FB_EINT) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_EXT_WALL_FB); - if (comp & WM8350_EXT_BAT_FB_EINT) - wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_BAT_FB); - } - - if (level_one & WM8350_GP_INT) { - int i; - u16 gpio; - - gpio = wm8350_reg_read(wm8350, WM8350_GPIO_INT_STATUS); - gpio &= ~wm8350_reg_read(wm8350, - WM8350_GPIO_INT_STATUS_MASK); - - for (i = 0; i < 12; i++) { - if (gpio & (1 << i)) - wm8350_irq_call_handler(wm8350, - WM8350_IRQ_GPIO(i)); - } - } - - enable_irq(wm8350->chip_irq); -} - -static irqreturn_t wm8350_irq(int irq, void *data) -{ - struct wm8350 *wm8350 = data; - - disable_irq_nosync(irq); - schedule_work(&wm8350->irq_work); - - return IRQ_HANDLED; -} - -int wm8350_register_irq(struct wm8350 *wm8350, int irq, - void (*handler) (struct wm8350 *, int, void *), - void *data) -{ - if (irq < 0 || irq > WM8350_NUM_IRQ || !handler) - return -EINVAL; - - if (wm8350->irq[irq].handler) - return -EBUSY; - - mutex_lock(&wm8350->irq_mutex); - wm8350->irq[irq].handler = handler; - wm8350->irq[irq].data = data; - mutex_unlock(&wm8350->irq_mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_register_irq); - -int wm8350_free_irq(struct wm8350 *wm8350, int irq) -{ - if (irq < 0 || irq > WM8350_NUM_IRQ) - return -EINVAL; - - mutex_lock(&wm8350->irq_mutex); - wm8350->irq[irq].handler = NULL; - mutex_unlock(&wm8350->irq_mutex); - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_free_irq); - -int wm8350_mask_irq(struct wm8350 *wm8350, int irq) -{ - switch (irq) { - case WM8350_IRQ_CHG_BAT_HOT: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_BAT_HOT_EINT); - case WM8350_IRQ_CHG_BAT_COLD: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_BAT_COLD_EINT); - case WM8350_IRQ_CHG_BAT_FAIL: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_BAT_FAIL_EINT); - case WM8350_IRQ_CHG_TO: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_TO_EINT); - case WM8350_IRQ_CHG_END: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_END_EINT); - case WM8350_IRQ_CHG_START: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_START_EINT); - case WM8350_IRQ_CHG_FAST_RDY: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_FAST_RDY_EINT); - case WM8350_IRQ_RTC_PER: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_RTC_PER_EINT); - case WM8350_IRQ_RTC_SEC: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_RTC_SEC_EINT); - case WM8350_IRQ_RTC_ALM: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_RTC_ALM_EINT); - case WM8350_IRQ_CHG_VBATT_LT_3P9: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_VBATT_LT_3P9_EINT); - case WM8350_IRQ_CHG_VBATT_LT_3P1: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_VBATT_LT_3P1_EINT); - case WM8350_IRQ_CHG_VBATT_LT_2P85: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_VBATT_LT_2P85_EINT); - case WM8350_IRQ_CS1: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_CS1_EINT); - case WM8350_IRQ_CS2: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_CS2_EINT); - case WM8350_IRQ_USB_LIMIT: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_USB_LIMIT_EINT); - case WM8350_IRQ_AUXADC_DATARDY: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DATARDY_EINT); - case WM8350_IRQ_AUXADC_DCOMP4: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP4_EINT); - case WM8350_IRQ_AUXADC_DCOMP3: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP3_EINT); - case WM8350_IRQ_AUXADC_DCOMP2: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP2_EINT); - case WM8350_IRQ_AUXADC_DCOMP1: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP1_EINT); - case WM8350_IRQ_SYS_HYST_COMP_FAIL: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_HYST_COMP_FAIL_EINT); - case WM8350_IRQ_SYS_CHIP_GT115: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_CHIP_GT115_EINT); - case WM8350_IRQ_SYS_CHIP_GT140: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_CHIP_GT140_EINT); - case WM8350_IRQ_SYS_WDOG_TO: - return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_WDOG_TO_EINT); - case WM8350_IRQ_UV_LDO4: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO4_EINT); - case WM8350_IRQ_UV_LDO3: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO3_EINT); - case WM8350_IRQ_UV_LDO2: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO2_EINT); - case WM8350_IRQ_UV_LDO1: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO1_EINT); - case WM8350_IRQ_UV_DC6: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC6_EINT); - case WM8350_IRQ_UV_DC5: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC5_EINT); - case WM8350_IRQ_UV_DC4: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC4_EINT); - case WM8350_IRQ_UV_DC3: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC3_EINT); - case WM8350_IRQ_UV_DC2: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC2_EINT); - case WM8350_IRQ_UV_DC1: - return wm8350_set_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC1_EINT); - case WM8350_IRQ_OC_LS: - return wm8350_set_bits(wm8350, - WM8350_OVER_CURRENT_INT_STATUS_MASK, - WM8350_IM_OC_LS_EINT); - case WM8350_IRQ_EXT_USB_FB: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_EXT_USB_FB_EINT); - case WM8350_IRQ_EXT_WALL_FB: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_EXT_WALL_FB_EINT); - case WM8350_IRQ_EXT_BAT_FB: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_EXT_BAT_FB_EINT); - case WM8350_IRQ_CODEC_JCK_DET_L: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_JCK_DET_L_EINT); - case WM8350_IRQ_CODEC_JCK_DET_R: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_JCK_DET_R_EINT); - case WM8350_IRQ_CODEC_MICSCD: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_MICSCD_EINT); - case WM8350_IRQ_CODEC_MICD: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_MICD_EINT); - case WM8350_IRQ_WKUP_OFF_STATE: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_OFF_STATE_EINT); - case WM8350_IRQ_WKUP_HIB_STATE: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_HIB_STATE_EINT); - case WM8350_IRQ_WKUP_CONV_FAULT: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_CONV_FAULT_EINT); - case WM8350_IRQ_WKUP_WDOG_RST: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_OFF_STATE_EINT); - case WM8350_IRQ_WKUP_GP_PWR_ON: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_GP_PWR_ON_EINT); - case WM8350_IRQ_WKUP_ONKEY: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_ONKEY_EINT); - case WM8350_IRQ_WKUP_GP_WAKEUP: - return wm8350_set_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_GP_WAKEUP_EINT); - case WM8350_IRQ_GPIO(0): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP0_EINT); - case WM8350_IRQ_GPIO(1): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP1_EINT); - case WM8350_IRQ_GPIO(2): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP2_EINT); - case WM8350_IRQ_GPIO(3): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP3_EINT); - case WM8350_IRQ_GPIO(4): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP4_EINT); - case WM8350_IRQ_GPIO(5): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP5_EINT); - case WM8350_IRQ_GPIO(6): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP6_EINT); - case WM8350_IRQ_GPIO(7): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP7_EINT); - case WM8350_IRQ_GPIO(8): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP8_EINT); - case WM8350_IRQ_GPIO(9): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP9_EINT); - case WM8350_IRQ_GPIO(10): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP10_EINT); - case WM8350_IRQ_GPIO(11): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP11_EINT); - case WM8350_IRQ_GPIO(12): - return wm8350_set_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP12_EINT); - default: - dev_warn(wm8350->dev, "Attempting to mask unknown IRQ %d\n", - irq); - return -EINVAL; - } - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_mask_irq); - -int wm8350_unmask_irq(struct wm8350 *wm8350, int irq) -{ - switch (irq) { - case WM8350_IRQ_CHG_BAT_HOT: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_BAT_HOT_EINT); - case WM8350_IRQ_CHG_BAT_COLD: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_BAT_COLD_EINT); - case WM8350_IRQ_CHG_BAT_FAIL: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_BAT_FAIL_EINT); - case WM8350_IRQ_CHG_TO: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_TO_EINT); - case WM8350_IRQ_CHG_END: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_END_EINT); - case WM8350_IRQ_CHG_START: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_START_EINT); - case WM8350_IRQ_CHG_FAST_RDY: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_FAST_RDY_EINT); - case WM8350_IRQ_RTC_PER: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_RTC_PER_EINT); - case WM8350_IRQ_RTC_SEC: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_RTC_SEC_EINT); - case WM8350_IRQ_RTC_ALM: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_RTC_ALM_EINT); - case WM8350_IRQ_CHG_VBATT_LT_3P9: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_VBATT_LT_3P9_EINT); - case WM8350_IRQ_CHG_VBATT_LT_3P1: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_VBATT_LT_3P1_EINT); - case WM8350_IRQ_CHG_VBATT_LT_2P85: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK, - WM8350_IM_CHG_VBATT_LT_2P85_EINT); - case WM8350_IRQ_CS1: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_CS1_EINT); - case WM8350_IRQ_CS2: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_CS2_EINT); - case WM8350_IRQ_USB_LIMIT: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_USB_LIMIT_EINT); - case WM8350_IRQ_AUXADC_DATARDY: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DATARDY_EINT); - case WM8350_IRQ_AUXADC_DCOMP4: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP4_EINT); - case WM8350_IRQ_AUXADC_DCOMP3: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP3_EINT); - case WM8350_IRQ_AUXADC_DCOMP2: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP2_EINT); - case WM8350_IRQ_AUXADC_DCOMP1: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_AUXADC_DCOMP1_EINT); - case WM8350_IRQ_SYS_HYST_COMP_FAIL: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_HYST_COMP_FAIL_EINT); - case WM8350_IRQ_SYS_CHIP_GT115: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_CHIP_GT115_EINT); - case WM8350_IRQ_SYS_CHIP_GT140: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_CHIP_GT140_EINT); - case WM8350_IRQ_SYS_WDOG_TO: - return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK, - WM8350_IM_SYS_WDOG_TO_EINT); - case WM8350_IRQ_UV_LDO4: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO4_EINT); - case WM8350_IRQ_UV_LDO3: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO3_EINT); - case WM8350_IRQ_UV_LDO2: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO2_EINT); - case WM8350_IRQ_UV_LDO1: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_LDO1_EINT); - case WM8350_IRQ_UV_DC6: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC6_EINT); - case WM8350_IRQ_UV_DC5: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC5_EINT); - case WM8350_IRQ_UV_DC4: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC4_EINT); - case WM8350_IRQ_UV_DC3: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC3_EINT); - case WM8350_IRQ_UV_DC2: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC2_EINT); - case WM8350_IRQ_UV_DC1: - return wm8350_clear_bits(wm8350, - WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, - WM8350_IM_UV_DC1_EINT); - case WM8350_IRQ_OC_LS: - return wm8350_clear_bits(wm8350, - WM8350_OVER_CURRENT_INT_STATUS_MASK, - WM8350_IM_OC_LS_EINT); - case WM8350_IRQ_EXT_USB_FB: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_EXT_USB_FB_EINT); - case WM8350_IRQ_EXT_WALL_FB: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_EXT_WALL_FB_EINT); - case WM8350_IRQ_EXT_BAT_FB: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_EXT_BAT_FB_EINT); - case WM8350_IRQ_CODEC_JCK_DET_L: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_JCK_DET_L_EINT); - case WM8350_IRQ_CODEC_JCK_DET_R: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_JCK_DET_R_EINT); - case WM8350_IRQ_CODEC_MICSCD: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_MICSCD_EINT); - case WM8350_IRQ_CODEC_MICD: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_CODEC_MICD_EINT); - case WM8350_IRQ_WKUP_OFF_STATE: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_OFF_STATE_EINT); - case WM8350_IRQ_WKUP_HIB_STATE: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_HIB_STATE_EINT); - case WM8350_IRQ_WKUP_CONV_FAULT: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_CONV_FAULT_EINT); - case WM8350_IRQ_WKUP_WDOG_RST: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_OFF_STATE_EINT); - case WM8350_IRQ_WKUP_GP_PWR_ON: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_GP_PWR_ON_EINT); - case WM8350_IRQ_WKUP_ONKEY: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_ONKEY_EINT); - case WM8350_IRQ_WKUP_GP_WAKEUP: - return wm8350_clear_bits(wm8350, - WM8350_COMPARATOR_INT_STATUS_MASK, - WM8350_IM_WKUP_GP_WAKEUP_EINT); - case WM8350_IRQ_GPIO(0): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP0_EINT); - case WM8350_IRQ_GPIO(1): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP1_EINT); - case WM8350_IRQ_GPIO(2): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP2_EINT); - case WM8350_IRQ_GPIO(3): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP3_EINT); - case WM8350_IRQ_GPIO(4): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP4_EINT); - case WM8350_IRQ_GPIO(5): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP5_EINT); - case WM8350_IRQ_GPIO(6): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP6_EINT); - case WM8350_IRQ_GPIO(7): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP7_EINT); - case WM8350_IRQ_GPIO(8): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP8_EINT); - case WM8350_IRQ_GPIO(9): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP9_EINT); - case WM8350_IRQ_GPIO(10): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP10_EINT); - case WM8350_IRQ_GPIO(11): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP11_EINT); - case WM8350_IRQ_GPIO(12): - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_STATUS_MASK, - WM8350_IM_GP12_EINT); - default: - dev_warn(wm8350->dev, "Attempting to unmask unknown IRQ %d\n", - irq); - return -EINVAL; - } - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_unmask_irq); - -/* - * Cache is always host endian. - */ -static int wm8350_create_cache(struct wm8350 *wm8350, int mode) -{ - int i, ret = 0; - u16 value; - const u16 *reg_map; - - switch (mode) { -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_0 - case 0: - reg_map = wm8350_mode0_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_1 - case 1: - reg_map = wm8350_mode1_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_2 - case 2: - reg_map = wm8350_mode2_defaults; - break; -#endif -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_3 - case 3: - reg_map = wm8350_mode3_defaults; - break; -#endif - default: - dev_err(wm8350->dev, "Configuration mode %d not supported\n", - mode); - return -EINVAL; - } - - wm8350->reg_cache = - kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL); - if (wm8350->reg_cache == NULL) - return -ENOMEM; - - /* Read the initial cache state back from the device - this is - * a PMIC so the device many not be in a virgin state and we - * can't rely on the silicon values. - */ - for (i = 0; i < WM8350_MAX_REGISTER; i++) { - /* audio register range */ - if (wm8350_reg_io_map[i].readable && - (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) { - ret = wm8350->read_dev(wm8350, i, 2, (char *)&value); - if (ret < 0) { - dev_err(wm8350->dev, - "failed to read initial cache value\n"); - goto out; - } - value = be16_to_cpu(value); - value &= wm8350_reg_io_map[i].readable; - wm8350->reg_cache[i] = value; - } else - wm8350->reg_cache[i] = reg_map[i]; - } - -out: - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_create_cache); - -/* - * Register a client device. This is non-fatal since there is no need to - * fail the entire device init due to a single platform device failing. - */ -static void wm8350_client_dev_register(struct wm8350 *wm8350, - const char *name, - struct platform_device **pdev) -{ - int ret; - - *pdev = platform_device_alloc(name, -1); - if (pdev == NULL) { - dev_err(wm8350->dev, "Failed to allocate %s\n", name); - return; - } - - (*pdev)->dev.parent = wm8350->dev; - platform_set_drvdata(*pdev, wm8350); - ret = platform_device_add(*pdev); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to register %s: %d\n", name, ret); - platform_device_put(*pdev); - *pdev = NULL; - } -} - -int wm8350_device_init(struct wm8350 *wm8350, int irq, - struct wm8350_platform_data *pdata) -{ - int ret = -EINVAL; - u16 id1, id2, mask, mode; - - /* get WM8350 revision and config mode */ - wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); - wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); - - id1 = be16_to_cpu(id1); - id2 = be16_to_cpu(id2); - - if (id1 == 0x6143) { - switch ((id2 & WM8350_CHIP_REV_MASK) >> 12) { - case WM8350_REV_E: - dev_info(wm8350->dev, "Found Rev E device\n"); - wm8350->rev = WM8350_REV_E; - break; - case WM8350_REV_F: - dev_info(wm8350->dev, "Found Rev F device\n"); - wm8350->rev = WM8350_REV_F; - break; - case WM8350_REV_G: - dev_info(wm8350->dev, "Found Rev G device\n"); - wm8350->rev = WM8350_REV_G; - break; - default: - /* For safety we refuse to run on unknown hardware */ - dev_info(wm8350->dev, "Found unknown rev\n"); - ret = -ENODEV; - goto err; - } - } else { - dev_info(wm8350->dev, "Device with ID %x is not a WM8350\n", - id1); - ret = -ENODEV; - goto err; - } - - mode = id2 & WM8350_CONF_STS_MASK >> 10; - mask = id2 & WM8350_CUST_ID_MASK; - dev_info(wm8350->dev, "Config mode %d, ROM mask %d\n", mode, mask); - - ret = wm8350_create_cache(wm8350, mode); - if (ret < 0) { - printk(KERN_ERR "wm8350: failed to create register cache\n"); - return ret; - } - - if (pdata->init) { - ret = pdata->init(wm8350); - if (ret != 0) { - dev_err(wm8350->dev, "Platform init() failed: %d\n", - ret); - goto err; - } - } - - mutex_init(&wm8350->irq_mutex); - INIT_WORK(&wm8350->irq_work, wm8350_irq_worker); - if (irq != NO_IRQ) { - ret = request_irq(irq, wm8350_irq, 0, - "wm8350", wm8350); - if (ret != 0) { - dev_err(wm8350->dev, "Failed to request IRQ: %d\n", - ret); - goto err; - } - } else { - dev_err(wm8350->dev, "No IRQ configured\n"); - goto err; - } - wm8350->chip_irq = irq; - - wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0); - - wm8350_client_dev_register(wm8350, "wm8350-codec", - &(wm8350->codec.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-gpio", - &(wm8350->gpio.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-power", - &(wm8350->power.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev)); - wm8350_client_dev_register(wm8350, "wm8350-wdt", &(wm8350->wdt.pdev)); - - return 0; - -err: - kfree(wm8350->reg_cache); - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_device_init); - -void wm8350_device_exit(struct wm8350 *wm8350) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(wm8350->pmic.pdev); i++) - platform_device_unregister(wm8350->pmic.pdev[i]); - - platform_device_unregister(wm8350->wdt.pdev); - platform_device_unregister(wm8350->rtc.pdev); - platform_device_unregister(wm8350->power.pdev); - platform_device_unregister(wm8350->gpio.pdev); - platform_device_unregister(wm8350->codec.pdev); - - free_irq(wm8350->chip_irq, wm8350); - flush_work(&wm8350->irq_work); - kfree(wm8350->reg_cache); -} -EXPORT_SYMBOL_GPL(wm8350_device_exit); - -MODULE_DESCRIPTION("WM8350 AudioPlus PMIC core driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mfd/wm8350-gpio.c b/trunk/drivers/mfd/wm8350-gpio.c deleted file mode 100644 index ebf99bef392f..000000000000 --- a/trunk/drivers/mfd/wm8350-gpio.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * wm8350-core.c -- Device access for Wolfson WM8350 - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include - -#include -#include -#include - -static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir) -{ - int ret; - - wm8350_reg_unlock(wm8350); - if (dir == WM8350_GPIO_DIR_OUT) - ret = wm8350_clear_bits(wm8350, - WM8350_GPIO_CONFIGURATION_I_O, - 1 << gpio); - else - ret = wm8350_set_bits(wm8350, - WM8350_GPIO_CONFIGURATION_I_O, - 1 << gpio); - wm8350_reg_lock(wm8350); - return ret; -} - -static int gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db) -{ - if (db == WM8350_GPIO_DEBOUNCE_ON) - return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_DEBOUNCE, 1 << gpio); -} - -static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func) -{ - u16 reg; - - wm8350_reg_unlock(wm8350); - switch (gpio) { - case 0: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP0_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 0)); - break; - case 1: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP1_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 4)); - break; - case 2: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP2_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 8)); - break; - case 3: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) - & ~WM8350_GP3_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, - reg | ((func & 0xf) << 12)); - break; - case 4: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP4_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 0)); - break; - case 5: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP5_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 4)); - break; - case 6: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP6_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 8)); - break; - case 7: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) - & ~WM8350_GP7_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, - reg | ((func & 0xf) << 12)); - break; - case 8: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP8_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 0)); - break; - case 9: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP9_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 4)); - break; - case 10: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP10_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 8)); - break; - case 11: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) - & ~WM8350_GP11_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, - reg | ((func & 0xf) << 12)); - break; - case 12: - reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4) - & ~WM8350_GP12_FN_MASK; - wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4, - reg | ((func & 0xf) << 0)); - break; - default: - wm8350_reg_lock(wm8350); - return -EINVAL; - } - - wm8350_reg_lock(wm8350); - return 0; -} - -static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up) -{ - if (up) - return wm8350_set_bits(wm8350, - WM8350_GPIO_PIN_PULL_UP_CONTROL, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_PIN_PULL_UP_CONTROL, - 1 << gpio); -} - -static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down) -{ - if (down) - return wm8350_set_bits(wm8350, - WM8350_GPIO_PULL_DOWN_CONTROL, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_PULL_DOWN_CONTROL, - 1 << gpio); -} - -static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol) -{ - if (pol == WM8350_GPIO_ACTIVE_HIGH) - return wm8350_set_bits(wm8350, - WM8350_GPIO_PIN_POLARITY_TYPE, - 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_PIN_POLARITY_TYPE, - 1 << gpio); -} - -static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert) -{ - if (invert == WM8350_GPIO_INVERT_ON) - return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio); - else - return wm8350_clear_bits(wm8350, - WM8350_GPIO_INT_MODE, 1 << gpio); -} - -int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func, - int pol, int pull, int invert, int debounce) -{ - /* make sure we never pull up and down at the same time */ - if (pull == WM8350_GPIO_PULL_NONE) { - if (gpio_set_pull_up(wm8350, gpio, 0)) - goto err; - if (gpio_set_pull_down(wm8350, gpio, 0)) - goto err; - } else if (pull == WM8350_GPIO_PULL_UP) { - if (gpio_set_pull_down(wm8350, gpio, 0)) - goto err; - if (gpio_set_pull_up(wm8350, gpio, 1)) - goto err; - } else if (pull == WM8350_GPIO_PULL_DOWN) { - if (gpio_set_pull_up(wm8350, gpio, 0)) - goto err; - if (gpio_set_pull_down(wm8350, gpio, 1)) - goto err; - } - - if (gpio_set_invert(wm8350, gpio, invert)) - goto err; - if (gpio_set_polarity(wm8350, gpio, pol)) - goto err; - if (gpio_set_debounce(wm8350, gpio, debounce)) - goto err; - if (gpio_set_dir(wm8350, gpio, dir)) - goto err; - return gpio_set_func(wm8350, gpio, func); - -err: - return -EIO; -} -EXPORT_SYMBOL_GPL(wm8350_gpio_config); diff --git a/trunk/drivers/mfd/wm8350-i2c.c b/trunk/drivers/mfd/wm8350-i2c.c deleted file mode 100644 index 8dfe21bb3bd1..000000000000 --- a/trunk/drivers/mfd/wm8350-i2c.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * wm8350-i2c.c -- Generic I2C driver for Wolfson WM8350 PMIC - * - * This driver defines and configures the WM8350 for the Freescale i.MX32ADS. - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include - -static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, - int bytes, void *dest) -{ - int ret; - - ret = i2c_master_send(wm8350->i2c_client, ®, 1); - if (ret < 0) - return ret; - return i2c_master_recv(wm8350->i2c_client, dest, bytes); -} - -static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg, - int bytes, void *src) -{ - /* we add 1 byte for device register */ - u8 msg[(WM8350_MAX_REGISTER << 1) + 1]; - - if (bytes > ((WM8350_MAX_REGISTER << 1) + 1)) - return -EINVAL; - - msg[0] = reg; - memcpy(&msg[1], src, bytes); - return i2c_master_send(wm8350->i2c_client, msg, bytes + 1); -} - -static int wm8350_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8350 *wm8350; - int ret = 0; - - wm8350 = kzalloc(sizeof(struct wm8350), GFP_KERNEL); - if (wm8350 == NULL) { - kfree(i2c); - return -ENOMEM; - } - - i2c_set_clientdata(i2c, wm8350); - wm8350->dev = &i2c->dev; - wm8350->i2c_client = i2c; - wm8350->read_dev = wm8350_i2c_read_device; - wm8350->write_dev = wm8350_i2c_write_device; - - ret = wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data); - if (ret < 0) - goto err; - - return ret; - -err: - kfree(wm8350); - return ret; -} - -static int wm8350_i2c_remove(struct i2c_client *i2c) -{ - struct wm8350 *wm8350 = i2c_get_clientdata(i2c); - - wm8350_device_exit(wm8350); - kfree(wm8350); - - return 0; -} - -static const struct i2c_device_id wm8350_i2c_id[] = { - { "wm8350", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id); - - -static struct i2c_driver wm8350_i2c_driver = { - .driver = { - .name = "wm8350", - .owner = THIS_MODULE, - }, - .probe = wm8350_i2c_probe, - .remove = wm8350_i2c_remove, - .id_table = wm8350_i2c_id, -}; - -static int __init wm8350_i2c_init(void) -{ - return i2c_add_driver(&wm8350_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(wm8350_i2c_init); - -static void __exit wm8350_i2c_exit(void) -{ - i2c_del_driver(&wm8350_i2c_driver); -} -module_exit(wm8350_i2c_exit); - -MODULE_DESCRIPTION("I2C support for the WM8350 AudioPlus PMIC"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mfd/wm8350-regmap.c b/trunk/drivers/mfd/wm8350-regmap.c deleted file mode 100644 index 974678db22cd..000000000000 --- a/trunk/drivers/mfd/wm8350-regmap.c +++ /dev/null @@ -1,1347 +0,0 @@ -/* - * wm8350-regmap.c -- Wolfson Microelectronics WM8350 register map - * - * This file splits out the tables describing the defaults and access - * status of the WM8350 registers since they are rather large. - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_0 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode0_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1002, /* R3 - System Control 1 */ - 0x0004, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0FFC, /* R134 - GPIO Configuration (i/o) */ - 0x0FFC, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0013, /* R140 - GPIO Function Select 1 */ - 0x0000, /* R141 - GPIO Function Select 2 */ - 0x0000, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0000, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0000, /* R186 - DCDC3 Control */ - 0x0000, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0000, /* R189 - DCDC4 Control */ - 0x0000, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0000, /* R195 - DCDC6 Control */ - 0x0000, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001B, /* R203 - LDO2 Control */ - 0x0000, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001B, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001B, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_1 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode1_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1002, /* R3 - System Control 1 */ - 0x0014, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x00FB, /* R134 - GPIO Configuration (i/o) */ - 0x04FE, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0312, /* R140 - GPIO Function Select 1 */ - 0x1003, /* R141 - GPIO Function Select 2 */ - 0x1331, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x0062, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x0026, /* R186 - DCDC3 Control */ - 0x0400, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0062, /* R189 - DCDC4 Control */ - 0x0400, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0800, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x0006, /* R200 - LDO1 Control */ - 0x0400, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0006, /* R203 - LDO2 Control */ - 0x0400, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001B, /* R206 - LDO3 Control */ - 0x0000, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001B, /* R209 - LDO4 Control */ - 0x0000, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_2 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode2_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1002, /* R3 - System Control 1 */ - 0x0014, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x08FB, /* R134 - GPIO Configuration (i/o) */ - 0x0CFE, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0312, /* R140 - GPIO Function Select 1 */ - 0x0003, /* R141 - GPIO Function Select 2 */ - 0x2331, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x002E, /* R186 - DCDC3 Control */ - 0x0800, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x000E, /* R189 - DCDC4 Control */ - 0x0800, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0C00, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001A, /* R200 - LDO1 Control */ - 0x0800, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x0010, /* R203 - LDO2 Control */ - 0x0800, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x000A, /* R206 - LDO3 Control */ - 0x0C00, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001A, /* R209 - LDO4 Control */ - 0x0800, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -#ifdef CONFIG_MFD_WM8350_CONFIG_MODE_3 - -#undef WM8350_HAVE_CONFIG_MODE -#define WM8350_HAVE_CONFIG_MODE - -const u16 wm8350_mode3_defaults[] = { - 0x17FF, /* R0 - Reset/ID */ - 0x1000, /* R1 - ID */ - 0x0000, /* R2 */ - 0x1000, /* R3 - System Control 1 */ - 0x0004, /* R4 - System Control 2 */ - 0x0000, /* R5 - System Hibernate */ - 0x8A00, /* R6 - Interface Control */ - 0x0000, /* R7 */ - 0x8000, /* R8 - Power mgmt (1) */ - 0x0000, /* R9 - Power mgmt (2) */ - 0x0000, /* R10 - Power mgmt (3) */ - 0x2000, /* R11 - Power mgmt (4) */ - 0x0E00, /* R12 - Power mgmt (5) */ - 0x0000, /* R13 - Power mgmt (6) */ - 0x0000, /* R14 - Power mgmt (7) */ - 0x0000, /* R15 */ - 0x0000, /* R16 - RTC Seconds/Minutes */ - 0x0100, /* R17 - RTC Hours/Day */ - 0x0101, /* R18 - RTC Date/Month */ - 0x1400, /* R19 - RTC Year */ - 0x0000, /* R20 - Alarm Seconds/Minutes */ - 0x0000, /* R21 - Alarm Hours/Day */ - 0x0000, /* R22 - Alarm Date/Month */ - 0x0320, /* R23 - RTC Time Control */ - 0x0000, /* R24 - System Interrupts */ - 0x0000, /* R25 - Interrupt Status 1 */ - 0x0000, /* R26 - Interrupt Status 2 */ - 0x0000, /* R27 - Power Up Interrupt Status */ - 0x0000, /* R28 - Under Voltage Interrupt status */ - 0x0000, /* R29 - Over Current Interrupt status */ - 0x0000, /* R30 - GPIO Interrupt Status */ - 0x0000, /* R31 - Comparator Interrupt Status */ - 0x3FFF, /* R32 - System Interrupts Mask */ - 0x0000, /* R33 - Interrupt Status 1 Mask */ - 0x0000, /* R34 - Interrupt Status 2 Mask */ - 0x0000, /* R35 - Power Up Interrupt Status Mask */ - 0x0000, /* R36 - Under Voltage Interrupt status Mask */ - 0x0000, /* R37 - Over Current Interrupt status Mask */ - 0x0000, /* R38 - GPIO Interrupt Status Mask */ - 0x0000, /* R39 - Comparator Interrupt Status Mask */ - 0x0040, /* R40 - Clock Control 1 */ - 0x0000, /* R41 - Clock Control 2 */ - 0x3B00, /* R42 - FLL Control 1 */ - 0x7086, /* R43 - FLL Control 2 */ - 0xC226, /* R44 - FLL Control 3 */ - 0x0000, /* R45 - FLL Control 4 */ - 0x0000, /* R46 */ - 0x0000, /* R47 */ - 0x0000, /* R48 - DAC Control */ - 0x0000, /* R49 */ - 0x00C0, /* R50 - DAC Digital Volume L */ - 0x00C0, /* R51 - DAC Digital Volume R */ - 0x0000, /* R52 */ - 0x0040, /* R53 - DAC LR Rate */ - 0x0000, /* R54 - DAC Clock Control */ - 0x0000, /* R55 */ - 0x0000, /* R56 */ - 0x0000, /* R57 */ - 0x4000, /* R58 - DAC Mute */ - 0x0000, /* R59 - DAC Mute Volume */ - 0x0000, /* R60 - DAC Side */ - 0x0000, /* R61 */ - 0x0000, /* R62 */ - 0x0000, /* R63 */ - 0x8000, /* R64 - ADC Control */ - 0x0000, /* R65 */ - 0x00C0, /* R66 - ADC Digital Volume L */ - 0x00C0, /* R67 - ADC Digital Volume R */ - 0x0000, /* R68 - ADC Divider */ - 0x0000, /* R69 */ - 0x0040, /* R70 - ADC LR Rate */ - 0x0000, /* R71 */ - 0x0303, /* R72 - Input Control */ - 0x0000, /* R73 - IN3 Input Control */ - 0x0000, /* R74 - Mic Bias Control */ - 0x0000, /* R75 */ - 0x0000, /* R76 - Output Control */ - 0x0000, /* R77 - Jack Detect */ - 0x0000, /* R78 - Anti Pop Control */ - 0x0000, /* R79 */ - 0x0040, /* R80 - Left Input Volume */ - 0x0040, /* R81 - Right Input Volume */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0000, /* R87 */ - 0x0800, /* R88 - Left Mixer Control */ - 0x1000, /* R89 - Right Mixer Control */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 - OUT3 Mixer Control */ - 0x0000, /* R93 - OUT4 Mixer Control */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Output Left Mixer Volume */ - 0x0000, /* R97 - Output Right Mixer Volume */ - 0x0000, /* R98 - Input Mixer Volume L */ - 0x0000, /* R99 - Input Mixer Volume R */ - 0x0000, /* R100 - Input Mixer Volume */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x00E4, /* R104 - LOUT1 Volume */ - 0x00E4, /* R105 - ROUT1 Volume */ - 0x00E4, /* R106 - LOUT2 Volume */ - 0x02E4, /* R107 - ROUT2 Volume */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 - BEEP Volume */ - 0x0A00, /* R112 - AI Formating */ - 0x0000, /* R113 - ADC DAC COMP */ - 0x0020, /* R114 - AI ADC Control */ - 0x0020, /* R115 - AI DAC Control */ - 0x0000, /* R116 - AIF Test */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x1FFF, /* R128 - GPIO Debounce */ - 0x0000, /* R129 - GPIO Pin pull up Control */ - 0x03FC, /* R130 - GPIO Pull down Control */ - 0x0000, /* R131 - GPIO Interrupt Mode */ - 0x0000, /* R132 */ - 0x0000, /* R133 - GPIO Control */ - 0x0A7B, /* R134 - GPIO Configuration (i/o) */ - 0x06FE, /* R135 - GPIO Pin Polarity / Type */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x1312, /* R140 - GPIO Function Select 1 */ - 0x1030, /* R141 - GPIO Function Select 2 */ - 0x2231, /* R142 - GPIO Function Select 3 */ - 0x0003, /* R143 - GPIO Function Select 4 */ - 0x0000, /* R144 - Digitiser Control (1) */ - 0x0002, /* R145 - Digitiser Control (2) */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x7000, /* R152 - AUX1 Readback */ - 0x7000, /* R153 - AUX2 Readback */ - 0x7000, /* R154 - AUX3 Readback */ - 0x7000, /* R155 - AUX4 Readback */ - 0x0000, /* R156 - USB Voltage Readback */ - 0x0000, /* R157 - LINE Voltage Readback */ - 0x0000, /* R158 - BATT Voltage Readback */ - 0x0000, /* R159 - Chip Temp Readback */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 - Generic Comparator Control */ - 0x0000, /* R164 - Generic comparator 1 */ - 0x0000, /* R165 - Generic comparator 2 */ - 0x0000, /* R166 - Generic comparator 3 */ - 0x0000, /* R167 - Generic comparator 4 */ - 0xA00F, /* R168 - Battery Charger Control 1 */ - 0x0B06, /* R169 - Battery Charger Control 2 */ - 0x0000, /* R170 - Battery Charger Control 3 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Current Sink Driver A */ - 0x0000, /* R173 - CSA Flash control */ - 0x0000, /* R174 - Current Sink Driver B */ - 0x0000, /* R175 - CSB Flash control */ - 0x0000, /* R176 - DCDC/LDO requested */ - 0x002D, /* R177 - DCDC Active options */ - 0x0000, /* R178 - DCDC Sleep options */ - 0x0025, /* R179 - Power-check comparator */ - 0x000E, /* R180 - DCDC1 Control */ - 0x0400, /* R181 - DCDC1 Timeouts */ - 0x1006, /* R182 - DCDC1 Low Power */ - 0x0018, /* R183 - DCDC2 Control */ - 0x0000, /* R184 - DCDC2 Timeouts */ - 0x0000, /* R185 */ - 0x000E, /* R186 - DCDC3 Control */ - 0x0400, /* R187 - DCDC3 Timeouts */ - 0x0006, /* R188 - DCDC3 Low Power */ - 0x0026, /* R189 - DCDC4 Control */ - 0x0400, /* R190 - DCDC4 Timeouts */ - 0x0006, /* R191 - DCDC4 Low Power */ - 0x0008, /* R192 - DCDC5 Control */ - 0x0000, /* R193 - DCDC5 Timeouts */ - 0x0000, /* R194 */ - 0x0026, /* R195 - DCDC6 Control */ - 0x0400, /* R196 - DCDC6 Timeouts */ - 0x0006, /* R197 - DCDC6 Low Power */ - 0x0000, /* R198 */ - 0x0003, /* R199 - Limit Switch Control */ - 0x001C, /* R200 - LDO1 Control */ - 0x0000, /* R201 - LDO1 Timeouts */ - 0x001C, /* R202 - LDO1 Low Power */ - 0x001C, /* R203 - LDO2 Control */ - 0x0400, /* R204 - LDO2 Timeouts */ - 0x001C, /* R205 - LDO2 Low Power */ - 0x001C, /* R206 - LDO3 Control */ - 0x0400, /* R207 - LDO3 Timeouts */ - 0x001C, /* R208 - LDO3 Low Power */ - 0x001F, /* R209 - LDO4 Control */ - 0x0400, /* R210 - LDO4 Timeouts */ - 0x001C, /* R211 - LDO4 Low Power */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 - VCC_FAULT Masks */ - 0x001F, /* R216 - Main Bandgap Control */ - 0x0000, /* R217 - OSC Control */ - 0x9000, /* R218 - RTC Tick Control */ - 0x0000, /* R219 */ - 0x4000, /* R220 - RAM BIST 1 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 - DCDC/LDO status */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0xE000, /* R230 - GPIO Pin Status */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ -}; -#endif - -/* The register defaults for the config mode used must be compiled in but - * due to the impact on kernel size it is possible to disable - */ -#ifndef WM8350_HAVE_CONFIG_MODE -#warning No WM8350 config modes supported - select at least one of the -#warning MFD_WM8350_CONFIG_MODE_n options from the board driver. -#endif - -/* - * Access masks. - */ - -const struct wm8350_reg_access wm8350_reg_io_map[] = { - /* read write volatile */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R0 - Reset/ID */ - { 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */ - { 0x0000, 0x0000, 0x0000 }, /* R2 */ - { 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */ - { 0xFCF7, 0xFCF7, 0xF800 }, /* R4 - System Control 2 */ - { 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */ - { 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */ - { 0x0000, 0x0000, 0x0000 }, /* R7 */ - { 0xE537, 0xE537, 0xFFFF }, /* R8 - Power mgmt (1) */ - { 0x0FF3, 0x0FF3, 0xFFFF }, /* R9 - Power mgmt (2) */ - { 0x008F, 0x008F, 0xFFFF }, /* R10 - Power mgmt (3) */ - { 0x6D3C, 0x6D3C, 0xFFFF }, /* R11 - Power mgmt (4) */ - { 0x1F8F, 0x1F8F, 0xFFFF }, /* R12 - Power mgmt (5) */ - { 0x8F3F, 0x8F3F, 0xFFFF }, /* R13 - Power mgmt (6) */ - { 0x0003, 0x0003, 0xFFFF }, /* R14 - Power mgmt (7) */ - { 0x0000, 0x0000, 0x0000 }, /* R15 */ - { 0x7F7F, 0x7F7F, 0xFFFF }, /* R16 - RTC Seconds/Minutes */ - { 0x073F, 0x073F, 0xFFFF }, /* R17 - RTC Hours/Day */ - { 0x1F3F, 0x1F3F, 0xFFFF }, /* R18 - RTC Date/Month */ - { 0x3FFF, 0x00FF, 0xFFFF }, /* R19 - RTC Year */ - { 0x7F7F, 0x7F7F, 0x0000 }, /* R20 - Alarm Seconds/Minutes */ - { 0x0F3F, 0x0F3F, 0x0000 }, /* R21 - Alarm Hours/Day */ - { 0x1F3F, 0x1F3F, 0x0000 }, /* R22 - Alarm Date/Month */ - { 0xEF7F, 0xEA7F, 0xFFFF }, /* R23 - RTC Time Control */ - { 0x3BFF, 0x0000, 0xFFFF }, /* R24 - System Interrupts */ - { 0xFEE7, 0x0000, 0xFFFF }, /* R25 - Interrupt Status 1 */ - { 0x35FF, 0x0000, 0xFFFF }, /* R26 - Interrupt Status 2 */ - { 0x0F3F, 0x0000, 0xFFFF }, /* R27 - Power Up Interrupt Status */ - { 0x0F3F, 0x0000, 0xFFFF }, /* R28 - Under Voltage Interrupt status */ - { 0x8000, 0x0000, 0xFFFF }, /* R29 - Over Current Interrupt status */ - { 0x1FFF, 0x0000, 0xFFFF }, /* R30 - GPIO Interrupt Status */ - { 0xEF7F, 0x0000, 0xFFFF }, /* R31 - Comparator Interrupt Status */ - { 0x3FFF, 0x3FFF, 0x0000 }, /* R32 - System Interrupts Mask */ - { 0xFEE7, 0xFEE7, 0x0000 }, /* R33 - Interrupt Status 1 Mask */ - { 0xF5FF, 0xF5FF, 0x0000 }, /* R34 - Interrupt Status 2 Mask */ - { 0x0F3F, 0x0F3F, 0x0000 }, /* R35 - Power Up Interrupt Status Mask */ - { 0x0F3F, 0x0F3F, 0x0000 }, /* R36 - Under Voltage Int status Mask */ - { 0x8000, 0x8000, 0x0000 }, /* R37 - Over Current Int status Mask */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R38 - GPIO Interrupt Status Mask */ - { 0xEF7F, 0xEF7F, 0x0000 }, /* R39 - Comparator IntStatus Mask */ - { 0xC9F7, 0xC9F7, 0xFFFF }, /* R40 - Clock Control 1 */ - { 0x8001, 0x8001, 0x0000 }, /* R41 - Clock Control 2 */ - { 0xFFF7, 0xFFF7, 0xFFFF }, /* R42 - FLL Control 1 */ - { 0xFBFF, 0xFBFF, 0x0000 }, /* R43 - FLL Control 2 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R44 - FLL Control 3 */ - { 0x0033, 0x0033, 0x0000 }, /* R45 - FLL Control 4 */ - { 0x0000, 0x0000, 0x0000 }, /* R46 */ - { 0x0000, 0x0000, 0x0000 }, /* R47 */ - { 0x3033, 0x3033, 0x0000 }, /* R48 - DAC Control */ - { 0x0000, 0x0000, 0x0000 }, /* R49 */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R50 - DAC Digital Volume L */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R51 - DAC Digital Volume R */ - { 0x0000, 0x0000, 0x0000 }, /* R52 */ - { 0x0FFF, 0x0FFF, 0xFFFF }, /* R53 - DAC LR Rate */ - { 0x0017, 0x0017, 0x0000 }, /* R54 - DAC Clock Control */ - { 0x0000, 0x0000, 0x0000 }, /* R55 */ - { 0x0000, 0x0000, 0x0000 }, /* R56 */ - { 0x0000, 0x0000, 0x0000 }, /* R57 */ - { 0x4000, 0x4000, 0x0000 }, /* R58 - DAC Mute */ - { 0x7000, 0x7000, 0x0000 }, /* R59 - DAC Mute Volume */ - { 0x3C00, 0x3C00, 0x0000 }, /* R60 - DAC Side */ - { 0x0000, 0x0000, 0x0000 }, /* R61 */ - { 0x0000, 0x0000, 0x0000 }, /* R62 */ - { 0x0000, 0x0000, 0x0000 }, /* R63 */ - { 0x8303, 0x8303, 0xFFFF }, /* R64 - ADC Control */ - { 0x0000, 0x0000, 0x0000 }, /* R65 */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R66 - ADC Digital Volume L */ - { 0x81FF, 0x81FF, 0xFFFF }, /* R67 - ADC Digital Volume R */ - { 0x0FFF, 0x0FFF, 0x0000 }, /* R68 - ADC Divider */ - { 0x0000, 0x0000, 0x0000 }, /* R69 */ - { 0x0FFF, 0x0FFF, 0xFFFF }, /* R70 - ADC LR Rate */ - { 0x0000, 0x0000, 0x0000 }, /* R71 */ - { 0x0707, 0x0707, 0xFFFF }, /* R72 - Input Control */ - { 0xC0C0, 0xC0C0, 0xFFFF }, /* R73 - IN3 Input Control */ - { 0xC09F, 0xC09F, 0xFFFF }, /* R74 - Mic Bias Control */ - { 0x0000, 0x0000, 0x0000 }, /* R75 */ - { 0x0F15, 0x0F15, 0xFFFF }, /* R76 - Output Control */ - { 0xC000, 0xC000, 0xFFFF }, /* R77 - Jack Detect */ - { 0x03FF, 0x03FF, 0x0000 }, /* R78 - Anti Pop Control */ - { 0x0000, 0x0000, 0x0000 }, /* R79 */ - { 0xE1FC, 0xE1FC, 0x8000 }, /* R80 - Left Input Volume */ - { 0xE1FC, 0xE1FC, 0x8000 }, /* R81 - Right Input Volume */ - { 0x0000, 0x0000, 0x0000 }, /* R82 */ - { 0x0000, 0x0000, 0x0000 }, /* R83 */ - { 0x0000, 0x0000, 0x0000 }, /* R84 */ - { 0x0000, 0x0000, 0x0000 }, /* R85 */ - { 0x0000, 0x0000, 0x0000 }, /* R86 */ - { 0x0000, 0x0000, 0x0000 }, /* R87 */ - { 0x9807, 0x9807, 0xFFFF }, /* R88 - Left Mixer Control */ - { 0x980B, 0x980B, 0xFFFF }, /* R89 - Right Mixer Control */ - { 0x0000, 0x0000, 0x0000 }, /* R90 */ - { 0x0000, 0x0000, 0x0000 }, /* R91 */ - { 0x8909, 0x8909, 0xFFFF }, /* R92 - OUT3 Mixer Control */ - { 0x9E07, 0x9E07, 0xFFFF }, /* R93 - OUT4 Mixer Control */ - { 0x0000, 0x0000, 0x0000 }, /* R94 */ - { 0x0000, 0x0000, 0x0000 }, /* R95 */ - { 0x0EEE, 0x0EEE, 0x0000 }, /* R96 - Output Left Mixer Volume */ - { 0xE0EE, 0xE0EE, 0x0000 }, /* R97 - Output Right Mixer Volume */ - { 0x0E0F, 0x0E0F, 0x0000 }, /* R98 - Input Mixer Volume L */ - { 0xE0E1, 0xE0E1, 0x0000 }, /* R99 - Input Mixer Volume R */ - { 0x800E, 0x800E, 0x0000 }, /* R100 - Input Mixer Volume */ - { 0x0000, 0x0000, 0x0000 }, /* R101 */ - { 0x0000, 0x0000, 0x0000 }, /* R102 */ - { 0x0000, 0x0000, 0x0000 }, /* R103 */ - { 0xE1FC, 0xE1FC, 0xFFFF }, /* R104 - LOUT1 Volume */ - { 0xE1FC, 0xE1FC, 0xFFFF }, /* R105 - ROUT1 Volume */ - { 0xE1FC, 0xE1FC, 0xFFFF }, /* R106 - LOUT2 Volume */ - { 0xE7FC, 0xE7FC, 0xFFFF }, /* R107 - ROUT2 Volume */ - { 0x0000, 0x0000, 0x0000 }, /* R108 */ - { 0x0000, 0x0000, 0x0000 }, /* R109 */ - { 0x0000, 0x0000, 0x0000 }, /* R110 */ - { 0x80E0, 0x80E0, 0xFFFF }, /* R111 - BEEP Volume */ - { 0xBF00, 0xBF00, 0x0000 }, /* R112 - AI Formating */ - { 0x00F1, 0x00F1, 0x0000 }, /* R113 - ADC DAC COMP */ - { 0x00F8, 0x00F8, 0x0000 }, /* R114 - AI ADC Control */ - { 0x40FB, 0x40FB, 0x0000 }, /* R115 - AI DAC Control */ - { 0x7C30, 0x7C30, 0x0000 }, /* R116 - AIF Test */ - { 0x0000, 0x0000, 0x0000 }, /* R117 */ - { 0x0000, 0x0000, 0x0000 }, /* R118 */ - { 0x0000, 0x0000, 0x0000 }, /* R119 */ - { 0x0000, 0x0000, 0x0000 }, /* R120 */ - { 0x0000, 0x0000, 0x0000 }, /* R121 */ - { 0x0000, 0x0000, 0x0000 }, /* R122 */ - { 0x0000, 0x0000, 0x0000 }, /* R123 */ - { 0x0000, 0x0000, 0x0000 }, /* R124 */ - { 0x0000, 0x0000, 0x0000 }, /* R125 */ - { 0x0000, 0x0000, 0x0000 }, /* R126 */ - { 0x0000, 0x0000, 0x0000 }, /* R127 */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R128 - GPIO Debounce */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R129 - GPIO Pin pull up Control */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R130 - GPIO Pull down Control */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R131 - GPIO Interrupt Mode */ - { 0x0000, 0x0000, 0x0000 }, /* R132 */ - { 0x00C0, 0x00C0, 0x0000 }, /* R133 - GPIO Control */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R134 - GPIO Configuration (i/o) */ - { 0x1FFF, 0x1FFF, 0x0000 }, /* R135 - GPIO Pin Polarity / Type */ - { 0x0000, 0x0000, 0x0000 }, /* R136 */ - { 0x0000, 0x0000, 0x0000 }, /* R137 */ - { 0x0000, 0x0000, 0x0000 }, /* R138 */ - { 0x0000, 0x0000, 0x0000 }, /* R139 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R140 - GPIO Function Select 1 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R141 - GPIO Function Select 2 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R142 - GPIO Function Select 3 */ - { 0x000F, 0x000F, 0x0000 }, /* R143 - GPIO Function Select 4 */ - { 0xF0FF, 0xF0FF, 0xA000 }, /* R144 - Digitiser Control (1) */ - { 0x3707, 0x3707, 0x0000 }, /* R145 - Digitiser Control (2) */ - { 0x0000, 0x0000, 0x0000 }, /* R146 */ - { 0x0000, 0x0000, 0x0000 }, /* R147 */ - { 0x0000, 0x0000, 0x0000 }, /* R148 */ - { 0x0000, 0x0000, 0x0000 }, /* R149 */ - { 0x0000, 0x0000, 0x0000 }, /* R150 */ - { 0x0000, 0x0000, 0x0000 }, /* R151 */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R152 - AUX1 Readback */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R153 - AUX2 Readback */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R154 - AUX3 Readback */ - { 0x7FFF, 0x7000, 0xFFFF }, /* R155 - AUX4 Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R156 - USB Voltage Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R157 - LINE Voltage Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R158 - BATT Voltage Readback */ - { 0x0FFF, 0x0000, 0xFFFF }, /* R159 - Chip Temp Readback */ - { 0x0000, 0x0000, 0x0000 }, /* R160 */ - { 0x0000, 0x0000, 0x0000 }, /* R161 */ - { 0x0000, 0x0000, 0x0000 }, /* R162 */ - { 0x000F, 0x000F, 0x0000 }, /* R163 - Generic Comparator Control */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R164 - Generic comparator 1 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R165 - Generic comparator 2 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R166 - Generic comparator 3 */ - { 0xFFFF, 0xFFFF, 0x0000 }, /* R167 - Generic comparator 4 */ - { 0xBFFF, 0xBFFF, 0x8000 }, /* R168 - Battery Charger Control 1 */ - { 0xFFFF, 0x4FFF, 0xB000 }, /* R169 - Battery Charger Control 2 */ - { 0x007F, 0x007F, 0x0000 }, /* R170 - Battery Charger Control 3 */ - { 0x0000, 0x0000, 0x0000 }, /* R171 */ - { 0x903F, 0x903F, 0xFFFF }, /* R172 - Current Sink Driver A */ - { 0xE333, 0xE333, 0xFFFF }, /* R173 - CSA Flash control */ - { 0x903F, 0x903F, 0xFFFF }, /* R174 - Current Sink Driver B */ - { 0xE333, 0xE333, 0xFFFF }, /* R175 - CSB Flash control */ - { 0x8F3F, 0x8F3F, 0xFFFF }, /* R176 - DCDC/LDO requested */ - { 0x332D, 0x332D, 0x0000 }, /* R177 - DCDC Active options */ - { 0x002D, 0x002D, 0x0000 }, /* R178 - DCDC Sleep options */ - { 0x5177, 0x5177, 0x8000 }, /* R179 - Power-check comparator */ - { 0x047F, 0x047F, 0x0000 }, /* R180 - DCDC1 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R181 - DCDC1 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R182 - DCDC1 Low Power */ - { 0x535B, 0x535B, 0x0000 }, /* R183 - DCDC2 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R184 - DCDC2 Timeouts */ - { 0x0000, 0x0000, 0x0000 }, /* R185 */ - { 0x047F, 0x047F, 0x0000 }, /* R186 - DCDC3 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R187 - DCDC3 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R188 - DCDC3 Low Power */ - { 0x047F, 0x047F, 0x0000 }, /* R189 - DCDC4 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R190 - DCDC4 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R191 - DCDC4 Low Power */ - { 0x535B, 0x535B, 0x0000 }, /* R192 - DCDC5 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R193 - DCDC5 Timeouts */ - { 0x0000, 0x0000, 0x0000 }, /* R194 */ - { 0x047F, 0x047F, 0x0000 }, /* R195 - DCDC6 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R196 - DCDC6 Timeouts */ - { 0x737F, 0x737F, 0x0000 }, /* R197 - DCDC6 Low Power */ - { 0x0000, 0x0000, 0x0000 }, /* R198 */ - { 0xFFD3, 0xFFD3, 0x0000 }, /* R199 - Limit Switch Control */ - { 0x441F, 0x441F, 0x0000 }, /* R200 - LDO1 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R201 - LDO1 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R202 - LDO1 Low Power */ - { 0x441F, 0x441F, 0x0000 }, /* R203 - LDO2 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R204 - LDO2 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R205 - LDO2 Low Power */ - { 0x441F, 0x441F, 0x0000 }, /* R206 - LDO3 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R207 - LDO3 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R208 - LDO3 Low Power */ - { 0x441F, 0x441F, 0x0000 }, /* R209 - LDO4 Control */ - { 0xFFC0, 0xFFC0, 0x0000 }, /* R210 - LDO4 Timeouts */ - { 0x331F, 0x331F, 0x0000 }, /* R211 - LDO4 Low Power */ - { 0x0000, 0x0000, 0x0000 }, /* R212 */ - { 0x0000, 0x0000, 0x0000 }, /* R213 */ - { 0x0000, 0x0000, 0x0000 }, /* R214 */ - { 0x8F3F, 0x8F3F, 0x0000 }, /* R215 - VCC_FAULT Masks */ - { 0xFF3F, 0xE03F, 0x0000 }, /* R216 - Main Bandgap Control */ - { 0xEF2F, 0xE02F, 0x0000 }, /* R217 - OSC Control */ - { 0xF3FF, 0xB3FF, 0xc000 }, /* R218 - RTC Tick Control */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R219 */ - { 0x09FF, 0x01FF, 0x0000 }, /* R220 - RAM BIST 1 */ - { 0x0000, 0x0000, 0x0000 }, /* R221 */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R222 */ - { 0xFFFF, 0xFFFF, 0xFFFF }, /* R223 */ - { 0x0000, 0x0000, 0x0000 }, /* R224 */ - { 0x8F3F, 0x0000, 0xFFFF }, /* R225 - DCDC/LDO status */ - { 0x0000, 0x0000, 0x0000 }, /* R226 */ - { 0x0000, 0x0000, 0xFFFF }, /* R227 */ - { 0x0000, 0x0000, 0x0000 }, /* R228 */ - { 0x0000, 0x0000, 0x0000 }, /* R229 */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R230 - GPIO Pin Status */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R231 */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R232 */ - { 0xFFFF, 0x1FFF, 0xFFFF }, /* R233 */ - { 0x0000, 0x0000, 0x0000 }, /* R234 */ - { 0x0000, 0x0000, 0x0000 }, /* R235 */ - { 0x0000, 0x0000, 0x0000 }, /* R236 */ - { 0x0000, 0x0000, 0x0000 }, /* R237 */ - { 0x0000, 0x0000, 0x0000 }, /* R238 */ - { 0x0000, 0x0000, 0x0000 }, /* R239 */ - { 0x0000, 0x0000, 0x0000 }, /* R240 */ - { 0x0000, 0x0000, 0x0000 }, /* R241 */ - { 0x0000, 0x0000, 0x0000 }, /* R242 */ - { 0x0000, 0x0000, 0x0000 }, /* R243 */ - { 0x0000, 0x0000, 0x0000 }, /* R244 */ - { 0x0000, 0x0000, 0x0000 }, /* R245 */ - { 0x0000, 0x0000, 0x0000 }, /* R246 */ - { 0x0000, 0x0000, 0x0000 }, /* R247 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R248 */ - { 0x0000, 0x0000, 0x0000 }, /* R249 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R250 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R251 */ - { 0x0000, 0x0000, 0x0000 }, /* R252 */ - { 0xFFFF, 0x0010, 0xFFFF }, /* R253 */ - { 0x0000, 0x0000, 0x0000 }, /* R254 */ - { 0x0000, 0x0000, 0x0000 }, /* R255 */ -}; diff --git a/trunk/drivers/mfd/wm8400-core.c b/trunk/drivers/mfd/wm8400-core.c deleted file mode 100644 index 6a0cedb5bb8a..000000000000 --- a/trunk/drivers/mfd/wm8400-core.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Core driver for WM8400. - * - * Copyright 2008 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include - -static struct { - u16 readable; /* Mask of readable bits */ - u16 writable; /* Mask of writable bits */ - u16 vol; /* Mask of volatile bits */ - int is_codec; /* Register controlled by codec reset */ - u16 default_val; /* Value on reset */ -} reg_data[] = { - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x6172 }, /* R0 */ - { 0x7000, 0x0000, 0x8000, 0, 0x0000 }, /* R1 */ - { 0xFF17, 0xFF17, 0x0000, 0, 0x0000 }, /* R2 */ - { 0xEBF3, 0xEBF3, 0x0000, 1, 0x6000 }, /* R3 */ - { 0x3CF3, 0x3CF3, 0x0000, 1, 0x0000 }, /* R4 */ - { 0xF1F8, 0xF1F8, 0x0000, 1, 0x4050 }, /* R5 */ - { 0xFC1F, 0xFC1F, 0x0000, 1, 0x4000 }, /* R6 */ - { 0xDFDE, 0xDFDE, 0x0000, 1, 0x01C8 }, /* R7 */ - { 0xFCFC, 0xFCFC, 0x0000, 1, 0x0000 }, /* R8 */ - { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R9 */ - { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R10 */ - { 0x27F7, 0x27F7, 0x0000, 1, 0x0004 }, /* R11 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R12 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R13 */ - { 0x1FEF, 0x1FEF, 0x0000, 1, 0x0000 }, /* R14 */ - { 0x0163, 0x0163, 0x0000, 1, 0x0100 }, /* R15 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R16 */ - { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R17 */ - { 0x1FFF, 0x0FFF, 0x0000, 1, 0x0000 }, /* R18 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1000 }, /* R19 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R20 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R21 */ - { 0x0FDD, 0x0FDD, 0x0000, 1, 0x8000 }, /* R22 */ - { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0800 }, /* R23 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R24 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R25 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R26 */ - { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R27 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R28 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R29 */ - { 0x0000, 0x0077, 0x0000, 1, 0x0066 }, /* R30 */ - { 0x0000, 0x0033, 0x0000, 1, 0x0022 }, /* R31 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R32 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R33 */ - { 0x0000, 0x0003, 0x0000, 1, 0x0003 }, /* R34 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0003 }, /* R35 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R36 */ - { 0x0000, 0x003F, 0x0000, 1, 0x0100 }, /* R37 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R38 */ - { 0x0000, 0x000F, 0x0000, 0, 0x0000 }, /* R39 */ - { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R40 */ - { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R41 */ - { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R42 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R43 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R44 */ - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R45 */ - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R46 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R47 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R48 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R49 */ - { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R50 */ - { 0x0000, 0x01B3, 0x0000, 1, 0x0180 }, /* R51 */ - { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R52 */ - { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R53 */ - { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R54 */ - { 0x0000, 0x0001, 0x0000, 1, 0x0000 }, /* R55 */ - { 0x0000, 0x003F, 0x0000, 1, 0x0000 }, /* R56 */ - { 0x0000, 0x004F, 0x0000, 1, 0x0000 }, /* R57 */ - { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R58 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R59 */ - { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0000 }, /* R60 */ - { 0xFFFF, 0xFFFF, 0x0000, 1, 0x0000 }, /* R61 */ - { 0x03FF, 0x03FF, 0x0000, 1, 0x0000 }, /* R62 */ - { 0x007F, 0x007F, 0x0000, 1, 0x0000 }, /* R63 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R64 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R65 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R66 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R67 */ - { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R68 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R69 */ - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R70 */ - { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R71 */ - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R72 */ - { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R73 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R74 */ - { 0x000E, 0x000E, 0x0000, 0, 0x0008 }, /* R75 */ - { 0xE00F, 0xE00F, 0x0000, 0, 0x0000 }, /* R76 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R77 */ - { 0x03C0, 0x03C0, 0x0000, 0, 0x02C0 }, /* R78 */ - { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R79 */ - { 0xFFFF, 0xFFFF, 0x0000, 0, 0x0000 }, /* R80 */ - { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R81 */ - { 0x2BFF, 0x0000, 0xffff, 0, 0x0000 }, /* R82 */ - { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R83 */ - { 0x80FF, 0x80FF, 0x0000, 0, 0x00ff }, /* R84 */ -}; - -static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest) -{ - int i, ret = 0; - - BUG_ON(reg + num_regs - 1 > ARRAY_SIZE(wm8400->reg_cache)); - - /* If there are any volatile reads then read back the entire block */ - for (i = reg; i < reg + num_regs; i++) - if (reg_data[i].vol) { - ret = wm8400->read_dev(wm8400->io_data, reg, - num_regs, dest); - if (ret != 0) - return ret; - for (i = 0; i < num_regs; i++) - dest[i] = be16_to_cpu(dest[i]); - - return 0; - } - - /* Otherwise use the cache */ - memcpy(dest, &wm8400->reg_cache[reg], num_regs * sizeof(u16)); - - return 0; -} - -static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs, - u16 *src) -{ - int ret, i; - - BUG_ON(reg + num_regs - 1 > ARRAY_SIZE(wm8400->reg_cache)); - - for (i = 0; i < num_regs; i++) { - BUG_ON(!reg_data[reg + i].writable); - wm8400->reg_cache[reg + i] = src[i]; - src[i] = cpu_to_be16(src[i]); - } - - /* Do the actual I/O */ - ret = wm8400->write_dev(wm8400->io_data, reg, num_regs, src); - if (ret != 0) - return -EIO; - - return 0; -} - -/** - * wm8400_reg_read - Single register read - * - * @wm8400: Pointer to wm8400 control structure - * @reg: Register to read - * - * @return Read value - */ -u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg) -{ - u16 val; - - mutex_lock(&wm8400->io_lock); - - wm8400_read(wm8400, reg, 1, &val); - - mutex_unlock(&wm8400->io_lock); - - return val; -} -EXPORT_SYMBOL_GPL(wm8400_reg_read); - -int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data) -{ - int ret; - - mutex_lock(&wm8400->io_lock); - - ret = wm8400_read(wm8400, reg, count, data); - - mutex_unlock(&wm8400->io_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(wm8400_block_read); - -/** - * wm8400_set_bits - Bitmask write - * - * @wm8400: Pointer to wm8400 control structure - * @reg: Register to access - * @mask: Mask of bits to change - * @val: Value to set for masked bits - */ -int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val) -{ - u16 tmp; - int ret; - - mutex_lock(&wm8400->io_lock); - - ret = wm8400_read(wm8400, reg, 1, &tmp); - tmp = (tmp & ~mask) | val; - if (ret == 0) - ret = wm8400_write(wm8400, reg, 1, &tmp); - - mutex_unlock(&wm8400->io_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(wm8400_set_bits); - -/** - * wm8400_reset_codec_reg_cache - Reset cached codec registers to - * their default values. - */ -void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) -{ - int i; - - mutex_lock(&wm8400->io_lock); - - /* Reset all codec registers to their initial value */ - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) - if (reg_data[i].is_codec) - wm8400->reg_cache[i] = reg_data[i].default_val; - - mutex_unlock(&wm8400->io_lock); -} -EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); - -/* - * wm8400_init - Generic initialisation - * - * The WM8400 can be configured as either an I2C or SPI device. Probe - * functions for each bus set up the accessors then call into this to - * set up the device itself. - */ -static int wm8400_init(struct wm8400 *wm8400, - struct wm8400_platform_data *pdata) -{ - u16 reg; - int ret, i; - - mutex_init(&wm8400->io_lock); - - wm8400->dev->driver_data = wm8400; - - /* Check that this is actually a WM8400 */ - ret = wm8400->read_dev(wm8400->io_data, WM8400_RESET_ID, 1, ®); - if (ret != 0) { - dev_err(wm8400->dev, "Chip ID register read failed\n"); - return -EIO; - } - if (be16_to_cpu(reg) != reg_data[WM8400_RESET_ID].default_val) { - dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", - be16_to_cpu(reg)); - return -ENODEV; - } - - /* We don't know what state the hardware is in and since this - * is a PMIC we can't reset it safely so initialise the register - * cache from the hardware. - */ - ret = wm8400->read_dev(wm8400->io_data, 0, - ARRAY_SIZE(wm8400->reg_cache), - wm8400->reg_cache); - if (ret != 0) { - dev_err(wm8400->dev, "Register cache read failed\n"); - return -EIO; - } - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) - wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]); - - /* If the codec is in reset use hard coded values */ - if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA)) - for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) - if (reg_data[i].is_codec) - wm8400->reg_cache[i] = reg_data[i].default_val; - - ret = wm8400_read(wm8400, WM8400_ID, 1, ®); - if (ret != 0) { - dev_err(wm8400->dev, "ID register read failed: %d\n", ret); - return ret; - } - reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT; - dev_info(wm8400->dev, "WM8400 revision %x\n", reg); - - if (pdata && pdata->platform_init) { - ret = pdata->platform_init(wm8400->dev); - if (ret != 0) - dev_err(wm8400->dev, "Platform init failed: %d\n", - ret); - } else - dev_warn(wm8400->dev, "No platform initialisation supplied\n"); - - return ret; -} - -static void wm8400_release(struct wm8400 *wm8400) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(wm8400->regulators); i++) - if (wm8400->regulators[i].name) - platform_device_unregister(&wm8400->regulators[i]); -} - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int wm8400_i2c_read(void *io_data, char reg, int count, u16 *dest) -{ - struct i2c_client *i2c = io_data; - struct i2c_msg xfer[2]; - int ret; - - /* Write register */ - xfer[0].addr = i2c->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - - /* Read data */ - xfer[1].addr = i2c->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = count * sizeof(u16); - xfer[1].buf = (u8 *)dest; - - ret = i2c_transfer(i2c->adapter, xfer, 2); - if (ret == 2) - ret = 0; - else if (ret >= 0) - ret = -EIO; - - return ret; -} - -static int wm8400_i2c_write(void *io_data, char reg, int count, const u16 *src) -{ - struct i2c_client *i2c = io_data; - u8 *msg; - int ret; - - /* We add 1 byte for device register - ideally I2C would gather. */ - msg = kmalloc((count * sizeof(u16)) + 1, GFP_KERNEL); - if (msg == NULL) - return -ENOMEM; - - msg[0] = reg; - memcpy(&msg[1], src, count * sizeof(u16)); - - ret = i2c_master_send(i2c, msg, (count * sizeof(u16)) + 1); - - if (ret == (count * 2) + 1) - ret = 0; - else if (ret >= 0) - ret = -EIO; - - kfree(msg); - - return ret; -} - -static int wm8400_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8400 *wm8400; - int ret; - - wm8400 = kzalloc(sizeof(struct wm8400), GFP_KERNEL); - if (wm8400 == NULL) { - ret = -ENOMEM; - goto err; - } - - wm8400->io_data = i2c; - wm8400->read_dev = wm8400_i2c_read; - wm8400->write_dev = wm8400_i2c_write; - wm8400->dev = &i2c->dev; - i2c_set_clientdata(i2c, wm8400); - - ret = wm8400_init(wm8400, i2c->dev.platform_data); - if (ret != 0) - goto struct_err; - - return 0; - -struct_err: - i2c_set_clientdata(i2c, NULL); - kfree(wm8400); -err: - return ret; -} - -static int wm8400_i2c_remove(struct i2c_client *i2c) -{ - struct wm8400 *wm8400 = i2c_get_clientdata(i2c); - - wm8400_release(wm8400); - i2c_set_clientdata(i2c, NULL); - kfree(wm8400); - - return 0; -} - -static const struct i2c_device_id wm8400_i2c_id[] = { - { "wm8400", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8400_i2c_id); - -static struct i2c_driver wm8400_i2c_driver = { - .driver = { - .name = "WM8400", - .owner = THIS_MODULE, - }, - .probe = wm8400_i2c_probe, - .remove = wm8400_i2c_remove, - .id_table = wm8400_i2c_id, -}; -#endif - -static int __init wm8400_module_init(void) -{ - int ret = -ENODEV; - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8400_i2c_driver); - if (ret != 0) - pr_err("Failed to register I2C driver: %d\n", ret); -#endif - - return ret; -} -module_init(wm8400_module_init); - -static void __exit wm8400_module_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8400_i2c_driver); -#endif -} -module_exit(wm8400_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mark Brown "); diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index efd3aa08b88b..a726f3b01a6b 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -15,7 +15,7 @@ if MISC_DEVICES config ATMEL_PWM tristate "Atmel AT32/AT91 PWM support" - depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 + depends on AVR32 || ARCH_AT91 help This option enables device driver support for the PWM channels on certain Atmel prcoessors. Pulse Width Modulation is used for @@ -409,7 +409,6 @@ config EEEPC_LAPTOP depends on BACKLIGHT_CLASS_DEVICE depends on HWMON depends on EXPERIMENTAL - depends on RFKILL ---help--- This driver supports the Fn-Fx keys on Eee PC laptops. It also adds the ability to switch camera/wlan on/off. diff --git a/trunk/drivers/misc/hp-wmi.c b/trunk/drivers/misc/hp-wmi.c index 5dabfb69ee53..6d407c2a4f91 100644 --- a/trunk/drivers/misc/hp-wmi.c +++ b/trunk/drivers/misc/hp-wmi.c @@ -309,7 +309,7 @@ static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } -static void hp_wmi_notify(u32 value, void *context) +void hp_wmi_notify(u32 value, void *context) { struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; static struct key_entry *key; diff --git a/trunk/drivers/misc/phantom.c b/trunk/drivers/misc/phantom.c index abdebe347383..daf585689ce3 100644 --- a/trunk/drivers/misc/phantom.c +++ b/trunk/drivers/misc/phantom.c @@ -399,9 +399,9 @@ static int __devinit phantom_probe(struct pci_dev *pdev, goto err_irq; } - if (IS_ERR(device_create(phantom_class, &pdev->dev, - MKDEV(phantom_major, minor), NULL, - "phantom%u", minor))) + if (IS_ERR(device_create_drvdata(phantom_class, &pdev->dev, + MKDEV(phantom_major, minor), + NULL, "phantom%u", minor))) dev_err(&pdev->dev, "can't create device\n"); pci_set_drvdata(pdev, pht); diff --git a/trunk/drivers/misc/sgi-gru/gru.h b/trunk/drivers/misc/sgi-gru/gru.h index f93f03a9e6e9..40df7cb3f0a5 100644 --- a/trunk/drivers/misc/sgi-gru/gru.h +++ b/trunk/drivers/misc/sgi-gru/gru.h @@ -30,9 +30,9 @@ /* * Size used to map GRU GSeg */ -#if defined(CONFIG_IA64) +#if defined CONFIG_IA64 #define GRU_GSEG_PAGESIZE (256 * 1024UL) -#elif defined(CONFIG_X86_64) +#elif defined CONFIG_X86_64 #define GRU_GSEG_PAGESIZE (256 * 1024UL) /* ZZZ 2MB ??? */ #else #error "Unsupported architecture" diff --git a/trunk/drivers/misc/sgi-gru/gru_instructions.h b/trunk/drivers/misc/sgi-gru/gru_instructions.h index 48762e7b98be..0dc36225c7c6 100644 --- a/trunk/drivers/misc/sgi-gru/gru_instructions.h +++ b/trunk/drivers/misc/sgi-gru/gru_instructions.h @@ -26,7 +26,7 @@ * Architecture dependent functions */ -#if defined(CONFIG_IA64) +#if defined CONFIG_IA64 #include #include #define __flush_cache(p) ia64_fc(p) @@ -36,7 +36,7 @@ barrier(); \ *((volatile int *)(p)) = v; /* force st.rel */ \ } while (0) -#elif defined(CONFIG_X86_64) +#elif defined CONFIG_X86_64 #define __flush_cache(p) clflush(p) #define gru_ordered_store_int(p,v) \ do { \ @@ -299,7 +299,6 @@ static inline void gru_flush_cache(void *p) static inline void gru_start_instruction(struct gru_instruction *ins, int op32) { gru_ordered_store_int(ins, op32); - gru_flush_cache(ins); } @@ -605,9 +604,8 @@ static inline int gru_get_cb_substatus(void *cb) static inline int gru_check_status(void *cb) { struct gru_control_block_status *cbs = (void *)cb; - int ret; + int ret = cbs->istatus; - ret = cbs->istatus; if (ret == CBS_CALL_OS) ret = gru_check_status_proc(cb); return ret; @@ -619,7 +617,7 @@ static inline int gru_check_status(void *cb) static inline int gru_wait(void *cb) { struct gru_control_block_status *cbs = (void *)cb; - int ret = cbs->istatus; + int ret = cbs->istatus;; if (ret != CBS_IDLE) ret = gru_wait_proc(cb); diff --git a/trunk/drivers/misc/sgi-gru/grufault.c b/trunk/drivers/misc/sgi-gru/grufault.c index 8c389d606c30..3d33015bbf31 100644 --- a/trunk/drivers/misc/sgi-gru/grufault.c +++ b/trunk/drivers/misc/sgi-gru/grufault.c @@ -214,14 +214,12 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma, } /* + * * atomic_pte_lookup * * Convert a user virtual address to a physical address * Only supports Intel large pages (2MB only) on x86_64. * ZZZ - hugepage support is incomplete - * - * NOTE: mmap_sem is already held on entry to this function. This - * guarantees existence of the page tables. */ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr, int write, unsigned long *paddr, int *pageshift) @@ -231,6 +229,9 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr, pud_t *pudp; pte_t pte; + WARN_ON(irqs_disabled()); /* ZZZ debug */ + + local_irq_disable(); pgdp = pgd_offset(vma->vm_mm, vaddr); if (unlikely(pgd_none(*pgdp))) goto err; @@ -249,6 +250,8 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr, #endif pte = *pte_offset_kernel(pmdp, vaddr); + local_irq_enable(); + if (unlikely(!pte_present(pte) || (write && (!pte_write(pte) || !pte_dirty(pte))))) return 1; @@ -321,7 +324,6 @@ static int gru_try_dropin(struct gru_thread_state *gts, * Atomic lookup is faster & usually works even if called in non-atomic * context. */ - rmb(); /* Must/check ms_range_active before loading PTEs */ ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift); if (ret) { if (!cb) @@ -541,7 +543,6 @@ int gru_get_exception_detail(unsigned long arg) ucbnum = get_cb_number((void *)excdet.cb); cbrnum = thread_cbr_number(gts, ucbnum); cbe = get_cbe_by_index(gts->ts_gru, cbrnum); - prefetchw(cbe); /* Harmless on hardware, required for emulator */ excdet.opc = cbe->opccpy; excdet.exopc = cbe->exopccpy; excdet.ecause = cbe->ecause; diff --git a/trunk/drivers/misc/sgi-gru/grufile.c b/trunk/drivers/misc/sgi-gru/grufile.c index 5c027b6b4e5a..d61cee796efd 100644 --- a/trunk/drivers/misc/sgi-gru/grufile.c +++ b/trunk/drivers/misc/sgi-gru/grufile.c @@ -113,7 +113,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma) return -EPERM; if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) || - vma->vm_end & (GRU_GSEG_PAGESIZE - 1)) + vma->vm_end & (GRU_GSEG_PAGESIZE - 1)) return -EINVAL; vma->vm_flags |= @@ -398,12 +398,6 @@ static int __init gru_init(void) irq = get_base_irq(); for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) { ret = request_irq(irq + chip, gru_intr, 0, id, NULL); - /* TODO: fix irq handling on x86. For now ignore failures because - * interrupts are not required & not yet fully supported */ - if (ret) { - printk("!!!WARNING: GRU ignoring request failure!!!\n"); - ret = 0; - } if (ret) { printk(KERN_ERR "%s: request_irq failed\n", GRU_DRIVER_ID_STR); diff --git a/trunk/drivers/misc/sgi-gru/gruhandles.h b/trunk/drivers/misc/sgi-gru/gruhandles.h index b63018d60fe1..d16031d62673 100644 --- a/trunk/drivers/misc/sgi-gru/gruhandles.h +++ b/trunk/drivers/misc/sgi-gru/gruhandles.h @@ -91,7 +91,12 @@ #define GSEGPOFF(h) ((h) & (GRU_SIZE - 1)) /* Convert an arbitrary handle address to the beginning of the GRU segment */ +#ifndef __PLUGIN__ #define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1))) +#else +extern void *gmu_grubase(void *h); +#define GRUBASE(h) gmu_grubase(h) +#endif /* General addressing macros. */ static inline void *get_gseg_base_address(void *base, int ctxnum) diff --git a/trunk/drivers/misc/sgi-gru/grukservices.c b/trunk/drivers/misc/sgi-gru/grukservices.c index 880c55dfb662..dfd49af0fe18 100644 --- a/trunk/drivers/misc/sgi-gru/grukservices.c +++ b/trunk/drivers/misc/sgi-gru/grukservices.c @@ -122,7 +122,6 @@ int gru_get_cb_exception_detail(void *cb, struct gru_control_block_extended *cbe; cbe = get_cbe(GRUBASE(cb), get_cb_number(cb)); - prefetchw(cbe); /* Harmless on hardware, required for emulator */ excdet->opc = cbe->opccpy; excdet->exopc = cbe->exopccpy; excdet->ecause = cbe->ecause; @@ -467,7 +466,7 @@ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes) STAT(mesq_send); BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES); - clines = DIV_ROUND_UP(bytes, GRU_CACHE_LINE_BYTES); + clines = (bytes + GRU_CACHE_LINE_BYTES - 1) / GRU_CACHE_LINE_BYTES; if (gru_get_cpu_resources(bytes, &cb, &dsr)) return MQE_BUG_NO_RESOURCES; memcpy(dsr, mesg, bytes); diff --git a/trunk/drivers/misc/sgi-gru/grumain.c b/trunk/drivers/misc/sgi-gru/grumain.c index e11e1ac50900..0eeb8dddd2f5 100644 --- a/trunk/drivers/misc/sgi-gru/grumain.c +++ b/trunk/drivers/misc/sgi-gru/grumain.c @@ -432,35 +432,29 @@ static inline long gru_copy_handle(void *d, void *s) return GRU_HANDLE_BYTES; } -static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap, - unsigned long length) +/* rewrite in assembly & use lots of prefetch */ +static void gru_load_context_data(void *save, void *grubase, int ctxnum, + unsigned long cbrmap, unsigned long dsrmap) { + void *gseg, *cb, *cbe; + unsigned long length; int i, scr; + gseg = grubase + ctxnum * GRU_GSEG_STRIDE; + length = hweight64(dsrmap) * GRU_DSR_AU_BYTES; prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES, GRU_CACHE_LINE_BYTES); + cb = gseg + GRU_CB_BASE; + cbe = grubase + GRU_CBE_BASE; for_each_cbr_in_allocation_map(i, &cbrmap, scr) { prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES); prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1, GRU_CACHE_LINE_BYTES); cb += GRU_HANDLE_STRIDE; } -} - -static void gru_load_context_data(void *save, void *grubase, int ctxnum, - unsigned long cbrmap, unsigned long dsrmap) -{ - void *gseg, *cb, *cbe; - unsigned long length; - int i, scr; - gseg = grubase + ctxnum * GRU_GSEG_STRIDE; cb = gseg + GRU_CB_BASE; - cbe = grubase + GRU_CBE_BASE; - length = hweight64(dsrmap) * GRU_DSR_AU_BYTES; - gru_prefetch_context(gseg, cb, cbe, cbrmap, length); - for_each_cbr_in_allocation_map(i, &cbrmap, scr) { save += gru_copy_handle(cb, save); save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save); @@ -478,16 +472,15 @@ static void gru_unload_context_data(void *save, void *grubase, int ctxnum, int i, scr; gseg = grubase + ctxnum * GRU_GSEG_STRIDE; + cb = gseg + GRU_CB_BASE; cbe = grubase + GRU_CBE_BASE; - length = hweight64(dsrmap) * GRU_DSR_AU_BYTES; - gru_prefetch_context(gseg, cb, cbe, cbrmap, length); - for_each_cbr_in_allocation_map(i, &cbrmap, scr) { save += gru_copy_handle(save, cb); save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE); cb += GRU_HANDLE_STRIDE; } + length = hweight64(dsrmap) * GRU_DSR_AU_BYTES; memcpy(save, gseg + GRU_DS_BASE, length); } diff --git a/trunk/drivers/mmc/host/omap.c b/trunk/drivers/mmc/host/omap.c index 1b9fc3c6b875..c16028872bbb 100644 --- a/trunk/drivers/mmc/host/omap.c +++ b/trunk/drivers/mmc/host/omap.c @@ -172,7 +172,7 @@ struct mmc_omap_host { struct omap_mmc_platform_data *pdata; }; -static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot) +void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot) { unsigned long tick_ns; @@ -182,7 +182,7 @@ static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot) } } -static void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable) +void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable) { unsigned long flags; @@ -1455,9 +1455,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev) host->irq = irq; host->phys_base = host->mem_res->start; - host->virt_base = ioremap(res->start, res->end - res->start + 1); - if (!host->virt_base) - goto err_ioremap; + host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base); if (cpu_is_omap24xx()) { host->iclk = clk_get(&pdev->dev, "mmc_ick"); @@ -1512,8 +1510,6 @@ static int __init mmc_omap_probe(struct platform_device *pdev) clk_put(host->iclk); } err_free_mmc_host: - iounmap(host->virt_base); -err_ioremap: kfree(host); err_free_mem_region: release_mem_region(res->start, res->end - res->start + 1); @@ -1540,7 +1536,6 @@ static int mmc_omap_remove(struct platform_device *pdev) if (host->fclk && !IS_ERR(host->fclk)) clk_put(host->fclk); - iounmap(host->virt_base); release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index 9bd7026b0021..0a84f10d719c 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -327,7 +327,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { { .vendor = PCI_VENDOR_ID_MARVELL, - .device = PCI_DEVICE_ID_MARVELL_88ALP01_SD, + .device = PCI_DEVICE_ID_MARVELL_CAFE_SD, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = (kernel_ulong_t)&sdhci_cafe, diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c index d600c2deff73..90924fb00481 100644 --- a/trunk/drivers/mtd/maps/pcmciamtd.c +++ b/trunk/drivers/mtd/maps/pcmciamtd.c @@ -118,8 +118,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x", dev->offset, mrq.CardOffset); mrq.Page = 0; - ret = pcmcia_map_mem_page(win, &mrq); - if (ret != 0) { + if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { cs_error(dev->p_dev, MapMemPage, ret); return NULL; } @@ -327,8 +326,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); ret = pcmcia_modify_configuration(link, &mod); - if (ret != 0) + if(ret != CS_SUCCESS) { cs_error(link, ModifyConfiguration, ret); + } } @@ -368,14 +368,14 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, tuple.DesiredTuple = RETURN_FIRST_TUPLE; rc = pcmcia_get_first_tuple(link, &tuple); - while (rc == 0) { + while(rc == CS_SUCCESS) { rc = pcmcia_get_tuple_data(link, &tuple); - if (rc != 0) { + if(rc != CS_SUCCESS) { cs_error(link, GetTupleData, rc); break; } - rc = pcmcia_parse_tuple(&tuple, &parse); - if (rc != 0) { + rc = pcmcia_parse_tuple(link, &tuple, &parse); + if(rc != CS_SUCCESS) { cs_error(link, ParseTuple, rc); break; } @@ -493,11 +493,18 @@ static int pcmciamtd_config(struct pcmcia_device *link) int last_ret = 0, last_fn = 0; int ret; int i; + config_info_t t; static char *probes[] = { "jedec_probe", "cfi_probe" }; int new_name = 0; DEBUG(3, "link=0x%p", link); + DEBUG(2, "Validating CIS"); + ret = pcmcia_validate_cis(link, NULL); + if(ret != CS_SUCCESS) { + cs_error(link, GetTupleData, ret); + } + card_settings(dev, link, &new_name); dev->pcmcia_map.phys = NO_XIP; @@ -564,7 +571,10 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->pcmcia_map.map_priv_1 = (unsigned long)dev; dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; - dev->vpp = (vpp) ? vpp : link->socket.socket.Vpp; + DEBUG(2, "Getting configuration"); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t)); + DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); + dev->vpp = (vpp) ? vpp : t.Vpp1; link->conf.Attributes = 0; if(setvpp == 2) { link->conf.Vpp = dev->vpp; @@ -573,10 +583,16 @@ static int pcmciamtd_config(struct pcmcia_device *link) } link->conf.IntType = INT_MEMORY; + link->conf.ConfigBase = t.ConfigBase; + link->conf.Status = t.Status; + link->conf.Pin = t.Pin; + link->conf.Copy = t.Copy; + link->conf.ExtStatus = t.ExtStatus; link->conf.ConfigIndex = 0; + link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); ret = pcmcia_request_configuration(link, &link->conf); - if (ret != 0) { + if(ret != CS_SUCCESS) { cs_error(link, RequestConfiguration, ret); if (dev->win_base) { iounmap(dev->win_base); diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index 1c74762dec89..e00d424e6575 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -26,11 +26,13 @@ static void mtd_notify_add(struct mtd_info* mtd) if (!mtd) return; - device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), - NULL, "mtd%d", mtd->index); + device_create_drvdata(mtd_class, NULL, + MKDEV(MTD_CHAR_MAJOR, mtd->index*2), + NULL, "mtd%d", mtd->index); - device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), - NULL, "mtd%dro", mtd->index); + device_create_drvdata(mtd_class, NULL, + MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), + NULL, "mtd%dro", mtd->index); } static void mtd_notify_remove(struct mtd_info* mtd) diff --git a/trunk/drivers/mtd/mtdpart.c b/trunk/drivers/mtd/mtdpart.c index 9a06dc93ee0d..edb90b58a9b1 100644 --- a/trunk/drivers/mtd/mtdpart.c +++ b/trunk/drivers/mtd/mtdpart.c @@ -564,8 +564,10 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, for ( ; ret <= 0 && *types; types++) { parser = get_partition_parser(*types); +#ifdef CONFIG_KMOD if (!parser && !request_module("%s", *types)) parser = get_partition_parser(*types); +#endif if (!parser) { printk(KERN_NOTICE "%s partition parsing not available\n", *types); diff --git a/trunk/drivers/mtd/nand/ams-delta.c b/trunk/drivers/mtd/nand/ams-delta.c index 782994ead0e8..26d42987971f 100644 --- a/trunk/drivers/mtd/nand/ams-delta.c +++ b/trunk/drivers/mtd/nand/ams-delta.c @@ -145,7 +145,7 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd, static int ams_delta_nand_ready(struct mtd_info *mtd) { - return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB); + return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB); } /* @@ -185,7 +185,7 @@ static int __init ams_delta_init(void) this->read_buf = ams_delta_read_buf; this->verify_buf = ams_delta_verify_buf; this->cmd_ctrl = ams_delta_hwcontrol; - if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) { + if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) { this->dev_ready = ams_delta_nand_ready; } else { this->dev_ready = NULL; diff --git a/trunk/drivers/mtd/nand/cafe_nand.c b/trunk/drivers/mtd/nand/cafe_nand.c index b8064bf3aee4..95345d051579 100644 --- a/trunk/drivers/mtd/nand/cafe_nand.c +++ b/trunk/drivers/mtd/nand/cafe_nand.c @@ -1,9 +1,6 @@ /* * Driver for One Laptop Per Child ‘CAFÉ’ controller, aka Marvell 88ALP01 * - * The data sheet for this device can be found at: - * http://www.marvell.com/products/pcconn/88ALP01.jsp - * * Copyright © 2006 Red Hat, Inc. * Copyright © 2006 David Woodhouse */ @@ -845,8 +842,7 @@ static void __devexit cafe_nand_remove(struct pci_dev *pdev) } static struct pci_device_id cafe_nand_tbl[] = { - { PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_88ALP01_NAND, - PCI_ANY_ID, PCI_ANY_ID }, + { 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID }, { } }; diff --git a/trunk/drivers/net/3c501.c b/trunk/drivers/net/3c501.c index 7d15e7c6bcad..5ba4bab6d43e 100644 --- a/trunk/drivers/net/3c501.c +++ b/trunk/drivers/net/3c501.c @@ -17,7 +17,7 @@ Annapolis MD 21403 Fixed (again!) the missing interrupt locking on TX/RX shifting. - Alan Cox + Alan Cox Removed calls to init_etherdev since they are no longer needed, and cleaned up modularization just a bit. The driver still allows only @@ -29,16 +29,16 @@ the board. Now getting 150K/second FTP with a 3c501 card. Still playing with a TX-TX optimisation to see if we can touch 180-200K/second as seems theoretically maximum. - 19950402 Alan Cox + 19950402 Alan Cox Cleaned up for 2.3.x because we broke SMP now. - 20000208 Alan Cox + 20000208 Alan Cox Check up pass for 2.5. Nothing significant changed - 20021009 Alan Cox + 20021009 Alan Cox Fixed zero fill corner case - 20030104 Alan Cox + 20030104 Alan Cox For the avoidance of doubt the "preferred form" of this code is one which @@ -104,7 +104,7 @@ static const char version[] = - DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@lxorguk.ukuu.org.uk).\n"; + DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@redhat.com).\n"; /* * Braindamage remaining: diff --git a/trunk/drivers/net/3c509.c b/trunk/drivers/net/3c509.c index 3a7bc524af33..b9d097c9f6bb 100644 --- a/trunk/drivers/net/3c509.c +++ b/trunk/drivers/net/3c509.c @@ -40,7 +40,7 @@ v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb v1.15 1/31/98 Faster recovery for Tx errors. -djb v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb - v1.18 12Mar2001 Andrew Morton + v1.18 12Mar2001 Andrew Morton - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz) - Reviewed against 1.18 from scyld.com v1.18a 17Nov2001 Jeff Garzik diff --git a/trunk/drivers/net/3c515.c b/trunk/drivers/net/3c515.c index a0f8b6e2d0af..e4e3241628d6 100644 --- a/trunk/drivers/net/3c515.c +++ b/trunk/drivers/net/3c515.c @@ -18,7 +18,7 @@ 2001/11/17 - Added ethtool support (jgarzik) - 2002/10/28 - Locking updates for 2.5 (alan@lxorguk.ukuu.org.uk) + 2002/10/28 - Locking updates for 2.5 (alan@redhat.com) */ diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 1d8af3348331..e9d529442b06 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2400,7 +2400,7 @@ config EHEA will be called ehea. config ENIC - tristate "Cisco 10G Ethernet NIC support" + tristate "E, the Cisco 10G Ethernet NIC" depends on PCI && INET select INET_LRO help diff --git a/trunk/drivers/net/appletalk/cops.c b/trunk/drivers/net/appletalk/cops.c index 735fc9476403..a0b4c8516073 100644 --- a/trunk/drivers/net/appletalk/cops.c +++ b/trunk/drivers/net/appletalk/cops.c @@ -4,7 +4,7 @@ * - Jay Schulist * * With more than a little help from; - * - Alan Cox + * - Alan Cox * * Derived from: * - skeleton.c: A network driver outline for linux. diff --git a/trunk/drivers/net/au1000_eth.c b/trunk/drivers/net/au1000_eth.c index 019b13c08ae6..7b92201a7b50 100644 --- a/trunk/drivers/net/au1000_eth.c +++ b/trunk/drivers/net/au1000_eth.c @@ -94,8 +94,8 @@ static irqreturn_t au1000_interrupt(int, void *); static void au1000_tx_timeout(struct net_device *); static void set_rx_mode(struct net_device *); static int au1000_ioctl(struct net_device *, struct ifreq *, int); -static int au1000_mdio_read(struct net_device *, int, int); -static void au1000_mdio_write(struct net_device *, int, int, u16); +static int mdio_read(struct net_device *, int, int); +static void mdio_write(struct net_device *, int, int, u16); static void au1000_adjust_link(struct net_device *); static void enable_mac(struct net_device *, int); @@ -191,7 +191,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES]; /* * MII operations */ -static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) +static int mdio_read(struct net_device *dev, int phy_addr, int reg) { struct au1000_private *aup = (struct au1000_private *) dev->priv; volatile u32 *const mii_control_reg = &aup->mac->mii_control; @@ -225,8 +225,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) return (int)*mii_data_reg; } -static void au1000_mdio_write(struct net_device *dev, int phy_addr, - int reg, u16 value) +static void mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value) { struct au1000_private *aup = (struct au1000_private *) dev->priv; volatile u32 *const mii_control_reg = &aup->mac->mii_control; @@ -250,7 +249,7 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr, *mii_control_reg = mii_control; } -static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) +static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) { /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */ @@ -258,21 +257,21 @@ static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) enable_mac(dev, 0); /* make sure the MAC associated with this * mii_bus is enabled */ - return au1000_mdio_read(dev, phy_addr, regnum); + return mdio_read(dev, phy_addr, regnum); } -static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, - u16 value) +static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, + u16 value) { struct net_device *const dev = bus->priv; enable_mac(dev, 0); /* make sure the MAC associated with this * mii_bus is enabled */ - au1000_mdio_write(dev, phy_addr, regnum, value); + mdio_write(dev, phy_addr, regnum, value); return 0; } -static int au1000_mdiobus_reset(struct mii_bus *bus) +static int mdiobus_reset(struct mii_bus *bus) { struct net_device *const dev = bus->priv; @@ -704,9 +703,9 @@ static struct net_device * au1000_probe(int port_num) goto err_out; aup->mii_bus->priv = dev; - aup->mii_bus->read = au1000_mdiobus_read; - aup->mii_bus->write = au1000_mdiobus_write; - aup->mii_bus->reset = au1000_mdiobus_reset; + aup->mii_bus->read = mdiobus_read; + aup->mii_bus->write = mdiobus_write; + aup->mii_bus->reset = mdiobus_reset; aup->mii_bus->name = "au1000_eth_mii"; snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id); aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); diff --git a/trunk/drivers/net/bfin_mac.c b/trunk/drivers/net/bfin_mac.c index b458d607a9c6..a0d41c5d97d8 100644 --- a/trunk/drivers/net/bfin_mac.c +++ b/trunk/drivers/net/bfin_mac.c @@ -253,7 +253,7 @@ static int desc_list_init(void) * MII operations */ /* Wait until the previous MDC/MDIO transaction has completed */ -static void bfin_mdio_poll(void) +static void mdio_poll(void) { int timeout_cnt = MAX_TIMEOUT_CNT; @@ -269,25 +269,25 @@ static void bfin_mdio_poll(void) } /* Read an off-chip register in a PHY through the MDC/MDIO port */ -static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) +static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) { - bfin_mdio_poll(); + mdio_poll(); /* read mode */ bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) | SET_REGAD((u16) regnum) | STABUSY); - bfin_mdio_poll(); + mdio_poll(); return (int) bfin_read_EMAC_STADAT(); } /* Write an off-chip register in a PHY through the MDC/MDIO port */ -static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, - u16 value) +static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, + u16 value) { - bfin_mdio_poll(); + mdio_poll(); bfin_write_EMAC_STADAT((u32) value); @@ -297,12 +297,12 @@ static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, STAOP | STABUSY); - bfin_mdio_poll(); + mdio_poll(); return 0; } -static int bfin_mdiobus_reset(struct mii_bus *bus) +static int mdiobus_reset(struct mii_bus *bus) { return 0; } @@ -818,7 +818,7 @@ static void bfin_mac_enable(void) bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config); /* Wait MII done */ - bfin_mdio_poll(); + mdio_poll(); /* We enable only RX here */ /* ASTP : Enable Automatic Pad Stripping @@ -1063,9 +1063,9 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) goto out_err_mdiobus_alloc; lp->mii_bus->priv = ndev; - lp->mii_bus->read = bfin_mdiobus_read; - lp->mii_bus->write = bfin_mdiobus_write; - lp->mii_bus->reset = bfin_mdiobus_reset; + lp->mii_bus->read = mdiobus_read; + lp->mii_bus->write = mdiobus_write; + lp->mii_bus->reset = mdiobus_reset; lp->mii_bus->name = "bfin_mac_mdio"; snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0"); lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); diff --git a/trunk/drivers/net/cs89x0.c b/trunk/drivers/net/cs89x0.c index 7107620f615d..a28de8182802 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -36,7 +36,8 @@ Alan Cox : Removed 1.2 support, added 2.1 extra counters. - Andrew Morton : Kernel 2.3.48 + Andrew Morton : andrewm@uow.edu.au + : Kernel 2.3.48 : Handle kmalloc() failures : Other resource allocation fixes : Add SMP locks @@ -48,7 +49,7 @@ : Fixed an out-of-mem bug in dma_rx() : Updated Documentation/networking/cs89x0.txt - Andrew Morton : Kernel 2.3.99-pre1 + Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1 : Use skb_reserve to longword align IP header (two places) : Remove a delay loop from dma_rx() : Replace '100' with HZ @@ -56,11 +57,11 @@ : Added 'cs89x0_dma=N' kernel boot option : Correctly initialise lp->lock in non-module compile - Andrew Morton : Kernel 2.3.99-pre4-1 + Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1 : MOD_INC/DEC race fix (see : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html) - Andrew Morton : Kernel 2.4.0-test7-pre2 + Andrew Morton : andrewm@uow.edu.au / Kernel 2.4.0-test7-pre2 : Enhanced EEPROM support to cover more devices, : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch : (Jason Gunthorpe ) @@ -155,7 +156,7 @@ #include "cs89x0.h" static char version[] __initdata = -"cs89x0.c: v2.4.3-pre1 Russell Nelson , Andrew Morton\n"; +"cs89x0.c: v2.4.3-pre1 Russell Nelson , Andrew Morton \n"; #define DRV_NAME "cs89x0" @@ -1876,7 +1877,7 @@ MODULE_PARM_DESC(dmasize , "(ignored)"); MODULE_PARM_DESC(use_dma , "(ignored)"); #endif -MODULE_AUTHOR("Mike Cruse, Russwll Nelson , Andrew Morton"); +MODULE_AUTHOR("Mike Cruse, Russwll Nelson , Andrew Morton "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h index bc8e2413abd2..455ef529cd62 100644 --- a/trunk/drivers/net/cxgb3/adapter.h +++ b/trunk/drivers/net/cxgb3/adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/ael1002.c b/trunk/drivers/net/cxgb3/ael1002.c index 5c3c05da4d96..744fac0b1617 100644 --- a/trunk/drivers/net/cxgb3/ael1002.c +++ b/trunk/drivers/net/cxgb3/ael1002.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/common.h b/trunk/drivers/net/cxgb3/common.h index e312d315a42d..593fb643a615 100644 --- a/trunk/drivers/net/cxgb3/common.h +++ b/trunk/drivers/net/cxgb3/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h b/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h index 1d8d46eb3c96..6ad92405d9a0 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h +++ b/trunk/drivers/net/cxgb3/cxgb3_ctl_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/cxgb3_defs.h b/trunk/drivers/net/cxgb3/cxgb3_defs.h index 47e53769af5b..45e92164c260 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_defs.h +++ b/trunk/drivers/net/cxgb3/cxgb3_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/cxgb3_ioctl.h b/trunk/drivers/net/cxgb3/cxgb3_ioctl.h index b19e4376ba76..3e8d5faec3a4 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_ioctl.h +++ b/trunk/drivers/net/cxgb3/cxgb3_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 1ace41a13ac3..f31985df0bb9 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index 265aa8a15afa..0f6fd63b2847 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.h b/trunk/drivers/net/cxgb3/cxgb3_offload.h index d514e5019dfc..7a379138b5a6 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.h +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/firmware_exports.h b/trunk/drivers/net/cxgb3/firmware_exports.h index 0d9b0e6dccff..b75ddd8777fe 100644 --- a/trunk/drivers/net/cxgb3/firmware_exports.h +++ b/trunk/drivers/net/cxgb3/firmware_exports.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2004-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/l2t.c b/trunk/drivers/net/cxgb3/l2t.c index 4407ac9bb555..b2c5314582aa 100644 --- a/trunk/drivers/net/cxgb3/l2t.c +++ b/trunk/drivers/net/cxgb3/l2t.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/l2t.h b/trunk/drivers/net/cxgb3/l2t.h index fd3eb07e3f40..42ce65f76a87 100644 --- a/trunk/drivers/net/cxgb3/l2t.h +++ b/trunk/drivers/net/cxgb3/l2t.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/mc5.c b/trunk/drivers/net/cxgb3/mc5.c index 3b5517b8fbde..4c4d6e877ea6 100644 --- a/trunk/drivers/net/cxgb3/mc5.c +++ b/trunk/drivers/net/cxgb3/mc5.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index c6480be0bc1f..87919419b707 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/t3_cpl.h b/trunk/drivers/net/cxgb3/t3_cpl.h index 852c399a8b0a..917970ed24a1 100644 --- a/trunk/drivers/net/cxgb3/t3_cpl.h +++ b/trunk/drivers/net/cxgb3/t3_cpl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2004-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/t3_hw.c b/trunk/drivers/net/cxgb3/t3_hw.c index 968f64be3743..4da5b09b9bc2 100644 --- a/trunk/drivers/net/cxgb3/t3_hw.c +++ b/trunk/drivers/net/cxgb3/t3_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/t3cdev.h b/trunk/drivers/net/cxgb3/t3cdev.h index be55e9ae74d1..0a21cfbd2b21 100644 --- a/trunk/drivers/net/cxgb3/t3cdev.h +++ b/trunk/drivers/net/cxgb3/t3cdev.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Chelsio Communications. All rights reserved. + * Copyright (C) 2006-2007 Chelsio Communications. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/version.h b/trunk/drivers/net/cxgb3/version.h index bb8698a86754..29db711303b9 100644 --- a/trunk/drivers/net/cxgb3/version.h +++ b/trunk/drivers/net/cxgb3/version.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -35,7 +35,7 @@ #define DRV_DESC "Chelsio T3 Network Driver" #define DRV_NAME "cxgb3" /* Driver version */ -#define DRV_VERSION "1.1.0-ko" +#define DRV_VERSION "1.0-ko" /* Firmware version */ #define FW_VERSION_MAJOR 7 diff --git a/trunk/drivers/net/cxgb3/vsc8211.c b/trunk/drivers/net/cxgb3/vsc8211.c index 33f956bd6b59..306c2dc4ab34 100644 --- a/trunk/drivers/net/cxgb3/vsc8211.c +++ b/trunk/drivers/net/cxgb3/vsc8211.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/cxgb3/xgmac.c b/trunk/drivers/net/cxgb3/xgmac.c index 9d7786937aad..ffdc0a1892bd 100644 --- a/trunk/drivers/net/cxgb3/xgmac.c +++ b/trunk/drivers/net/cxgb3/xgmac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. + * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/net/eexpress.c b/trunk/drivers/net/eexpress.c index b751c1b96cfa..795c594a4b7c 100644 --- a/trunk/drivers/net/eexpress.c +++ b/trunk/drivers/net/eexpress.c @@ -8,7 +8,7 @@ * * Many modifications, and currently maintained, by * Philip Blundell - * Added the Compaq LTE Alan Cox + * Added the Compaq LTE Alan Cox * Added MCA support Adam Fritzler * * Note - this driver is experimental still - it has problems on faster diff --git a/trunk/drivers/net/enic/enic_main.c b/trunk/drivers/net/enic/enic_main.c index 180e968dc54d..f3a47a87dbbe 100644 --- a/trunk/drivers/net/enic/enic_main.c +++ b/trunk/drivers/net/enic/enic_main.c @@ -34,7 +34,6 @@ #include #include #include -#include #include "cq_enet_desc.h" #include "vnic_dev.h" diff --git a/trunk/drivers/net/ibm_newemac/Kconfig b/trunk/drivers/net/ibm_newemac/Kconfig index 78a1628c9892..bcec7320895c 100644 --- a/trunk/drivers/net/ibm_newemac/Kconfig +++ b/trunk/drivers/net/ibm_newemac/Kconfig @@ -62,15 +62,3 @@ config IBM_NEW_EMAC_TAH config IBM_NEW_EMAC_EMAC4 bool default n - -config IBM_NEW_EMAC_NO_FLOW_CTRL - bool - default n - -config IBM_NEW_EMAC_MAL_CLR_ICINTSTAT - bool - default n - -config IBM_NEW_EMAC_MAL_COMMON_ERR - bool - default n diff --git a/trunk/drivers/net/ibm_newemac/core.c b/trunk/drivers/net/ibm_newemac/core.c index efcf21c9f5c7..58dfd32ccca8 100644 --- a/trunk/drivers/net/ibm_newemac/core.c +++ b/trunk/drivers/net/ibm_newemac/core.c @@ -202,15 +202,13 @@ static inline int emac_phy_supports_gige(int phy_mode) { return phy_mode == PHY_MODE_GMII || phy_mode == PHY_MODE_RGMII || - phy_mode == PHY_MODE_SGMII || phy_mode == PHY_MODE_TBI || phy_mode == PHY_MODE_RTBI; } static inline int emac_phy_gpcs(int phy_mode) { - return phy_mode == PHY_MODE_SGMII || - phy_mode == PHY_MODE_TBI || + return phy_mode == PHY_MODE_TBI || phy_mode == PHY_MODE_RTBI; } @@ -564,9 +562,8 @@ static int emac_configure(struct emac_instance *dev) switch (dev->phy.speed) { case SPEED_1000: if (emac_phy_gpcs(dev->phy.mode)) { - mr1 |= EMAC_MR1_MF_1000GPCS | EMAC_MR1_MF_IPPA( - (dev->phy.gpcs_address != 0xffffffff) ? - dev->phy.gpcs_address : dev->phy.address); + mr1 |= EMAC_MR1_MF_1000GPCS | + EMAC_MR1_MF_IPPA(dev->phy.address); /* Put some arbitrary OUI, Manuf & Rev IDs so we can * identify this GPCS PHY later. @@ -678,12 +675,8 @@ static int emac_configure(struct emac_instance *dev) out_be32(&p->iser, r); /* We need to take GPCS PHY out of isolate mode after EMAC reset */ - if (emac_phy_gpcs(dev->phy.mode)) { - if (dev->phy.gpcs_address != 0xffffffff) - emac_mii_reset_gpcs(&dev->phy); - else - emac_mii_reset_phy(&dev->phy); - } + if (emac_phy_gpcs(dev->phy.mode)) + emac_mii_reset_phy(&dev->phy); return 0; } @@ -888,9 +881,7 @@ static int emac_mdio_read(struct net_device *ndev, int id, int reg) struct emac_instance *dev = netdev_priv(ndev); int res; - res = __emac_mdio_read((dev->mdio_instance && - dev->phy.gpcs_address != id) ? - dev->mdio_instance : dev, + res = __emac_mdio_read(dev->mdio_instance ? dev->mdio_instance : dev, (u8) id, (u8) reg); return res; } @@ -899,9 +890,7 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val) { struct emac_instance *dev = netdev_priv(ndev); - __emac_mdio_write((dev->mdio_instance && - dev->phy.gpcs_address != id) ? - dev->mdio_instance : dev, + __emac_mdio_write(dev->mdio_instance ? dev->mdio_instance : dev, (u8) id, (u8) reg, (u16) val); } @@ -2393,11 +2382,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) * XXX I probably should move these settings to the dev tree */ dev->phy.address = -1; - dev->phy.features = SUPPORTED_MII; - if (emac_phy_supports_gige(dev->phy_mode)) - dev->phy.features |= SUPPORTED_1000baseT_Full; - else - dev->phy.features |= SUPPORTED_100baseT_Full; + dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII; dev->phy.pause = 1; return 0; @@ -2436,9 +2421,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) * Note that the busy_phy_map is currently global * while it should probably be per-ASIC... */ - dev->phy.gpcs_address = dev->gpcs_address; - if (dev->phy.gpcs_address == 0xffffffff) - dev->phy.address = dev->cell_index; + dev->phy.address = dev->cell_index; } emac_configure(dev); @@ -2548,8 +2531,6 @@ static int __devinit emac_init_config(struct emac_instance *dev) dev->phy_address = 0xffffffff; if (emac_read_uint_prop(np, "phy-map", &dev->phy_map, 0)) dev->phy_map = 0xffffffff; - if (emac_read_uint_prop(np, "gpcs-address", &dev->gpcs_address, 0)) - dev->gpcs_address = 0xffffffff; if (emac_read_uint_prop(np->parent, "clock-frequency", &dev->opb_bus_freq, 1)) return -ENXIO; if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0)) @@ -2604,8 +2585,6 @@ static int __devinit emac_init_config(struct emac_instance *dev) if (of_device_is_compatible(np, "ibm,emac-440ep") || of_device_is_compatible(np, "ibm,emac-440gr")) dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; - if (of_device_is_compatible(np, "ibm,emac-405ez")) - dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x; } /* Fixup some feature bits based on the device tree */ @@ -2863,9 +2842,6 @@ static int __devinit emac_probe(struct of_device *ofdev, ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); - if (dev->phy_mode == PHY_MODE_SGMII) - printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name); - if (dev->phy.address >= 0) printk("%s: found %s PHY (0x%02x)\n", ndev->name, dev->phy.def->name, dev->phy.address); diff --git a/trunk/drivers/net/ibm_newemac/core.h b/trunk/drivers/net/ibm_newemac/core.h index 18d56c6c4238..5ca70e55b6c5 100644 --- a/trunk/drivers/net/ibm_newemac/core.h +++ b/trunk/drivers/net/ibm_newemac/core.h @@ -190,9 +190,6 @@ struct emac_instance { struct delayed_work link_work; int link_polling; - /* GPCS PHY infos */ - u32 gpcs_address; - /* Shared MDIO if any */ u32 mdio_ph; struct of_device *mdio_dev; @@ -347,9 +344,6 @@ enum { #endif #ifdef CONFIG_IBM_NEW_EMAC_RGMII EMAC_FTR_HAS_RGMII | -#endif -#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL - EMAC_FTR_NO_FLOW_CONTROL_40x | #endif EMAC_FTR_460EX_PHY_CLK_FIX | EMAC_FTR_440EP_PHY_CLK_FIX, diff --git a/trunk/drivers/net/ibm_newemac/mal.c b/trunk/drivers/net/ibm_newemac/mal.c index 1839d3f154a3..10c267b2b961 100644 --- a/trunk/drivers/net/ibm_newemac/mal.c +++ b/trunk/drivers/net/ibm_newemac/mal.c @@ -28,7 +28,6 @@ #include #include "core.h" -#include static int mal_count; @@ -280,10 +279,6 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance) mal_schedule_poll(mal); set_mal_dcrn(mal, MAL_TXEOBISR, r); - if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT)) - mtdcri(SDR0, DCRN_SDR_ICINTSTAT, - (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX)); - return IRQ_HANDLED; } @@ -298,10 +293,6 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance) mal_schedule_poll(mal); set_mal_dcrn(mal, MAL_RXEOBISR, r); - if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT)) - mtdcri(SDR0, DCRN_SDR_ICINTSTAT, - (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX)); - return IRQ_HANDLED; } @@ -345,25 +336,6 @@ static irqreturn_t mal_rxde(int irq, void *dev_instance) return IRQ_HANDLED; } -static irqreturn_t mal_int(int irq, void *dev_instance) -{ - struct mal_instance *mal = dev_instance; - u32 esr = get_mal_dcrn(mal, MAL_ESR); - - if (esr & MAL_ESR_EVB) { - /* descriptor error */ - if (esr & MAL_ESR_DE) { - if (esr & MAL_ESR_CIDT) - return mal_rxde(irq, dev_instance); - else - return mal_txde(irq, dev_instance); - } else { /* SERR */ - return mal_serr(irq, dev_instance); - } - } - return IRQ_HANDLED; -} - void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac) { /* Spinlock-type semantics: only one caller disable poll at a time */ @@ -521,8 +493,6 @@ static int __devinit mal_probe(struct of_device *ofdev, unsigned int dcr_base; const u32 *prop; u32 cfg; - unsigned long irqflags; - irq_handler_t hdlr_serr, hdlr_txde, hdlr_rxde; mal = kzalloc(sizeof(struct mal_instance), GFP_KERNEL); if (!mal) { @@ -572,21 +542,11 @@ static int __devinit mal_probe(struct of_device *ofdev, goto fail; } - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) - mal->features |= (MAL_FTR_CLEAR_ICINTSTAT | - MAL_FTR_COMMON_ERR_INT); - mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0); mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1); mal->serr_irq = irq_of_parse_and_map(ofdev->node, 2); - - if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) { - mal->txde_irq = mal->rxde_irq = mal->serr_irq; - } else { - mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3); - mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4); - } - + mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3); + mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4); if (mal->txeob_irq == NO_IRQ || mal->rxeob_irq == NO_IRQ || mal->serr_irq == NO_IRQ || mal->txde_irq == NO_IRQ || mal->rxde_irq == NO_IRQ) { @@ -648,26 +608,16 @@ static int __devinit mal_probe(struct of_device *ofdev, sizeof(struct mal_descriptor) * mal_rx_bd_offset(mal, i)); - if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) { - irqflags = IRQF_SHARED; - hdlr_serr = hdlr_txde = hdlr_rxde = mal_int; - } else { - irqflags = 0; - hdlr_serr = mal_serr; - hdlr_txde = mal_txde; - hdlr_rxde = mal_rxde; - } - - err = request_irq(mal->serr_irq, hdlr_serr, irqflags, "MAL SERR", mal); + err = request_irq(mal->serr_irq, mal_serr, 0, "MAL SERR", mal); if (err) goto fail2; - err = request_irq(mal->txde_irq, hdlr_txde, irqflags, "MAL TX DE", mal); + err = request_irq(mal->txde_irq, mal_txde, 0, "MAL TX DE", mal); if (err) goto fail3; err = request_irq(mal->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal); if (err) goto fail4; - err = request_irq(mal->rxde_irq, hdlr_rxde, irqflags, "MAL RX DE", mal); + err = request_irq(mal->rxde_irq, mal_rxde, 0, "MAL RX DE", mal); if (err) goto fail5; err = request_irq(mal->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal); diff --git a/trunk/drivers/net/ibm_newemac/mal.h b/trunk/drivers/net/ibm_newemac/mal.h index 2f0a87360844..717dc38b6858 100644 --- a/trunk/drivers/net/ibm_newemac/mal.h +++ b/trunk/drivers/net/ibm_newemac/mal.h @@ -213,8 +213,6 @@ struct mal_instance { struct of_device *ofdev; int index; spinlock_t lock; - - unsigned int features; }; static inline u32 get_mal_dcrn(struct mal_instance *mal, int reg) @@ -227,38 +225,6 @@ static inline void set_mal_dcrn(struct mal_instance *mal, int reg, u32 val) dcr_write(mal->dcr_host, reg, val); } -/* Features of various MAL implementations */ - -/* Set if you have interrupt coalescing and you have to clear the SDR - * register for TXEOB and RXEOB interrupts to work - */ -#define MAL_FTR_CLEAR_ICINTSTAT 0x00000001 - -/* Set if your MAL has SERR, TXDE, and RXDE OR'd into a single UIC - * interrupt - */ -#define MAL_FTR_COMMON_ERR_INT 0x00000002 - -enum { - MAL_FTRS_ALWAYS = 0, - - MAL_FTRS_POSSIBLE = -#ifdef CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT - MAL_FTR_CLEAR_ICINTSTAT | -#endif -#ifdef CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR - MAL_FTR_COMMON_ERR_INT | -#endif - 0, -}; - -static inline int mal_has_feature(struct mal_instance *dev, - unsigned long feature) -{ - return (MAL_FTRS_ALWAYS & feature) || - (MAL_FTRS_POSSIBLE & dev->features & feature); -} - /* Register MAL devices */ int mal_init(void); void mal_exit(void); diff --git a/trunk/drivers/net/ibm_newemac/phy.c b/trunk/drivers/net/ibm_newemac/phy.c index c40cd8df2212..9164abb72d9b 100644 --- a/trunk/drivers/net/ibm_newemac/phy.c +++ b/trunk/drivers/net/ibm_newemac/phy.c @@ -38,16 +38,6 @@ static inline void phy_write(struct mii_phy *phy, int reg, int val) phy->mdio_write(phy->dev, phy->address, reg, val); } -static inline int gpcs_phy_read(struct mii_phy *phy, int reg) -{ - return phy->mdio_read(phy->dev, phy->gpcs_address, reg); -} - -static inline void gpcs_phy_write(struct mii_phy *phy, int reg, int val) -{ - phy->mdio_write(phy->dev, phy->gpcs_address, reg, val); -} - int emac_mii_reset_phy(struct mii_phy *phy) { int val; @@ -72,37 +62,6 @@ int emac_mii_reset_phy(struct mii_phy *phy) return limit <= 0; } -int emac_mii_reset_gpcs(struct mii_phy *phy) -{ - int val; - int limit = 10000; - - val = gpcs_phy_read(phy, MII_BMCR); - val &= ~(BMCR_ISOLATE | BMCR_ANENABLE); - val |= BMCR_RESET; - gpcs_phy_write(phy, MII_BMCR, val); - - udelay(300); - - while (limit--) { - val = gpcs_phy_read(phy, MII_BMCR); - if (val >= 0 && (val & BMCR_RESET) == 0) - break; - udelay(10); - } - if ((val & BMCR_ISOLATE) && limit > 0) - gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE); - - if (limit > 0 && phy->mode == PHY_MODE_SGMII) { - /* Configure GPCS interface to recommended setting for SGMII */ - gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */ - gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */ - gpcs_phy_write(phy, 0x00, 0x0140); /* 1Gbps, FDX */ - } - - return limit <= 0; -} - static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) { int ctl, adv; @@ -373,33 +332,6 @@ static int m88e1111_init(struct mii_phy *phy) return 0; } -static int m88e1112_init(struct mii_phy *phy) -{ - /* - * Marvell 88E1112 PHY needs to have the SGMII MAC - * interace (page 2) properly configured to - * communicate with the 460EX/GT GPCS interface. - */ - - u16 reg_short; - - pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__); - - /* Set access to Page 2 */ - phy_write(phy, 0x16, 0x0002); - - phy_write(phy, 0x00, 0x0040); /* 1Gbps */ - reg_short = (u16)(phy_read(phy, 0x1a)); - reg_short |= 0x8000; /* bypass Auto-Negotiation */ - phy_write(phy, 0x1a, reg_short); - emac_mii_reset_phy(phy); /* reset MAC interface */ - - /* Reset access to Page 0 */ - phy_write(phy, 0x16, 0x0000); - - return 0; -} - static int et1011c_init(struct mii_phy *phy) { u16 reg_short; @@ -452,27 +384,11 @@ static struct mii_phy_def m88e1111_phy_def = { .ops = &m88e1111_phy_ops, }; -static struct mii_phy_ops m88e1112_phy_ops = { - .init = m88e1112_init, - .setup_aneg = genmii_setup_aneg, - .setup_forced = genmii_setup_forced, - .poll_link = genmii_poll_link, - .read_link = genmii_read_link -}; - -static struct mii_phy_def m88e1112_phy_def = { - .phy_id = 0x01410C90, - .phy_id_mask = 0x0ffffff0, - .name = "Marvell 88E1112 Ethernet", - .ops = &m88e1112_phy_ops, -}; - static struct mii_phy_def *mii_phy_table[] = { &et1011c_phy_def, &cis8201_phy_def, &bcm5248_phy_def, &m88e1111_phy_def, - &m88e1112_phy_def, &genmii_phy_def, NULL }; diff --git a/trunk/drivers/net/ibm_newemac/phy.h b/trunk/drivers/net/ibm_newemac/phy.h index 5d2bf4cbe50b..1b65c81f6557 100644 --- a/trunk/drivers/net/ibm_newemac/phy.h +++ b/trunk/drivers/net/ibm_newemac/phy.h @@ -57,7 +57,6 @@ struct mii_phy { or determined automaticaly */ int address; /* PHY address */ int mode; /* PHY mode */ - int gpcs_address; /* GPCS PHY address */ /* 1: autoneg enabled, 0: disabled */ int autoneg; @@ -82,6 +81,5 @@ struct mii_phy { */ int emac_mii_phy_probe(struct mii_phy *phy, int address); int emac_mii_reset_phy(struct mii_phy *phy); -int emac_mii_reset_gpcs(struct mii_phy *phy); #endif /* __IBM_NEWEMAC_PHY_H */ diff --git a/trunk/drivers/net/ibmlana.c b/trunk/drivers/net/ibmlana.c index f02764725a22..95e3464068db 100644 --- a/trunk/drivers/net/ibmlana.c +++ b/trunk/drivers/net/ibmlana.c @@ -71,7 +71,7 @@ special acknowledgements to: June 1st, 2000 corrected version codes, added support for the latest 2.3 changes Oct 28th, 2002 - cleaned up for the 2.5 tree + cleaned up for the 2.5 tree *************************************************************************/ diff --git a/trunk/drivers/net/irda/sir_dongle.c b/trunk/drivers/net/irda/sir_dongle.c index 2a9930e6e2af..36030241f7a9 100644 --- a/trunk/drivers/net/irda/sir_dongle.c +++ b/trunk/drivers/net/irda/sir_dongle.c @@ -67,7 +67,9 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type) const struct dongle_driver *drv = NULL; int err = -EINVAL; +#ifdef CONFIG_KMOD request_module("irda-dongle-%d", type); +#endif if (dev->dongle_drv != NULL) return -EBUSY; diff --git a/trunk/drivers/net/jme.c b/trunk/drivers/net/jme.c index 81c6cdc3851f..5f9a1313fa3e 100644 --- a/trunk/drivers/net/jme.c +++ b/trunk/drivers/net/jme.c @@ -21,6 +21,7 @@ * */ +#include #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include "jme.h" static int force_pseudohp = -1; diff --git a/trunk/drivers/net/macmace.c b/trunk/drivers/net/macmace.c index 85587a6667b9..51ad3765e075 100644 --- a/trunk/drivers/net/macmace.c +++ b/trunk/drivers/net/macmace.c @@ -9,7 +9,7 @@ * 2 of the License, or (at your option) any later version. * * Copyright (C) 1996 Paul Mackerras. - * Copyright (C) 1998 Alan Cox + * Copyright (C) 1998 Alan Cox * * Modified heavily by Joshua M. Thompson based on Dave Huang's NetBSD driver * diff --git a/trunk/drivers/net/pcmcia/3c574_cs.c b/trunk/drivers/net/pcmcia/3c574_cs.c index 08c4dd896077..7112fd5e0e1b 100644 --- a/trunk/drivers/net/pcmcia/3c574_cs.c +++ b/trunk/drivers/net/pcmcia/3c574_cs.c @@ -355,10 +355,9 @@ static int tc574_config(struct pcmcia_device *link) for (i = j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == 0) - break; + if (i == CS_SUCCESS) break; } - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); goto failed; } @@ -378,7 +377,7 @@ static int tc574_config(struct pcmcia_device *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(link, &tuple) == 0) { + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(le16_to_cpu(buf[i])); diff --git a/trunk/drivers/net/pcmcia/3c589_cs.c b/trunk/drivers/net/pcmcia/3c589_cs.c index c235cdba69c6..549a64558420 100644 --- a/trunk/drivers/net/pcmcia/3c589_cs.c +++ b/trunk/drivers/net/pcmcia/3c589_cs.c @@ -15,7 +15,7 @@ incorporated herein by reference. Donald Becker may be reached at becker@scyld.com - Updated for 2.5.x by Alan Cox + Updated for 2.5.x by Alan Cox ======================================================================*/ @@ -278,10 +278,9 @@ static int tc589_config(struct pcmcia_device *link) if (multi && (j & 0x80)) continue; link->io.BasePort1 = j ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == 0) - break; + if (i == CS_SUCCESS) break; } - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); goto failed; } @@ -296,7 +295,7 @@ static int tc589_config(struct pcmcia_device *link) /* The 3c589 has an extra EEPROM for configuration info, including the hardware address. The 3c562 puts the address in the CIS. */ tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(link, &tuple) == 0) { + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(le16_to_cpu(buf[i])); diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index b37a498939ae..52bf11b73c6e 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -262,7 +262,7 @@ static int try_io_port(struct pcmcia_device *link) if (link->io.NumPorts2 > 0) { /* for master/slave multifunction cards */ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; } } else { @@ -276,8 +276,7 @@ static int try_io_port(struct pcmcia_device *link) link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; ret = pcmcia_request_io(link, &link->io); - if (ret == 0) - return ret; + if (ret == CS_SUCCESS) return ret; } return ret; } else { @@ -285,50 +284,59 @@ static int try_io_port(struct pcmcia_device *link) } } -static int axnet_configcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - int i; - cistpl_io_t *io = &cfg->io; - - if (cfg->index == 0 || cfg->io.nwin == 0) - return -ENODEV; - - p_dev->conf.ConfigIndex = 0x05; - /* For multifunction cards, by convention, we configure the - network function with window 0, and serial with window 1 */ - if (io->nwin > 1) { - i = (io->win[1].len > io->win[0].len); - p_dev->io.BasePort2 = io->win[1-i].base; - p_dev->io.NumPorts2 = io->win[1-i].len; - } else { - i = p_dev->io.NumPorts2 = 0; - } - p_dev->io.BasePort1 = io->win[i].base; - p_dev->io.NumPorts1 = io->win[i].len; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) - return try_io_port(p_dev); - - return -ENODEV; -} - static int axnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); + tuple_t tuple; + cisparse_t parse; int i, j, last_ret, last_fn; + u_short buf[64]; DECLARE_MAC_BUF(mac); DEBUG(0, "axnet_config(0x%p)\n", link); + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; - last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); - if (last_ret != 0) { + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (last_ret == CS_SUCCESS) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + cistpl_io_t *io = &(parse.cftable_entry.io); + + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0 || + cfg->index == 0 || cfg->io.nwin == 0) + goto next_entry; + + link->conf.ConfigIndex = 0x05; + /* For multifunction cards, by convention, we configure the + network function with window 0, and serial with window 1 */ + if (io->nwin > 1) { + i = (io->win[1].len > io->win[0].len); + link->io.BasePort2 = io->win[1-i].base; + link->io.NumPorts2 = io->win[1-i].len; + } else { + i = link->io.NumPorts2 = 0; + } + link->io.BasePort1 = io->win[i].base; + link->io.NumPorts1 = io->win[i].len; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { + last_ret = try_io_port(link); + if (last_ret == CS_SUCCESS) break; + } + next_entry: + last_ret = pcmcia_get_next_tuple(link, &tuple); + } + if (last_ret != CS_SUCCESS) { cs_error(link, RequestIO, last_ret); goto failed; } diff --git a/trunk/drivers/net/pcmcia/com20020_cs.c b/trunk/drivers/net/pcmcia/com20020_cs.c index 831090c75622..ea9414c4d900 100644 --- a/trunk/drivers/net/pcmcia/com20020_cs.c +++ b/trunk/drivers/net/pcmcia/com20020_cs.c @@ -260,21 +260,21 @@ static int com20020_config(struct pcmcia_device *link) DEBUG(0, "com20020_config(0x%p)\n", link); DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); - i = -ENODEV; + i = !CS_SUCCESS; if (!link->io.BasePort1) { for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; i = pcmcia_request_io(link, &link->io); - if (i == 0) + if (i == CS_SUCCESS) break; } } else i = pcmcia_request_io(link, &link->io); - if (i != 0) + if (i != CS_SUCCESS) { DEBUG(1,"arcnet: requestIO failed totally!\n"); goto failed; @@ -287,7 +287,7 @@ static int com20020_config(struct pcmcia_device *link) link->irq.AssignedIRQ, link->irq.IRQInfo1, link->irq.IRQInfo2); i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if (i != CS_SUCCESS) { DEBUG(1,"arcnet: requestIRQ failed totally!\n"); goto failed; diff --git a/trunk/drivers/net/pcmcia/fmvj18x_cs.c b/trunk/drivers/net/pcmcia/fmvj18x_cs.c index 69d916daa7bb..a550c9bd126f 100644 --- a/trunk/drivers/net/pcmcia/fmvj18x_cs.c +++ b/trunk/drivers/net/pcmcia/fmvj18x_cs.c @@ -309,8 +309,7 @@ static int mfc_try_io_port(struct pcmcia_device *link) printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); } ret = pcmcia_request_io(link, &link->io); - if (ret == 0) - return ret; + if (ret == CS_SUCCESS) return ret; } return ret; } @@ -326,7 +325,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link) for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) { link->io.BasePort1 = ioaddr; ret = pcmcia_request_io(link, &link->io); - if (ret == 0) { + if (ret == CS_SUCCESS) { /* calculate ConfigIndex value */ link->conf.ConfigIndex = ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22; @@ -357,12 +356,12 @@ static int fmvj18x_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(link, &tuple) == 0) { + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigIndex = parse.cftable_entry.index; switch (link->manf_id) { case MANFID_TDK: @@ -431,10 +430,10 @@ static int fmvj18x_config(struct pcmcia_device *link) link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ret = mfc_try_io_port(link); - if (ret != 0) goto cs_failed; + if (ret != CS_SUCCESS) goto cs_failed; } else if (cardtype == UNGERMANN) { ret = ungermann_try_io_port(link); - if (ret != 0) goto cs_failed; + if (ret != CS_SUCCESS) goto cs_failed; } else { CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } @@ -566,7 +565,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) req.Base = 0; req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestWindow, i); return -1; } @@ -600,7 +599,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) iounmap(base); j = pcmcia_release_window(link->win); - if (j != 0) + if (j != CS_SUCCESS) cs_error(link, ReleaseWindow, j); return (i != 0x200) ? 0 : -1; @@ -621,7 +620,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) req.Base = 0; req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestWindow, i); return -1; } @@ -643,7 +642,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) iounmap(base); j = pcmcia_release_window(link->win); - if (j != 0) + if (j != CS_SUCCESS) cs_error(link, ReleaseWindow, j); return 0; diff --git a/trunk/drivers/net/pcmcia/ibmtr_cs.c b/trunk/drivers/net/pcmcia/ibmtr_cs.c index cf3cca4642f2..4eafa4f42cff 100644 --- a/trunk/drivers/net/pcmcia/ibmtr_cs.c +++ b/trunk/drivers/net/pcmcia/ibmtr_cs.c @@ -238,7 +238,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) /* Try PRIMARY card at 0xA20-0xA23 */ link->io.BasePort1 = 0xA20; i = pcmcia_request_io(link, &link->io); - if (i != 0) { + if (i != CS_SUCCESS) { /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ link->io.BasePort1 = 0xA24; CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); diff --git a/trunk/drivers/net/pcmcia/nmclan_cs.c b/trunk/drivers/net/pcmcia/nmclan_cs.c index 448cd40aeba5..cfcbea9b7e2e 100644 --- a/trunk/drivers/net/pcmcia/nmclan_cs.c +++ b/trunk/drivers/net/pcmcia/nmclan_cs.c @@ -69,7 +69,7 @@ Driver Notes and Issues History ------------------------------------------------------------------------------- Log: nmclan_cs.c,v - * 2.5.75-ac1 2003/07/11 Alan Cox + * 2.5.75-ac1 2003/07/11 Alan Cox * Fixed hang on card eject as we probe it * Cleaned up to use new style locking. * @@ -925,7 +925,7 @@ static void mace_tx_timeout(struct net_device *dev) printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); #if RESET_ON_TIMEOUT printk("resetting card\n"); - pcmcia_reset_card(link->socket); + pcmcia_reset_card(link, NULL); #else /* #if RESET_ON_TIMEOUT */ printk("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index e40d6301aa7a..ebc1ae6bcbe5 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -310,7 +310,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) req.Base = 0; req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestWindow, i); return NULL; } @@ -333,7 +333,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) iounmap(virt); j = pcmcia_release_window(link->win); - if (j != 0) + if (j != CS_SUCCESS) cs_error(link, ReleaseWindow, j); return (i < NR_INFO) ? hw_info+i : NULL; } /* get_hwinfo */ @@ -504,8 +504,7 @@ static int try_io_port(struct pcmcia_device *link) link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; ret = pcmcia_request_io(link, &link->io); - if (ret == 0) - return ret; + if (ret == CS_SUCCESS) return ret; } return ret; } else { @@ -513,53 +512,58 @@ static int try_io_port(struct pcmcia_device *link) } } -static int pcnet_confcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - int *has_shmem = priv_data; - int i; - cistpl_io_t *io = &cfg->io; - - if (cfg->index == 0 || cfg->io.nwin == 0) - return -EINVAL; - - /* For multifunction cards, by convention, we configure the - network function with window 0, and serial with window 1 */ - if (io->nwin > 1) { - i = (io->win[1].len > io->win[0].len); - p_dev->io.BasePort2 = io->win[1-i].base; - p_dev->io.NumPorts2 = io->win[1-i].len; - } else { - i = p_dev->io.NumPorts2 = 0; - } - - *has_shmem = ((cfg->mem.nwin == 1) && - (cfg->mem.win[0].len >= 0x4000)); - p_dev->io.BasePort1 = io->win[i].base; - p_dev->io.NumPorts1 = io->win[i].len; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) - return try_io_port(p_dev); - - return 0; -} - static int pcnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); - int last_ret, last_fn, start_pg, stop_pg, cm_offset; + tuple_t tuple; + cisparse_t parse; + int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; + u_short buf[64]; hw_info_t *local_hw_info; DECLARE_MAC_BUF(mac); DEBUG(0, "pcnet_config(0x%p)\n", link); - last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); - if (last_ret) { + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (last_ret == CS_SUCCESS) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + cistpl_io_t *io = &(parse.cftable_entry.io); + + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0 || + cfg->index == 0 || cfg->io.nwin == 0) + goto next_entry; + + link->conf.ConfigIndex = cfg->index; + /* For multifunction cards, by convention, we configure the + network function with window 0, and serial with window 1 */ + if (io->nwin > 1) { + i = (io->win[1].len > io->win[0].len); + link->io.BasePort2 = io->win[1-i].base; + link->io.NumPorts2 = io->win[1-i].len; + } else { + i = link->io.NumPorts2 = 0; + } + has_shmem = ((cfg->mem.nwin == 1) && + (cfg->mem.win[0].len >= 0x4000)); + link->io.BasePort1 = io->win[i].base; + link->io.NumPorts1 = io->win[i].len; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { + last_ret = try_io_port(link); + if (last_ret == CS_SUCCESS) break; + } + next_entry: + last_ret = pcmcia_get_next_tuple(link, &tuple); + } + if (last_ret != CS_SUCCESS) { cs_error(link, RequestIO, last_ret); goto failed; } diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index c74d6656d266..250eb1954c34 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -409,13 +409,10 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, { int i; - i = pcmcia_get_first_tuple(handle, tuple); - if (i != 0) + if ((i = pcmcia_get_first_tuple(handle, tuple)) != CS_SUCCESS || + (i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS) return i; - i = pcmcia_get_tuple_data(handle, tuple); - if (i != 0) - return i; - return pcmcia_parse_tuple(tuple, parse); + return pcmcia_parse_tuple(handle, tuple, parse); } static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, @@ -423,10 +420,10 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, { int i; - if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 || - (i = pcmcia_get_tuple_data(handle, tuple)) != 0) + if ((i = pcmcia_get_next_tuple(handle, tuple)) != CS_SUCCESS || + (i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS) return i; - return pcmcia_parse_tuple(tuple, parse); + return pcmcia_parse_tuple(handle, tuple, parse); } /*====================================================================== @@ -462,36 +459,27 @@ static int mhz_3288_power(struct pcmcia_device *link) return 0; } -static int mhz_mfc_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - int k; - p_dev->io.BasePort2 = cf->io.win[0].base; - for (k = 0; k < 0x400; k += 0x10) { - if (k & 0x80) - continue; - p_dev->io.BasePort1 = k ^ 0x300; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; -} - static int mhz_mfc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; + tuple_t *tuple; + cisparse_t *parse; + cistpl_cftable_entry_t *cf; + u_char *buf; win_req_t req; memreq_t mem; - int i; + int i, k; cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) - return -ENOMEM; + return CS_OUT_OF_RESOURCE; + + tuple = &cfg_mem->tuple; + parse = &cfg_mem->parse; + cf = &parse->cftable_entry; + buf = cfg_mem->buf; link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; @@ -501,9 +489,27 @@ static int mhz_mfc_config(struct pcmcia_device *link) link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; + tuple->Attributes = tuple->TupleOffset = 0; + tuple->TupleData = (cisdata_t *)buf; + tuple->TupleDataMax = 255; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + + i = first_tuple(link, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ - if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) + while (i == CS_SUCCESS) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort2 = cf->io.win[0].base; + for (k = 0; k < 0x400; k += 0x10) { + if (k & 0x80) continue; + link->io.BasePort1 = k ^ 0x300; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } + if (i == CS_SUCCESS) break; + i = next_tuple(link, tuple, parse); + } + if (i != CS_SUCCESS) goto free_cfg_mem; dev->base_addr = link->io.BasePort1; @@ -512,7 +518,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) req.Base = req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != 0) + if (i != CS_SUCCESS) goto free_cfg_mem; smc->base = ioremap(req.Base, req.Size); mem.CardOffset = mem.Page = 0; @@ -520,14 +526,14 @@ static int mhz_mfc_config(struct pcmcia_device *link) mem.CardOffset = link->conf.ConfigBase; i = pcmcia_map_mem_page(link->win, &mem); - if ((i == 0) + if ((i == CS_SUCCESS) && (smc->manfid == MANFID_MEGAHERTZ) && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) mhz_3288_power(link); free_cfg_mem: kfree(cfg_mem); - return -ENODEV; + return i; } static int mhz_setup(struct pcmcia_device *link) @@ -554,12 +560,12 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != 0) { + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (next_tuple(link, tuple, parse) != 0) + if (next_tuple(link, tuple, parse) != CS_SUCCESS) first_tuple(link, tuple, parse); if (parse->version_1.ns > 3) { station_addr = parse->version_1.str + parse->version_1.ofs[3]; @@ -571,11 +577,11 @@ static int mhz_setup(struct pcmcia_device *link) /* Another possibility: for the EM3288, in a special tuple */ tuple->DesiredTuple = 0x81; - if (pcmcia_get_first_tuple(link, tuple) != 0) { + if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } - if (pcmcia_get_tuple_data(link, tuple) != 0) { + if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -654,27 +660,46 @@ static int mot_setup(struct pcmcia_device *link) /*====================================================================*/ -static int smc_configcheck(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - return pcmcia_request_io(p_dev, &p_dev->io); -} - static int smc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; + struct smc_cfg_mem *cfg_mem; + tuple_t *tuple; + cisparse_t *parse; + cistpl_cftable_entry_t *cf; + u_char *buf; int i; + cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); + if (!cfg_mem) + return CS_OUT_OF_RESOURCE; + + tuple = &cfg_mem->tuple; + parse = &cfg_mem->parse; + cf = &parse->cftable_entry; + buf = cfg_mem->buf; + + tuple->Attributes = tuple->TupleOffset = 0; + tuple->TupleData = (cisdata_t *)buf; + tuple->TupleDataMax = 255; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + link->io.NumPorts1 = 16; - i = pcmcia_loop_config(link, smc_configcheck, NULL); - if (!i) - dev->base_addr = link->io.BasePort1; + i = first_tuple(link, tuple, parse); + while (i != CS_NO_MORE_ITEMS) { + if (i == CS_SUCCESS) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } + i = next_tuple(link, tuple, parse); + } + if (i == CS_SUCCESS) + dev->base_addr = link->io.BasePort1; + kfree(cfg_mem); return i; } @@ -690,7 +715,7 @@ static int smc_setup(struct pcmcia_device *link) cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) - return -ENOMEM; + return CS_OUT_OF_RESOURCE; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; @@ -703,12 +728,12 @@ static int smc_setup(struct pcmcia_device *link) /* Check for a LAN function extension tuple */ tuple->DesiredTuple = CISTPL_FUNCE; i = first_tuple(link, tuple, parse); - while (i == 0) { + while (i == CS_SUCCESS) { if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID) break; i = next_tuple(link, tuple, parse); } - if (i == 0) { + if (i == CS_SUCCESS) { node_id = (cistpl_lan_node_id_t *)parse->funce.data; if (node_id->nb == 6) { for (i = 0; i < 6; i++) @@ -755,10 +780,9 @@ static int osi_config(struct pcmcia_device *link) for (i = j = 0; j < 4; j++) { link->io.BasePort2 = com[j]; i = pcmcia_request_io(link, &link->io); - if (i == 0) - break; + if (i == CS_SUCCESS) break; } - if (i != 0) { + if (i != CS_SUCCESS) { /* Fallback: turn off hard decode */ link->conf.ConfigIndex = 0x03; link->io.NumPorts2 = 0; @@ -791,13 +815,13 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) /* Read the station address from tuple 0x90, subtuple 0x04 */ tuple->DesiredTuple = 0x90; i = pcmcia_get_first_tuple(link, tuple); - while (i == 0) { + while (i == CS_SUCCESS) { i = pcmcia_get_tuple_data(link, tuple); - if ((i != 0) || (buf[0] == 0x04)) + if ((i != CS_SUCCESS) || (buf[0] == 0x04)) break; i = pcmcia_get_next_tuple(link, tuple); } - if (i != 0) { + if (i != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -935,11 +959,8 @@ static int check_sig(struct pcmcia_device *link) ======================================================================*/ -#define CS_EXIT_TEST(ret, svc, label) \ -if (ret != 0) { \ - cs_error(link, svc, ret); \ - goto label; \ -} +#define CS_EXIT_TEST(ret, svc, label) \ +if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; } static int smc91c92_config(struct pcmcia_device *link) { diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index e1fd585e7131..c33a3d523566 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -377,7 +377,7 @@ first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 && (err = pcmcia_get_tuple_data(handle, tuple)) == 0) - err = pcmcia_parse_tuple(tuple, parse); + err = pcmcia_parse_tuple(handle, tuple, parse); return err; } @@ -388,7 +388,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 && (err = pcmcia_get_tuple_data(handle, tuple)) == 0) - err = pcmcia_parse_tuple(tuple, parse); + err = pcmcia_parse_tuple(handle, tuple, parse); return err; } @@ -715,47 +715,6 @@ has_ce2_string(struct pcmcia_device * p_dev) return 0; } -static int -xirc2ps_config_modem(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - unsigned int ioaddr; - - if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { - for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { - p_dev->io.BasePort2 = cf->io.win[0].base; - p_dev->io.BasePort1 = ioaddr; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - } - return -ENODEV; -} - -static int -xirc2ps_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - int *pass = priv_data; - - if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { - p_dev->io.BasePort2 = cf->io.win[0].base; - p_dev->io.BasePort1 = p_dev->io.BasePort2 - + (*pass ? (cf->index & 0x20 ? -24:8) - : (cf->index & 0x20 ? 8:-24)); - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; - -} - /**************** * xirc2ps_config() is scheduled to run after a CARD_INSERTION event * is received, to configure the PCMCIA socket, and to make the @@ -766,12 +725,13 @@ xirc2ps_config(struct pcmcia_device * link) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); - unsigned int ioaddr; tuple_t tuple; cisparse_t parse; + unsigned int ioaddr; int err, i; u_char buf[64]; cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; DECLARE_MAC_BUF(mac); local->dingo_ccr = NULL; @@ -886,8 +846,19 @@ xirc2ps_config(struct pcmcia_device * link) /* Take the Modem IO port from the CIS and scan for a free * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ - if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) - goto port_found; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)) { + if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { + for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { + link->conf.ConfigIndex = cf->index ; + link->io.BasePort2 = cf->io.win[0].base; + link->io.BasePort1 = ioaddr; + if (!(err=pcmcia_request_io(link, &link->io))) + goto port_found; + } + } + } } else { link->io.NumPorts1 = 18; /* We do 2 passes here: The first one uses the regular mapping and @@ -895,9 +866,21 @@ xirc2ps_config(struct pcmcia_device * link) * mirrored every 32 bytes. Actually we use a mirrored port for * the Mako if (on the first pass) the COR bit 5 is set. */ - for (pass=0; pass < 2; pass++) - if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass)) + for (pass=0; pass < 2; pass++) { + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)){ + if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ + link->conf.ConfigIndex = cf->index ; + link->io.BasePort2 = cf->io.win[0].base; + link->io.BasePort1 = link->io.BasePort2 + + (pass ? (cf->index & 0x20 ? -24:8) + : (cf->index & 0x20 ? 8:-24)); + if (!(err=pcmcia_request_io(link, &link->io))) goto port_found; + } + } + } /* if special option: * try to configure as Ethernet only. * .... */ diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index d0ed1ef284a8..6671e2da0d57 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -55,7 +55,6 @@ EXPORT_SYMBOL(mdiobus_alloc); /** * mdiobus_release - mii_bus device release callback - * @d: the target struct device that contains the mii_bus * * Description: called when the last reference to an mii_bus is * dropped, to free the underlying memory. diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index e11b03b2b25a..171627480058 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -309,6 +309,11 @@ void phy_disconnect(struct phy_device *phydev) } EXPORT_SYMBOL(phy_disconnect); +static int phy_compare_id(struct device *dev, void *data) +{ + return strcmp((char *)data, dev->bus_id) ? 0 : 1; +} + /** * phy_attach - attach a network device to a particular PHY device * @dev: network device to attach @@ -332,7 +337,8 @@ struct phy_device *phy_attach(struct net_device *dev, /* Search the list of PHY devices on the mdio bus for the * PHY with the requested name */ - d = bus_find_device_by_name(bus, NULL, bus_id); + d = bus_find_device(bus, NULL, (void *)bus_id, phy_compare_id); + if (d) { phydev = to_phy_device(d); } else { @@ -551,7 +557,6 @@ int genphy_restart_aneg(struct phy_device *phydev) return ctl; } -EXPORT_SYMBOL(genphy_restart_aneg); /** diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 7e857e938adb..0ca0fcbb7c01 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -866,8 +866,8 @@ static int __init ppp_init(void) err = PTR_ERR(ppp_class); goto out_chrdev; } - device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, - "ppp"); + device_create_drvdata(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), + NULL, "ppp"); } out: @@ -2127,9 +2127,13 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg) || ccp_option[1] < 2 || ccp_option[1] > data.length) goto out; - cp = try_then_request_module( - find_compressor(ccp_option[0]), - "ppp-compress-%d", ccp_option[0]); + cp = find_compressor(ccp_option[0]); +#ifdef CONFIG_KMOD + if (!cp) { + request_module("ppp-compress-%d", ccp_option[0]); + cp = find_compressor(ccp_option[0]); + } +#endif /* CONFIG_KMOD */ if (!cp) goto out; diff --git a/trunk/drivers/net/pppox.c b/trunk/drivers/net/pppox.c index 03aecc97fb45..c6898c1fc54d 100644 --- a/trunk/drivers/net/pppox.c +++ b/trunk/drivers/net/pppox.c @@ -115,8 +115,13 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol) goto out; rc = -EPROTONOSUPPORT; - if (!pppox_protos[protocol]) - request_module("pppox-proto-%d", protocol); +#ifdef CONFIG_KMOD + if (!pppox_protos[protocol]) { + char buffer[32]; + sprintf(buffer, "pppox-proto-%d", protocol); + request_module(buffer); + } +#endif if (!pppox_protos[protocol] || !try_module_get(pppox_protos[protocol]->owner)) goto out; diff --git a/trunk/drivers/net/qlge/qlge.h b/trunk/drivers/net/qlge/qlge.h index 38116f9d4163..c37ea436c918 100644 --- a/trunk/drivers/net/qlge/qlge.h +++ b/trunk/drivers/net/qlge/qlge.h @@ -58,7 +58,7 @@ */ #if (PAGE_SHIFT == 12) || (PAGE_SHIFT == 13) /* 4k & 8k pages */ #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) -#else /* all other page sizes */ +#elif (PAGE_SHIFT == 16) /* 64k pages */ #define TX_DESC_PER_OAL 0 #endif diff --git a/trunk/drivers/net/qlge/qlge_ethtool.c b/trunk/drivers/net/qlge/qlge_ethtool.c index b62fbd4bf00f..6457f8c4fdaa 100644 --- a/trunk/drivers/net/qlge/qlge_ethtool.c +++ b/trunk/drivers/net/qlge/qlge_ethtool.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/qlge/qlge_main.c b/trunk/drivers/net/qlge/qlge_main.c index 4b2caa6b7ac5..3af822b6226e 100644 --- a/trunk/drivers/net/qlge/qlge_main.c +++ b/trunk/drivers/net/qlge/qlge_main.c @@ -36,10 +36,10 @@ #include #include #include +#include #include #include #include -#include #include "qlge.h" diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index c821da21d8eb..bdae2c59a750 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -2154,8 +2154,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&tp->lock); - tp->mmio_addr = ioaddr; - rtl_init_mac_address(tp, ioaddr); /* Get MAC address */ @@ -2188,6 +2186,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #endif tp->intr_mask = 0xffff; + tp->mmio_addr = ioaddr; tp->align = cfg->align; tp->hw_start = cfg->hw_start; tp->intr_event = cfg->intr_event; diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 3813d15e2df7..3805b9318be7 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -3034,8 +3034,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; - if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) - || !device_can_wakeup(&hw->pdev->dev)) + if (wol->wolopts & ~sky2_wol_supported(sky2->hw)) return -EOPNOTSUPP; sky2->wol = wol->wolopts; @@ -3046,8 +3045,6 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) sky2_write32(hw, B0_CTST, sky2->wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); - device_set_wakeup_enable(&hw->pdev->dev, sky2->wol); - if (!netif_running(dev)) sky2_wol_init(sky2); return 0; @@ -4182,6 +4179,18 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) return err; } +static int __devinit pci_wake_enabled(struct pci_dev *dev) +{ + int pm = pci_find_capability(dev, PCI_CAP_ID_PM); + u16 value; + + if (!pm) + return 0; + if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value)) + return 0; + return value & PCI_PM_CTRL_PME_ENABLE; +} + /* * Read and parse the first part of Vital Product Data */ @@ -4305,7 +4314,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, } } - wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0; + wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0; err = -ENOMEM; hw = kzalloc(sizeof(*hw), GFP_KERNEL); diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c index 8aa7460ef0e3..3d19d00e8eec 100644 --- a/trunk/drivers/net/smc911x.c +++ b/trunk/drivers/net/smc911x.c @@ -685,10 +685,8 @@ static void smc911x_phy_detect(struct net_device *dev) * PHY#1 to PHY#31, and then PHY#0 last. */ switch(lp->version) { - case CHIP_9115: - case CHIP_9117: - case CHIP_9215: - case CHIP_9217: + case 0x115: + case 0x117: cfg = SMC_GET_HW_CFG(lp); if (cfg & HW_CFG_EXT_PHY_DET_) { cfg &= ~HW_CFG_PHY_CLK_SEL_; diff --git a/trunk/drivers/net/smc911x.h b/trunk/drivers/net/smc911x.h index bf6240f23f5d..2abfc2845198 100644 --- a/trunk/drivers/net/smc911x.h +++ b/trunk/drivers/net/smc911x.h @@ -666,13 +666,10 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr, #define LAN911X_INTERNAL_PHY_ID (0x0007C000) /* Chip ID values */ -#define CHIP_9115 0x0115 -#define CHIP_9116 0x0116 -#define CHIP_9117 0x0117 -#define CHIP_9118 0x0118 -#define CHIP_9215 0x115A -#define CHIP_9217 0x117A -#define CHIP_9218 0x118A +#define CHIP_9115 0x115 +#define CHIP_9116 0x116 +#define CHIP_9117 0x117 +#define CHIP_9118 0x118 struct chip_id { u16 id; @@ -684,9 +681,6 @@ static const struct chip_id chip_ids[] = { { CHIP_9116, "LAN9116" }, { CHIP_9117, "LAN9117" }, { CHIP_9118, "LAN9118" }, - { CHIP_9215, "LAN9215" }, - { CHIP_9217, "LAN9217" }, - { CHIP_9218, "LAN9218" }, { 0, NULL }, }; diff --git a/trunk/drivers/net/tc35815.c b/trunk/drivers/net/tc35815.c index df20cafff7dd..4980b12b6219 100644 --- a/trunk/drivers/net/tc35815.c +++ b/trunk/drivers/net/tc35815.c @@ -796,7 +796,7 @@ static int tc_mii_init(struct net_device *dev) mdiobus_unregister(lp->mii_bus); err_out_free_mdio_irq: kfree(lp->mii_bus->irq); -err_out_free_mii_bus: +err_out_free_mii_bus; mdiobus_free(lp->mii_bus); err_out: return err; diff --git a/trunk/drivers/net/tlan.c b/trunk/drivers/net/tlan.c index c41d68761364..ec871f646766 100644 --- a/trunk/drivers/net/tlan.c +++ b/trunk/drivers/net/tlan.c @@ -29,8 +29,7 @@ * * Tigran Aivazian : TLan_PciProbe() now uses * new PCI BIOS interface. - * Alan Cox : - * Fixed the out of memory + * Alan Cox : Fixed the out of memory * handling. * * Torben Mathiasen New Maintainer! diff --git a/trunk/drivers/net/tokenring/smctr.c b/trunk/drivers/net/tokenring/smctr.c index ed50d288e494..fa73e6eed6be 100644 --- a/trunk/drivers/net/tokenring/smctr.c +++ b/trunk/drivers/net/tokenring/smctr.c @@ -25,7 +25,7 @@ * To do: * 1. Multicast support. * - * Initial 2.5 cleanup Alan Cox 2002/10/28 + * Initial 2.5 cleanup Alan Cox 2002/10/28 */ #include diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index 124d5d690dde..f54c45049d50 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -1688,7 +1688,6 @@ static void __devinit de21040_get_mac_address (struct de_private *de) unsigned i; dw32 (ROMCmd, 0); /* Reset the pointer with a dummy write. */ - udelay(5); for (i = 0; i < 6; i++) { int value, boguscnt = 100000; diff --git a/trunk/drivers/net/tulip/dmfe.c b/trunk/drivers/net/tulip/dmfe.c index 8e46a513a252..656200472fa1 100644 --- a/trunk/drivers/net/tulip/dmfe.c +++ b/trunk/drivers/net/tulip/dmfe.c @@ -23,7 +23,7 @@ Marcelo Tosatti : Made it compile in 2.3 (device to net_device) - Alan Cox : + Alan Cox : Cleaned up for kernel merge. Removed the back compatibility support Reformatted, fixing spelling etc as I went @@ -49,7 +49,7 @@ support. Updated PCI resource allocation. Do not forget to unmap PCI mapped skbs. - Alan Cox + Alan Cox Added new PCI identifiers provided by Clear Zhang at ALi for their 1563 ethernet device. diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index 2dced383bcfb..ad20f96edfa1 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -12,7 +12,7 @@ * Scatter gather * More testing * - * The changes are (c) Copyright 2004, Red Hat Inc. + * The changes are (c) Copyright 2004, Red Hat Inc. * Additional fixes and clean up: Francois Romieu * * This source has not been verified for use in safety critical systems. diff --git a/trunk/drivers/net/wan/Kconfig b/trunk/drivers/net/wan/Kconfig index 21efd99b9294..2ae2ec40015d 100644 --- a/trunk/drivers/net/wan/Kconfig +++ b/trunk/drivers/net/wan/Kconfig @@ -205,7 +205,7 @@ config WANXL_BUILD_FIRMWARE config PC300 tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" - depends on HDLC && PCI && BROKEN + depends on HDLC && PCI ---help--- Driver for the Cyclades-PC300 synchronous communication boards. diff --git a/trunk/drivers/net/wan/cosa.c b/trunk/drivers/net/wan/cosa.c index 7f97f8d08c39..f14051556c87 100644 --- a/trunk/drivers/net/wan/cosa.c +++ b/trunk/drivers/net/wan/cosa.c @@ -388,8 +388,8 @@ static int __init cosa_init(void) goto out_chrdev; } for (i = 0; i < nr_cards; i++) - device_create(cosa_class, NULL, MKDEV(cosa_major, i), NULL, - "cosa%d", i); + device_create_drvdata(cosa_class, NULL, MKDEV(cosa_major, i), + NULL, "cosa%d", i); err = 0; goto out; diff --git a/trunk/drivers/net/wan/z85230.c b/trunk/drivers/net/wan/z85230.c index ccd9cd35ecbe..243bd8d918fe 100644 --- a/trunk/drivers/net/wan/z85230.c +++ b/trunk/drivers/net/wan/z85230.c @@ -18,8 +18,7 @@ * DMA now uses get_free_page as kmalloc buffers may span a 64K * boundary. * - * Modified for SMP safety and SMP locking by Alan Cox - * + * Modified for SMP safety and SMP locking by Alan Cox * * Performance * diff --git a/trunk/drivers/net/wan/z85230.h b/trunk/drivers/net/wan/z85230.h index 85b3e785d484..4f372396c512 100644 --- a/trunk/drivers/net/wan/z85230.h +++ b/trunk/drivers/net/wan/z85230.h @@ -2,7 +2,7 @@ * Description of Z8530 Z85C30 and Z85230 communications chips * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1998 Alan Cox + * Copyright (C) 1998 Alan Cox */ #ifndef _Z8530_H diff --git a/trunk/drivers/net/wireless/airo_cs.c b/trunk/drivers/net/wireless/airo_cs.c index 27696c20f4c2..fd72e427cb28 100644 --- a/trunk/drivers/net/wireless/airo_cs.c +++ b/trunk/drivers/net/wireless/airo_cs.c @@ -206,123 +206,126 @@ static void airo_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int airo_cs_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - win_req_t *req = priv_data; - - if (cfg->index == 0) - return -ENODEV; - - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - p_dev->conf.Attributes |= CONF_ENABLE_SPKR; - p_dev->conf.Status = CCSR_AUDIO_ENA; - } - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vpp1.present & (1<conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt->vpp1.present & (1<conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - } - - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) - return -ENODEV; - - /* - Now set up a common memory window, if needed. There is room - in the struct pcmcia_device structure for one memory window handle, - but if the base addresses need to be saved, or if multiple - windows are needed, the info should go in the private data - structure for this device. - - Note that the memory window base is a physical address, and - needs to be mapped to virtual space with ioremap() before it - is used. - */ - if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { - cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; - memreq_t map; - req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; - req->Base = mem->win[0].host_addr; - req->Size = mem->win[0].len; - req->AccessSpeed = 0; - if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0) - return -ENODEV; - map.Page = 0; - map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(p_dev->win, &map) != 0) - return -ENODEV; - } - /* If we got this far, we're cool! */ - return 0; -} - - static int airo_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; local_info_t *dev; - win_req_t *req; int last_fn, last_ret; + u_char buf[64]; + win_req_t req; + memreq_t map; dev = link->priv; DEBUG(0, "airo_config(0x%p)\n", link); - req = kzalloc(sizeof(win_req_t), GFP_KERNEL); - if (!req) - return -ENOMEM; - - /* - * In this loop, we scan the CIS for configuration table - * entries, each of which describes a valid card - * configuration, including voltage, IO window, memory window, - * and interrupt settings. - * - * We make no assumptions about the card to be configured: we - * use just the information available in the CIS. In an ideal - * world, this would work for any PCMCIA card, but it requires - * a complete and accurate CIS. In practice, a driver usually - * "knows" most of these things without consulting the CIS, - * and most client drivers will only use the CIS to fill in - * implementation-defined details. - */ - last_ret = pcmcia_loop_config(link, airo_cs_config_check, req); - if (last_ret) - goto failed; - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. + In this loop, we scan the CIS for configuration table entries, + each of which describes a valid card configuration, including + voltage, IO window, memory window, and interrupt settings. + + We make no assumptions about the card to be configured: we use + just the information available in the CIS. In an ideal world, + this would work for any PCMCIA card, but it requires a complete + and accurate CIS. In practice, a driver usually "knows" most of + these things without consulting the CIS, and most client drivers + will only use the CIS to fill in implementation-defined details. */ + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t dflt = { 0 }; + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; + if (cfg->index == 0) goto next_entry; + link->conf.ConfigIndex = cfg->index; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vpp1.present & (1<conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vpp1.present & (1<conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) + link->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + } + + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + + /* + Now set up a common memory window, if needed. There is room + in the struct pcmcia_device structure for one memory window handle, + but if the base addresses need to be saved, or if multiple + windows are needed, the info should go in the private data + structure for this device. + + Note that the memory window base is a physical address, and + needs to be mapped to virtual space with ioremap() before it + is used. + */ + if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; + req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; + req.Base = mem->win[0].host_addr; + req.Size = mem->win[0].len; + req.AccessSpeed = 0; + if (pcmcia_request_window(&link, &req, &link->win) != 0) + goto next_entry; + map.Page = 0; map.CardOffset = mem->win[0].card_addr; + if (pcmcia_map_mem_page(link->win, &map) != 0) + goto next_entry; + } + /* If we got this far, we're cool! */ + break; + + next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } + + /* + Allocate an interrupt line. Note that this does not assign a + handler to the interrupt, unless the 'Handler' member of the + irq structure is initialized. + */ if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -359,17 +362,14 @@ static int airo_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) - printk(", mem 0x%06lx-0x%06lx", req->Base, - req->Base+req->Size-1); + printk(", mem 0x%06lx-0x%06lx", req.Base, + req.Base+req.Size-1); printk("\n"); - kfree(req); return 0; cs_failed: cs_error(link, last_fn, last_ret); - failed: airo_release(link); - kfree(req); return -ENODEV; } /* airo_config */ diff --git a/trunk/drivers/net/wireless/ath9k/main.c b/trunk/drivers/net/wireless/ath9k/main.c index f05f584ab7bc..74726990d59e 100644 --- a/trunk/drivers/net/wireless/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath9k/main.c @@ -1640,11 +1640,6 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, return ret; } -static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value) -{ - return -EOPNOTSUPP; -} - static struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -1669,8 +1664,7 @@ static struct ieee80211_ops ath9k_ops = { .get_tsf = ath9k_get_tsf, .reset_tsf = ath9k_reset_tsf, .tx_last_beacon = NULL, - .ampdu_action = ath9k_ampdu_action, - .set_frag_threshold = ath9k_no_fragmentation, + .ampdu_action = ath9k_ampdu_action }; static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/trunk/drivers/net/wireless/atmel_cs.c b/trunk/drivers/net/wireless/atmel_cs.c index 77406245dc7b..d2388e8d179a 100644 --- a/trunk/drivers/net/wireless/atmel_cs.c +++ b/trunk/drivers/net/wireless/atmel_cs.c @@ -224,58 +224,13 @@ static int card_present(void *arg) return 0; } -static int atmel_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if (cfg->index == 0) - return -ENODEV; - - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - p_dev->conf.Attributes |= CONF_ENABLE_SPKR; - p_dev->conf.Status = CCSR_AUDIO_ENA; - } - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vpp1.present & (1<conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt->vpp1.present & (1<conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - } - - /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); -} - static int atmel_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; local_info_t *dev; int last_fn, last_ret; + u_char buf[64]; struct pcmcia_device_id *did; dev = link->priv; @@ -283,6 +238,11 @@ static int atmel_config(struct pcmcia_device *link) DEBUG(0, "atmel_config(0x%p)\n", link); + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including @@ -295,8 +255,66 @@ static int atmel_config(struct pcmcia_device *link) these things without consulting the CIS, and most client drivers will only use the CIS to fill in implementation-defined details. */ - if (pcmcia_loop_config(link, atmel_config_check, NULL)) - goto failed; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t dflt = { 0 }; + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; + if (cfg->index == 0) goto next_entry; + link->conf.ConfigIndex = cfg->index; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vpp1.present & (1<conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vpp1.present & (1<conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) + link->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + } + + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + + /* If we got this far, we're cool! */ + break; + + next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } /* Allocate an interrupt line. Note that this does not assign a @@ -342,7 +360,6 @@ static int atmel_config(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); - failed: atmel_release(link); return -ENODEV; } diff --git a/trunk/drivers/net/wireless/b43/pcmcia.c b/trunk/drivers/net/wireless/b43/pcmcia.c index 3cfc30307a27..b8aa16307f79 100644 --- a/trunk/drivers/net/wireless/b43/pcmcia.c +++ b/trunk/drivers/net/wireless/b43/pcmcia.c @@ -82,13 +82,13 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) tuple.TupleOffset = 0; res = pcmcia_get_first_tuple(dev, &tuple); - if (res != 0) + if (res != CS_SUCCESS) goto err_kfree_ssb; res = pcmcia_get_tuple_data(dev, &tuple); - if (res != 0) + if (res != CS_SUCCESS) goto err_kfree_ssb; - res = pcmcia_parse_tuple(&tuple, &parse); - if (res != 0) + res = pcmcia_parse_tuple(dev, &tuple, &parse); + if (res != CS_SUCCESS) goto err_kfree_ssb; dev->conf.ConfigBase = parse.config.base; @@ -107,13 +107,13 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) win.Size = SSB_CORE_SIZE; win.AccessSpeed = 250; res = pcmcia_request_window(&dev, &win, &dev->win); - if (res != 0) + if (res != CS_SUCCESS) goto err_kfree_ssb; mem.CardOffset = 0; mem.Page = 0; res = pcmcia_map_mem_page(dev->win, &mem); - if (res != 0) + if (res != CS_SUCCESS) goto err_disable; dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; @@ -121,11 +121,11 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) dev->irq.Handler = NULL; /* The handler is registered later. */ dev->irq.Instance = NULL; res = pcmcia_request_irq(dev, &dev->irq); - if (res != 0) + if (res != CS_SUCCESS) goto err_disable; res = pcmcia_request_configuration(dev, &dev->conf); - if (res != 0) + if (res != CS_SUCCESS) goto err_disable; err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index 633740277352..3b4e55cf33cd 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -234,7 +234,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Value = hw_priv->link->io.BasePort1 & 0x00ff; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" " res=%d\n", res); } @@ -246,7 +246,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" " res=%d\n", res); } @@ -305,7 +305,7 @@ static int sandisk_enable_wireless(struct net_device *dev) tuple.DesiredTuple = CISTPL_LONGLINK_MFC; if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || pcmcia_get_tuple_data(hw_priv->link, &tuple) || - pcmcia_parse_tuple(&tuple, parse) || + pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || parse->longlink_mfc.nfn < 2) { /* No multi-function links found */ ret = -ENODEV; @@ -322,7 +322,7 @@ static int sandisk_enable_wireless(struct net_device *dev) reg.Value = COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", dev->name, res); goto done; @@ -339,7 +339,7 @@ static int sandisk_enable_wireless(struct net_device *dev) reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", dev->name, res); goto done; @@ -374,7 +374,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value = 0; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", res); return; @@ -386,7 +386,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value |= COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", res); return; @@ -399,7 +399,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value |= COR_IREQ_ENA; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", res); return; @@ -433,7 +433,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Value = 0; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " "(%d)\n", res); return; @@ -446,7 +446,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Value |= COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " "(%d)\n", res); return; @@ -460,7 +460,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Offset = CISREG_CCSR; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " "(%d)\n", res); return; @@ -472,7 +472,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Value = old_cor & ~COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != 0) { + if (res != CS_SUCCESS) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " "(%d)\n", res); return; @@ -532,118 +532,145 @@ static void prism2_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +#define CFG_CHECK2(fn, retf) \ +do { int _ret = (retf); \ +if (_ret != 0) { \ + PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \ + cs_error(link, fn, _ret); \ + goto next_entry; \ +} \ +} while (0) + /* run after a CARD_INSERTION event is received to configure the PCMCIA * socket and make the device available to the system */ - -static int prism2_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if (cfg->index == 0) - return -ENODEV; - - PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X " - "(default 0x%02X)\n", cfg->index, dflt->index); - - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - p_dev->conf.Attributes |= CONF_ENABLE_SPKR; - p_dev->conf.Status = CCSR_AUDIO_ENA; - } - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / - 10000 && !ignore_cis_vcc) { - PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping" - " this entry\n"); - return -ENODEV; - } - } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / - 10000 && !ignore_cis_vcc) { - PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch " - "- skipping this entry\n"); - return -ENODEV; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) { - /* At least Compaq WL200 does not have IRQInfo1 set, - * but it does not work without interrupts.. */ - printk(KERN_WARNING "Config has no IRQ info, but trying to " - "enable IRQ anyway..\n"); - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - } - - /* IO window settings */ - PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " - "dflt->io.nwin=%d\n", - cfg->io.nwin, dflt->io.nwin); - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, " - "io.base=0x%04x, len=%d\n", io->flags, - io->win[0].base, io->win[0].len); - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & - CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - } - - /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); -} - static int prism2_config(struct pcmcia_device *link) { struct net_device *dev; struct hostap_interface *iface; local_info_t *local; int ret = 1; + tuple_t tuple; + cisparse_t *parse; int last_fn, last_ret; + u_char buf[64]; + config_info_t conf; + cistpl_cftable_entry_t dflt = { 0 }; struct hostap_cs_priv *hw_priv; PDEBUG(DEBUG_FLOW, "prism2_config()\n"); + parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL); - if (hw_priv == NULL) { + if (parse == NULL || hw_priv == NULL) { ret = -ENOMEM; goto failed; } + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + + CS_CHECK(GetConfigurationInfo, + pcmcia_get_configuration_info(link, &conf)); + /* Look for an appropriate configuration table entry in the CIS */ - last_ret = pcmcia_loop_config(link, prism2_config_check, NULL); - if (last_ret) { - if (!ignore_cis_vcc) - printk(KERN_ERR "GetNextTuple(): No matching " - "CIS configuration. Maybe you need the " - "ignore_cis_vcc=1 parameter.\n"); - cs_error(link, RequestIO, last_ret); - goto failed; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + for (;;) { + cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); + CFG_CHECK2(GetTupleData, + pcmcia_get_tuple_data(link, &tuple)); + CFG_CHECK2(ParseTuple, + pcmcia_parse_tuple(link, &tuple, parse)); + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + dflt = *cfg; + if (cfg->index == 0) + goto next_entry; + link->conf.ConfigIndex = cfg->index; + PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X " + "(default 0x%02X)\n", cfg->index, dflt.index); + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / + 10000 && !ignore_cis_vcc) { + PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping" + " this entry\n"); + goto next_entry; + } + } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / + 10000 && !ignore_cis_vcc) { + PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch " + "- skipping this entry\n"); + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) + link->conf.Attributes |= CONF_ENABLE_IRQ; + else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) { + /* At least Compaq WL200 does not have IRQInfo1 set, + * but it does not work without interrupts.. */ + printk("Config has no IRQ info, but trying to enable " + "IRQ anyway..\n"); + link->conf.Attributes |= CONF_ENABLE_IRQ; + } + + /* IO window settings */ + PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " + "dflt.io.nwin=%d\n", + cfg->io.nwin, dflt.io.nwin); + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, " + "io.base=0x%04x, len=%d\n", io->flags, + io->win[0].base, io->win[0].len); + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = io->flags & + CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + } + + /* This reserves IO space but doesn't actually enable it */ + CFG_CHECK2(RequestIO, + pcmcia_request_io(link, &link->io)); + + /* This configuration table entry is OK */ + break; + + next_entry: + CS_CHECK(GetNextTuple, + pcmcia_get_next_tuple(link, &tuple)); } /* Need to allocate net_device before requesting IRQ handler */ @@ -711,12 +738,14 @@ static int prism2_config(struct pcmcia_device *link) if (ret == 0 && local->ddev) strcpy(hw_priv->node.dev_name, local->ddev->name); } + kfree(parse); return ret; cs_failed: cs_error(link, last_fn, last_ret); failed: + kfree(parse); kfree(hw_priv); prism2_release((u_long)link); return ret; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index 5155b8a760a7..f6003e7996af 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -833,12 +833,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { case CSR_HW_REV_TYPE_5100: case CSR_HW_REV_TYPE_5300: - case CSR_HW_REV_TYPE_5350: - /* 5X00 and 5350 wants in Celsius */ + /* 5X00 wants in Celsius */ priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; break; case CSR_HW_REV_TYPE_5150: - /* 5150 wants in Kelvin */ + case CSR_HW_REV_TYPE_5350: + /* 5X50 wants in Kelvin */ priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); break; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index e2a58e477036..93944de923ca 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2422,7 +2422,7 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, void *priv_sta) { struct iwl_lq_sta *lq_sta = priv_sta; - struct iwl_priv *priv __maybe_unused = priv_r; + struct iwl_priv *priv = priv_r; IWL_DEBUG_RATE("enter\n"); kfree(lq_sta); diff --git a/trunk/drivers/net/wireless/libertas/cmd.c b/trunk/drivers/net/wireless/libertas/cmd.c index 297696de2da0..a912fb68c099 100644 --- a/trunk/drivers/net/wireless/libertas/cmd.c +++ b/trunk/drivers/net/wireless/libertas/cmd.c @@ -823,9 +823,7 @@ int lbs_update_channel(struct lbs_private *priv) int lbs_set_channel(struct lbs_private *priv, u8 channel) { struct cmd_ds_802_11_rf_channel cmd; -#ifdef DEBUG u8 old_channel = priv->curbssparams.channel; -#endif int ret = 0; lbs_deb_enter(LBS_DEB_CMD); diff --git a/trunk/drivers/net/wireless/libertas/if_cs.c b/trunk/drivers/net/wireless/libertas/if_cs.c index 842a08d1f106..e3505c110af6 100644 --- a/trunk/drivers/net/wireless/libertas/if_cs.c +++ b/trunk/drivers/net/wireless/libertas/if_cs.c @@ -791,7 +791,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 || (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 || - (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) + (ret = pcmcia_parse_tuple(p_dev, &tuple, &parse)) != 0) { lbs_pr_err("error in pcmcia_get_first_tuple etc\n"); goto out1; diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index 1a019e98dac3..c9e4a435b2fc 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -533,11 +533,11 @@ static int __init init_mac80211_hwsim(void) data = hw->priv; data->hw = hw; - data->dev = device_create(hwsim_class, NULL, 0, hw, - "hwsim%d", i); + data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw, + "hwsim%d", i); if (IS_ERR(data->dev)) { printk(KERN_DEBUG - "mac80211_hwsim: device_create " + "mac80211_hwsim: device_create_drvdata " "failed (%ld)\n", PTR_ERR(data->dev)); err = -ENOMEM; goto failed_drvdata; diff --git a/trunk/drivers/net/wireless/netwave_cs.c b/trunk/drivers/net/wireless/netwave_cs.c index a670f36b5f3f..25bae7933aa5 100644 --- a/trunk/drivers/net/wireless/netwave_cs.c +++ b/trunk/drivers/net/wireless/netwave_cs.c @@ -749,10 +749,9 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { for (i = j = 0x0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == 0) - break; + if (i == CS_SUCCESS) break; } - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); goto failed; } diff --git a/trunk/drivers/net/wireless/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco_cs.c index 6fcf2bda7cdf..9eaa252c2430 100644 --- a/trunk/drivers/net/wireless/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco_cs.c @@ -80,7 +80,7 @@ orinoco_cs_hard_reset(struct orinoco_private *priv) /* We need atomic ops here, because we're not holding the lock */ set_bit(0, &card->hard_reset_in_progress); - err = pcmcia_reset_card(link->socket); + err = pcmcia_reset_card(link, NULL); if (err) return err; @@ -165,70 +165,6 @@ static void orinoco_cs_detach(struct pcmcia_device *link) last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ } while (0) -static int orinoco_cs_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if (cfg->index == 0) - goto next_entry; - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); - if (!ignore_cis_vcc) - goto next_entry; - } - } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000); - if (!ignore_cis_vcc) - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = - dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) - goto next_entry; - } - return 0; - -next_entry: - pcmcia_disable_device(p_dev); - return -ENODEV; -}; - static int orinoco_cs_config(struct pcmcia_device *link) { @@ -237,8 +173,16 @@ orinoco_cs_config(struct pcmcia_device *link) struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; int last_fn, last_ret; + u_char buf[64]; + config_info_t conf; + tuple_t tuple; + cisparse_t parse; void __iomem *mem; + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, + pcmcia_get_configuration_info(link, &conf)); + /* * In this loop, we scan the CIS for configuration table * entries, each of which describes a valid card @@ -253,14 +197,94 @@ orinoco_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL); - if (last_ret) { - if (!ignore_cis_vcc) + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + cistpl_cftable_entry_t dflt = { .index = 0 }; + + if ( (pcmcia_get_tuple_data(link, &tuple) != 0) + || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + dflt = *cfg; + if (cfg->index == 0) + goto next_entry; + link->conf.ConfigIndex = cfg->index; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); + if (!ignore_cis_vcc) + goto next_entry; + } + } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000); + if(!ignore_cis_vcc) + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* Do we need to allocate an interrupt? */ + link->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = + (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = + io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = + link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + } + + + /* If we got this far, we're cool! */ + + break; + + next_entry: + pcmcia_disable_device(link); + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret == CS_NO_MORE_ITEMS) { printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); - cs_error(link, RequestIO, last_ret); - goto failed; + goto cs_failed; + } } /* @@ -311,6 +335,7 @@ orinoco_cs_config(struct pcmcia_device *link) "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id, link->irq.AssignedIRQ, link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); + return 0; cs_failed: @@ -378,7 +403,6 @@ static int orinoco_cs_resume(struct pcmcia_device *link) struct orinoco_private *priv = netdev_priv(dev); struct orinoco_pccard *card = priv->card; int err = 0; - unsigned long flags; if (! test_bit(0, &card->hard_reset_in_progress)) { err = orinoco_reinit_firmware(dev); @@ -388,7 +412,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link) return -EIO; } - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); netif_device_attach(dev); priv->hw_unavailable--; @@ -400,7 +424,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link) dev->name, err); } - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); } return err; diff --git a/trunk/drivers/net/wireless/p54/p54common.c b/trunk/drivers/net/wireless/p54/p54common.c index 117c7d3a52b0..1994aa199d37 100644 --- a/trunk/drivers/net/wireless/p54/p54common.c +++ b/trunk/drivers/net/wireless/p54/p54common.c @@ -479,6 +479,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) printk(KERN_ERR "p54: eeprom parse failed!\n"); return err; } +EXPORT_SYMBOL_GPL(p54_parse_eeprom); static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) { diff --git a/trunk/drivers/net/wireless/p54/p54usb.c b/trunk/drivers/net/wireless/p54/p54usb.c index 75d749bccb0d..1912f5e9a0a9 100644 --- a/trunk/drivers/net/wireless/p54/p54usb.c +++ b/trunk/drivers/net/wireless/p54/p54usb.c @@ -39,7 +39,6 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */ {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ - {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ @@ -64,8 +63,8 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ + {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ - {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index 1404a5717520..44da0d19b5c8 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -798,9 +798,9 @@ static void ray_release(struct pcmcia_device *link) iounmap(local->amem); /* Do bother checking to see if these succeed or not */ i = pcmcia_release_window(local->amem_handle); - if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); i = pcmcia_release_window(local->rmem_handle); - if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); pcmcia_disable_device(link); DEBUG(2,"ray_release ending\n"); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c index 451d410ecdae..1676ac484790 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct txentry_desc txdesc; struct skb_frame_desc *skbdesc; - unsigned int iv_len = 0; + unsigned int iv_len; if (unlikely(rt2x00queue_full(queue))) return -EINVAL; @@ -395,9 +395,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) entry->skb = skb; rt2x00queue_create_tx_descriptor(entry, &txdesc); - if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL) - iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; - /* * All information is retreived from the skb->cb array, * now we should claim ownership of the driver part of that @@ -413,7 +410,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) * the frame so we can provide it to the driver seperately. */ if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && - !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { + !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) && + (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) { + iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; rt2x00crypto_tx_remove_iv(skb, iv_len); } diff --git a/trunk/drivers/net/wireless/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl8187_dev.c index 431e3c78bf27..e9902613e2ee 100644 --- a/trunk/drivers/net/wireless/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl8187_dev.c @@ -33,13 +33,10 @@ MODULE_LICENSE("GPL"); static struct usb_device_id rtl8187_table[] __devinitdata = { /* Asus */ {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, - /* Belkin */ - {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B}, /* Realtek */ {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, - {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, /* Netgear */ {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, diff --git a/trunk/drivers/net/wireless/spectrum_cs.c b/trunk/drivers/net/wireless/spectrum_cs.c index 852789ad34b3..67b26d3c3cd5 100644 --- a/trunk/drivers/net/wireless/spectrum_cs.c +++ b/trunk/drivers/net/wireless/spectrum_cs.c @@ -235,70 +235,6 @@ static void spectrum_cs_detach(struct pcmcia_device *link) * device available to the system. */ -static int spectrum_cs_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if (cfg->index == 0) - goto next_entry; - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); - if (!ignore_cis_vcc) - goto next_entry; - } - } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000); - if (!ignore_cis_vcc) - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = - dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) - goto next_entry; - } - return 0; - -next_entry: - pcmcia_disable_device(p_dev); - return -ENODEV; -}; - static int spectrum_cs_config(struct pcmcia_device *link) { @@ -307,8 +243,16 @@ spectrum_cs_config(struct pcmcia_device *link) struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; int last_fn, last_ret; + u_char buf[64]; + config_info_t conf; + tuple_t tuple; + cisparse_t parse; void __iomem *mem; + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, + pcmcia_get_configuration_info(link, &conf)); + /* * In this loop, we scan the CIS for configuration table * entries, each of which describes a valid card @@ -323,14 +267,94 @@ spectrum_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL); - if (last_ret) { - if (!ignore_cis_vcc) + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + cistpl_cftable_entry_t dflt = { .index = 0 }; + + if ( (pcmcia_get_tuple_data(link, &tuple) != 0) + || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + dflt = *cfg; + if (cfg->index == 0) + goto next_entry; + link->conf.ConfigIndex = cfg->index; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); + if (!ignore_cis_vcc) + goto next_entry; + } + } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000); + if(!ignore_cis_vcc) + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* Do we need to allocate an interrupt? */ + link->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = + (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = + io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + link->io.Attributes2 = + link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + } + + + /* If we got this far, we're cool! */ + + break; + + next_entry: + pcmcia_disable_device(link); + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret == CS_NO_MORE_ITEMS) { printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); - cs_error(link, RequestIO, last_ret); - goto failed; + goto cs_failed; + } } /* @@ -426,11 +450,10 @@ spectrum_cs_suspend(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; int err = 0; /* Mark the device as stopped, to block IO until later */ - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); err = __orinoco_down(dev); if (err) @@ -440,7 +463,7 @@ spectrum_cs_suspend(struct pcmcia_device *link) netif_device_detach(dev); priv->hw_unavailable++; - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); return err; } diff --git a/trunk/drivers/net/wireless/wavelan.c b/trunk/drivers/net/wireless/wavelan.c index e939a73ff794..136220b5ca81 100644 --- a/trunk/drivers/net/wireless/wavelan.c +++ b/trunk/drivers/net/wireless/wavelan.c @@ -4387,7 +4387,7 @@ MODULE_LICENSE("GPL"); * * Thanks go also to: * James Ashton (jaa101@syseng.anu.edu.au), - * Alan Cox (alan@lxorguk.ukuu.org.uk), + * Alan Cox (alan@redhat.com), * Allan Creighton (allanc@cs.usyd.edu.au), * Matthew Geier (matthew@cs.usyd.edu.au), * Remo di Giovanni (remo@cs.usyd.edu.au), diff --git a/trunk/drivers/net/wireless/wavelan.p.h b/trunk/drivers/net/wireless/wavelan.p.h index 44d31bbf39e4..b33ac47dd8df 100644 --- a/trunk/drivers/net/wireless/wavelan.p.h +++ b/trunk/drivers/net/wireless/wavelan.p.h @@ -186,7 +186,7 @@ * * Thanks go also to: * James Ashton , - * Alan Cox , + * Alan Cox , * Allan Creighton , * Matthew Geier , * Remo di Giovanni , diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index e124b1d6267a..b5de38a9b791 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -3702,7 +3702,7 @@ wv_pcmcia_reset(struct net_device * dev) #endif i = pcmcia_access_configuration_register(link, ®); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, AccessConfigurationRegister, i); return FALSE; @@ -3716,7 +3716,7 @@ wv_pcmcia_reset(struct net_device * dev) reg.Action = CS_WRITE; reg.Value = reg.Value | COR_SW_RESET; i = pcmcia_access_configuration_register(link, ®); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, AccessConfigurationRegister, i); return FALSE; @@ -3725,7 +3725,7 @@ wv_pcmcia_reset(struct net_device * dev) reg.Action = CS_WRITE; reg.Value = COR_LEVEL_IRQ | COR_CONFIG; i = pcmcia_access_configuration_register(link, ®); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, AccessConfigurationRegister, i); return FALSE; @@ -3903,7 +3903,7 @@ wv_pcmcia_config(struct pcmcia_device * link) do { i = pcmcia_request_io(link, &link->io); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, RequestIO, i); break; @@ -3914,7 +3914,7 @@ wv_pcmcia_config(struct pcmcia_device * link) * actually assign a handler to the interrupt. */ i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); break; @@ -3926,7 +3926,7 @@ wv_pcmcia_config(struct pcmcia_device * link) */ link->conf.ConfigIndex = 1; i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); break; @@ -3942,7 +3942,7 @@ wv_pcmcia_config(struct pcmcia_device * link) req.Base = req.Size = 0; req.AccessSpeed = mem_speed; i = pcmcia_request_window(&link, &req, &link->win); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, RequestWindow, i); break; @@ -3954,7 +3954,7 @@ wv_pcmcia_config(struct pcmcia_device * link) mem.CardOffset = 0; mem.Page = 0; i = pcmcia_map_mem_page(link->win, &mem); - if (i != 0) + if(i != CS_SUCCESS) { cs_error(link, MapMemPage, i); break; diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c index 68789c6e1ce9..74a5ad2f1223 100644 --- a/trunk/drivers/net/wireless/wl3501_cs.c +++ b/trunk/drivers/net/wireless/wl3501_cs.c @@ -1977,10 +1977,10 @@ static int wl3501_config(struct pcmcia_device *link) link->io.BasePort1 = j; link->io.BasePort2 = link->io.BasePort1 + 0x10; i = pcmcia_request_io(link, &link->io); - if (i == 0) + if (i == CS_SUCCESS) break; } - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); goto failed; } diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index 5c7a87e38951..3c3dd403f5dd 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -471,7 +471,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); - frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); + frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE; if (unlikely(frags > MAX_SKB_FRAGS + 1)) { printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", frags); diff --git a/trunk/drivers/nubus/nubus.c b/trunk/drivers/nubus/nubus.c index f5f75844954c..2f047e573d86 100644 --- a/trunk/drivers/nubus/nubus.c +++ b/trunk/drivers/nubus/nubus.c @@ -126,7 +126,7 @@ static void nubus_advance(unsigned char **ptr, int len, int map) { while(not_useful(p,map)) p++; - p++; + p++; len--; } *ptr = p; diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index 7c79e94a35ea..ad8ac1a8af28 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -410,7 +410,7 @@ struct of_modalias_table { char *modalias; }; static struct of_modalias_table of_modalias_table[] = { - { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, + /* Empty for now; add entries as needed */ }; /** @@ -420,12 +420,13 @@ static struct of_modalias_table of_modalias_table[] = { * @len: Length of modalias value * * Based on the value of the compatible property, this routine will determine - * an appropriate modalias value for a particular device tree node. Two - * separate methods are attempted to derive a modalias value. + * an appropriate modalias value for a particular device tree node. Three + * separate methods are used to derive a modalias value. * * First method is to lookup the compatible value in of_modalias_table. - * Second is to strip off the manufacturer prefix from the first - * compatible entry and use the remainder as modalias + * Second is to look for a "linux," entry in the compatible list + * and used that for modalias. Third is to strip off the manufacturer + * prefix from the first compatible entry and use the remainder as modalias * * This routine returns 0 on success */ @@ -448,7 +449,21 @@ int of_modalias_node(struct device_node *node, char *modalias, int len) if (!compatible) return -ENODEV; - /* 2. take first compatible entry and strip manufacturer */ + /* 2. search for linux, entry */ + p = compatible; + while (cplen > 0) { + if (!strncmp(p, "linux,", 6)) { + p += 6; + strlcpy(modalias, p, len); + return 0; + } + + i = strlen(p) + 1; + p += i; + cplen -= i; + } + + /* 3. take first compatible entry and strip manufacturer */ p = strchr(compatible, ','); if (!p) return -ENODEV; @@ -458,112 +473,3 @@ int of_modalias_node(struct device_node *node, char *modalias, int len) } EXPORT_SYMBOL_GPL(of_modalias_node); -/** - * of_parse_phandles_with_args - Find a node pointed by phandle in a list - * @np: pointer to a device tree node containing a list - * @list_name: property name that contains a list - * @cells_name: property name that specifies phandles' arguments count - * @index: index of a phandle to parse out - * @out_node: pointer to device_node struct pointer (will be filled) - * @out_args: pointer to arguments pointer (will be filled) - * - * This function is useful to parse lists of phandles and their arguments. - * Returns 0 on success and fills out_node and out_args, on error returns - * appropriate errno value. - * - * Example: - * - * phandle1: node1 { - * #list-cells = <2>; - * } - * - * phandle2: node2 { - * #list-cells = <1>; - * } - * - * node3 { - * list = <&phandle1 1 2 &phandle2 3>; - * } - * - * To get a device_node of the `node2' node you may call this: - * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args); - */ -int of_parse_phandles_with_args(struct device_node *np, const char *list_name, - const char *cells_name, int index, - struct device_node **out_node, - const void **out_args) -{ - int ret = -EINVAL; - const u32 *list; - const u32 *list_end; - int size; - int cur_index = 0; - struct device_node *node = NULL; - const void *args; - - list = of_get_property(np, list_name, &size); - if (!list) { - ret = -ENOENT; - goto err0; - } - list_end = list + size / sizeof(*list); - - while (list < list_end) { - const u32 *cells; - const phandle *phandle; - - phandle = list; - args = list + 1; - - /* one cell hole in the list = <>; */ - if (!*phandle) { - list++; - goto next; - } - - node = of_find_node_by_phandle(*phandle); - if (!node) { - pr_debug("%s: could not find phandle\n", - np->full_name); - goto err0; - } - - cells = of_get_property(node, cells_name, &size); - if (!cells || size != sizeof(*cells)) { - pr_debug("%s: could not get %s for %s\n", - np->full_name, cells_name, node->full_name); - goto err1; - } - - /* Next phandle is at offset of one phandle cell + #cells */ - list += 1 + *cells; - if (list > list_end) { - pr_debug("%s: insufficient arguments length\n", - np->full_name); - goto err1; - } -next: - if (cur_index == index) - break; - - of_node_put(node); - node = NULL; - cur_index++; - } - - if (!node) { - ret = -ENOENT; - goto err0; - } - - *out_node = node; - *out_args = args; - - return 0; -err1: - of_node_put(node); -err0: - pr_debug("%s failed with status %d\n", __func__, ret); - return ret; -} -EXPORT_SYMBOL(of_parse_phandles_with_args); diff --git a/trunk/drivers/of/gpio.c b/trunk/drivers/of/gpio.c index 7cd7301b5839..1c9cab844f10 100644 --- a/trunk/drivers/of/gpio.c +++ b/trunk/drivers/of/gpio.c @@ -28,35 +28,78 @@ */ int of_get_gpio(struct device_node *np, int index) { - int ret; + int ret = -EINVAL; struct device_node *gc; struct of_gpio_chip *of_gc = NULL; int size; + const u32 *gpios; + u32 nr_cells; + int i; const void *gpio_spec; const u32 *gpio_cells; + int gpio_index = 0; - ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, - &gc, &gpio_spec); - if (ret) { - pr_debug("%s: can't parse gpios property\n", __func__); + gpios = of_get_property(np, "gpios", &size); + if (!gpios) { + ret = -ENOENT; goto err0; } - - of_gc = gc->data; - if (!of_gc) { - pr_debug("%s: gpio controller %s isn't registered\n", - np->full_name, gc->full_name); - ret = -ENODEV; - goto err1; + nr_cells = size / sizeof(u32); + + for (i = 0; i < nr_cells; gpio_index++) { + const phandle *gpio_phandle; + + gpio_phandle = gpios + i; + gpio_spec = gpio_phandle + 1; + + /* one cell hole in the gpios = <>; */ + if (!*gpio_phandle) { + if (gpio_index == index) + return -ENOENT; + i++; + continue; + } + + gc = of_find_node_by_phandle(*gpio_phandle); + if (!gc) { + pr_debug("%s: could not find phandle for gpios\n", + np->full_name); + goto err0; + } + + of_gc = gc->data; + if (!of_gc) { + pr_debug("%s: gpio controller %s isn't registered\n", + np->full_name, gc->full_name); + goto err1; + } + + gpio_cells = of_get_property(gc, "#gpio-cells", &size); + if (!gpio_cells || size != sizeof(*gpio_cells) || + *gpio_cells != of_gc->gpio_cells) { + pr_debug("%s: wrong #gpio-cells for %s\n", + np->full_name, gc->full_name); + goto err1; + } + + /* Next phandle is at phandle cells + #gpio-cells */ + i += sizeof(*gpio_phandle) / sizeof(u32) + *gpio_cells; + if (i >= nr_cells + 1) { + pr_debug("%s: insufficient gpio-spec length\n", + np->full_name); + goto err1; + } + + if (gpio_index == index) + break; + + of_gc = NULL; + of_node_put(gc); } - gpio_cells = of_get_property(gc, "#gpio-cells", &size); - if (!gpio_cells || size != sizeof(*gpio_cells) || - *gpio_cells != of_gc->gpio_cells) { - pr_debug("%s: wrong #gpio-cells for %s\n", - np->full_name, gc->full_name); - ret = -EINVAL; - goto err1; + if (!of_gc) { + ret = -ENOENT; + goto err0; } ret = of_gc->xlate(of_gc, np, gpio_spec); diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index ed982273fb8b..9304c4555079 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -5,7 +5,6 @@ * @remark Read the file COPYING * * @author John Levon - * @author Barry Kasindorf * * This is the core of the buffer management. Each * CPU buffer is processed and entered into the @@ -34,7 +33,7 @@ #include "event_buffer.h" #include "cpu_buffer.h" #include "buffer_sync.h" - + static LIST_HEAD(dying_tasks); static LIST_HEAD(dead_tasks); static cpumask_t marked_cpus = CPU_MASK_NONE; @@ -49,11 +48,10 @@ static void process_task_mortuary(void); * Can be invoked from softirq via RCU callback due to * call_rcu() of the task struct, hence the _irqsave. */ -static int -task_free_notify(struct notifier_block *self, unsigned long val, void *data) +static int task_free_notify(struct notifier_block * self, unsigned long val, void * data) { unsigned long flags; - struct task_struct *task = data; + struct task_struct * task = data; spin_lock_irqsave(&task_mortuary, flags); list_add(&task->tasks, &dying_tasks); spin_unlock_irqrestore(&task_mortuary, flags); @@ -64,14 +62,13 @@ task_free_notify(struct notifier_block *self, unsigned long val, void *data) /* The task is on its way out. A sync of the buffer means we can catch * any remaining samples for this task. */ -static int -task_exit_notify(struct notifier_block *self, unsigned long val, void *data) +static int task_exit_notify(struct notifier_block * self, unsigned long val, void * data) { /* To avoid latency problems, we only process the current CPU, * hoping that most samples for the task are on this CPU */ sync_buffer(raw_smp_processor_id()); - return 0; + return 0; } @@ -80,12 +77,11 @@ task_exit_notify(struct notifier_block *self, unsigned long val, void *data) * we don't lose any. This does not have to be exact, it's a QoI issue * only. */ -static int -munmap_notify(struct notifier_block *self, unsigned long val, void *data) +static int munmap_notify(struct notifier_block * self, unsigned long val, void * data) { unsigned long addr = (unsigned long)data; - struct mm_struct *mm = current->mm; - struct vm_area_struct *mpnt; + struct mm_struct * mm = current->mm; + struct vm_area_struct * mpnt; down_read(&mm->mmap_sem); @@ -103,12 +99,11 @@ munmap_notify(struct notifier_block *self, unsigned long val, void *data) return 0; } - + /* We need to be told about new modules so we don't attribute to a previously * loaded module, or drop the samples on the floor. */ -static int -module_load_notify(struct notifier_block *self, unsigned long val, void *data) +static int module_load_notify(struct notifier_block * self, unsigned long val, void * data) { #ifdef CONFIG_MODULES if (val != MODULE_STATE_COMING) @@ -123,7 +118,7 @@ module_load_notify(struct notifier_block *self, unsigned long val, void *data) return 0; } - + static struct notifier_block task_free_nb = { .notifier_call = task_free_notify, }; @@ -140,7 +135,7 @@ static struct notifier_block module_load_nb = { .notifier_call = module_load_notify, }; - + static void end_sync(void) { end_cpu_work(); @@ -213,14 +208,14 @@ static inline unsigned long fast_get_dcookie(struct path *path) * not strictly necessary but allows oprofile to associate * shared-library samples with particular applications */ -static unsigned long get_exec_dcookie(struct mm_struct *mm) +static unsigned long get_exec_dcookie(struct mm_struct * mm) { unsigned long cookie = NO_COOKIE; - struct vm_area_struct *vma; - + struct vm_area_struct * vma; + if (!mm) goto out; - + for (vma = mm->mmap; vma; vma = vma->vm_next) { if (!vma->vm_file) continue; @@ -240,14 +235,13 @@ static unsigned long get_exec_dcookie(struct mm_struct *mm) * sure to do this lookup before a mm->mmap modification happens so * we don't lose track. */ -static unsigned long -lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset) +static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset) { unsigned long cookie = NO_COOKIE; - struct vm_area_struct *vma; + struct vm_area_struct * vma; for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { - + if (addr < vma->vm_start || addr >= vma->vm_end) continue; @@ -269,20 +263,9 @@ lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset) return cookie; } -static void increment_tail(struct oprofile_cpu_buffer *b) -{ - unsigned long new_tail = b->tail_pos + 1; - - rmb(); /* be sure fifo pointers are synchromized */ - - if (new_tail < b->buffer_size) - b->tail_pos = new_tail; - else - b->tail_pos = 0; -} static unsigned long last_cookie = INVALID_COOKIE; - + static void add_cpu_switch(int i) { add_event_entry(ESCAPE_CODE); @@ -295,16 +278,16 @@ static void add_kernel_ctx_switch(unsigned int in_kernel) { add_event_entry(ESCAPE_CODE); if (in_kernel) - add_event_entry(KERNEL_ENTER_SWITCH_CODE); + add_event_entry(KERNEL_ENTER_SWITCH_CODE); else - add_event_entry(KERNEL_EXIT_SWITCH_CODE); + add_event_entry(KERNEL_EXIT_SWITCH_CODE); } - + static void -add_user_ctx_switch(struct task_struct const *task, unsigned long cookie) +add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) { add_event_entry(ESCAPE_CODE); - add_event_entry(CTX_SWITCH_CODE); + add_event_entry(CTX_SWITCH_CODE); add_event_entry(task->pid); add_event_entry(cookie); /* Another code for daemon back-compat */ @@ -313,7 +296,7 @@ add_user_ctx_switch(struct task_struct const *task, unsigned long cookie) add_event_entry(task->tgid); } - + static void add_cookie_switch(unsigned long cookie) { add_event_entry(ESCAPE_CODE); @@ -321,78 +304,13 @@ static void add_cookie_switch(unsigned long cookie) add_event_entry(cookie); } - + static void add_trace_begin(void) { add_event_entry(ESCAPE_CODE); add_event_entry(TRACE_BEGIN_CODE); } -#ifdef CONFIG_OPROFILE_IBS - -#define IBS_FETCH_CODE_SIZE 2 -#define IBS_OP_CODE_SIZE 5 -#define IBS_EIP(offset) \ - (((struct op_sample *)&cpu_buf->buffer[(offset)])->eip) -#define IBS_EVENT(offset) \ - (((struct op_sample *)&cpu_buf->buffer[(offset)])->event) - -/* - * Add IBS fetch and op entries to event buffer - */ -static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code, - int in_kernel, struct mm_struct *mm) -{ - unsigned long rip; - int i, count; - unsigned long ibs_cookie = 0; - off_t offset; - - increment_tail(cpu_buf); /* move to RIP entry */ - - rip = IBS_EIP(cpu_buf->tail_pos); - -#ifdef __LP64__ - rip += IBS_EVENT(cpu_buf->tail_pos) << 32; -#endif - - if (mm) { - ibs_cookie = lookup_dcookie(mm, rip, &offset); - - if (ibs_cookie == NO_COOKIE) - offset = rip; - if (ibs_cookie == INVALID_COOKIE) { - atomic_inc(&oprofile_stats.sample_lost_no_mapping); - offset = rip; - } - if (ibs_cookie != last_cookie) { - add_cookie_switch(ibs_cookie); - last_cookie = ibs_cookie; - } - } else - offset = rip; - - add_event_entry(ESCAPE_CODE); - add_event_entry(code); - add_event_entry(offset); /* Offset from Dcookie */ - - /* we send the Dcookie offset, but send the raw Linear Add also*/ - add_event_entry(IBS_EIP(cpu_buf->tail_pos)); - add_event_entry(IBS_EVENT(cpu_buf->tail_pos)); - - if (code == IBS_FETCH_CODE) - count = IBS_FETCH_CODE_SIZE; /*IBS FETCH is 2 int64s*/ - else - count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ - - for (i = 0; i < count; i++) { - increment_tail(cpu_buf); - add_event_entry(IBS_EIP(cpu_buf->tail_pos)); - add_event_entry(IBS_EVENT(cpu_buf->tail_pos)); - } -} - -#endif static void add_sample_entry(unsigned long offset, unsigned long event) { @@ -401,13 +319,13 @@ static void add_sample_entry(unsigned long offset, unsigned long event) } -static int add_us_sample(struct mm_struct *mm, struct op_sample *s) +static int add_us_sample(struct mm_struct * mm, struct op_sample * s) { unsigned long cookie; off_t offset; - - cookie = lookup_dcookie(mm, s->eip, &offset); - + + cookie = lookup_dcookie(mm, s->eip, &offset); + if (cookie == INVALID_COOKIE) { atomic_inc(&oprofile_stats.sample_lost_no_mapping); return 0; @@ -423,13 +341,13 @@ static int add_us_sample(struct mm_struct *mm, struct op_sample *s) return 1; } - + /* Add a sample to the global event buffer. If possible the * sample is converted into a persistent dentry/offset pair * for later lookup from userspace. */ static int -add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel) +add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) { if (in_kernel) { add_sample_entry(s->eip, s->event); @@ -441,9 +359,9 @@ add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel) } return 0; } + - -static void release_mm(struct mm_struct *mm) +static void release_mm(struct mm_struct * mm) { if (!mm) return; @@ -452,9 +370,9 @@ static void release_mm(struct mm_struct *mm) } -static struct mm_struct *take_tasks_mm(struct task_struct *task) +static struct mm_struct * take_tasks_mm(struct task_struct * task) { - struct mm_struct *mm = get_task_mm(task); + struct mm_struct * mm = get_task_mm(task); if (mm) down_read(&mm->mmap_sem); return mm; @@ -465,10 +383,10 @@ static inline int is_code(unsigned long val) { return val == ESCAPE_CODE; } - + /* "acquire" as many cpu buffer slots as we can */ -static unsigned long get_slots(struct oprofile_cpu_buffer *b) +static unsigned long get_slots(struct oprofile_cpu_buffer * b) { unsigned long head = b->head_pos; unsigned long tail = b->tail_pos; @@ -494,6 +412,19 @@ static unsigned long get_slots(struct oprofile_cpu_buffer *b) } +static void increment_tail(struct oprofile_cpu_buffer * b) +{ + unsigned long new_tail = b->tail_pos + 1; + + rmb(); + + if (new_tail < b->buffer_size) + b->tail_pos = new_tail; + else + b->tail_pos = 0; +} + + /* Move tasks along towards death. Any tasks on dead_tasks * will definitely have no remaining references in any * CPU buffers at this point, because we use two lists, @@ -504,8 +435,8 @@ static void process_task_mortuary(void) { unsigned long flags; LIST_HEAD(local_dead_tasks); - struct task_struct *task; - struct task_struct *ttask; + struct task_struct * task; + struct task_struct * ttask; spin_lock_irqsave(&task_mortuary, flags); @@ -562,7 +493,7 @@ void sync_buffer(int cpu) { struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu); struct mm_struct *mm = NULL; - struct task_struct *new; + struct task_struct * new; unsigned long cookie = 0; int in_kernel = 1; unsigned int i; @@ -570,7 +501,7 @@ void sync_buffer(int cpu) unsigned long available; mutex_lock(&buffer_mutex); - + add_cpu_switch(cpu); /* Remember, only we can modify tail_pos */ @@ -578,8 +509,8 @@ void sync_buffer(int cpu) available = get_slots(cpu_buf); for (i = 0; i < available; ++i) { - struct op_sample *s = &cpu_buf->buffer[cpu_buf->tail_pos]; - + struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; + if (is_code(s->eip)) { if (s->event <= CPU_IS_KERNEL) { /* kernel/userspace switch */ @@ -590,18 +521,8 @@ void sync_buffer(int cpu) } else if (s->event == CPU_TRACE_BEGIN) { state = sb_bt_start; add_trace_begin(); -#ifdef CONFIG_OPROFILE_IBS - } else if (s->event == IBS_FETCH_BEGIN) { - state = sb_bt_start; - add_ibs_begin(cpu_buf, - IBS_FETCH_CODE, in_kernel, mm); - } else if (s->event == IBS_OP_BEGIN) { - state = sb_bt_start; - add_ibs_begin(cpu_buf, - IBS_OP_CODE, in_kernel, mm); -#endif } else { - struct mm_struct *oldmm = mm; + struct mm_struct * oldmm = mm; /* userspace context switch */ new = (struct task_struct *)s->event; @@ -612,11 +533,13 @@ void sync_buffer(int cpu) cookie = get_exec_dcookie(mm); add_user_ctx_switch(new, cookie); } - } else if (state >= sb_bt_start && - !add_sample(mm, s, in_kernel)) { - if (state == sb_bt_start) { - state = sb_bt_ignore; - atomic_inc(&oprofile_stats.bt_lost_no_mapping); + } else { + if (state >= sb_bt_start && + !add_sample(mm, s, in_kernel)) { + if (state == sb_bt_start) { + state = sb_bt_ignore; + atomic_inc(&oprofile_stats.bt_lost_no_mapping); + } } } diff --git a/trunk/drivers/oprofile/cpu_buffer.c b/trunk/drivers/oprofile/cpu_buffer.c index e1bd5a937f6c..7ba78e6d210e 100644 --- a/trunk/drivers/oprofile/cpu_buffer.c +++ b/trunk/drivers/oprofile/cpu_buffer.c @@ -5,7 +5,6 @@ * @remark Read the file COPYING * * @author John Levon - * @author Barry Kasindorf * * Each CPU has a local buffer that stores PC value/event * pairs. We also log context switches when we notice them. @@ -210,7 +209,7 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, return 1; } -static int oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf) +static int oprofile_begin_trace(struct oprofile_cpu_buffer * cpu_buf) { if (nr_available_slots(cpu_buf) < 4) { cpu_buf->sample_lost_overflow++; @@ -255,75 +254,6 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) oprofile_add_ext_sample(pc, regs, event, is_kernel); } -#ifdef CONFIG_OPROFILE_IBS - -#define MAX_IBS_SAMPLE_SIZE 14 -static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, - unsigned long pc, int is_kernel, unsigned int *ibs, int ibs_code) -{ - struct task_struct *task; - - cpu_buf->sample_received++; - - if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) { - cpu_buf->sample_lost_overflow++; - return 0; - } - - is_kernel = !!is_kernel; - - /* notice a switch from user->kernel or vice versa */ - if (cpu_buf->last_is_kernel != is_kernel) { - cpu_buf->last_is_kernel = is_kernel; - add_code(cpu_buf, is_kernel); - } - - /* notice a task switch */ - if (!is_kernel) { - task = current; - - if (cpu_buf->last_task != task) { - cpu_buf->last_task = task; - add_code(cpu_buf, (unsigned long)task); - } - } - - add_code(cpu_buf, ibs_code); - add_sample(cpu_buf, ibs[0], ibs[1]); - add_sample(cpu_buf, ibs[2], ibs[3]); - add_sample(cpu_buf, ibs[4], ibs[5]); - - if (ibs_code == IBS_OP_BEGIN) { - add_sample(cpu_buf, ibs[6], ibs[7]); - add_sample(cpu_buf, ibs[8], ibs[9]); - add_sample(cpu_buf, ibs[10], ibs[11]); - } - - return 1; -} - -void oprofile_add_ibs_sample(struct pt_regs *const regs, - unsigned int * const ibs_sample, u8 code) -{ - int is_kernel = !user_mode(regs); - unsigned long pc = profile_pc(regs); - - struct oprofile_cpu_buffer *cpu_buf = - &per_cpu(cpu_buffer, smp_processor_id()); - - if (!backtrace_depth) { - log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code); - return; - } - - /* if log_sample() fails we can't backtrace since we lost the source - * of this event */ - if (log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code)) - oprofile_ops.backtrace(regs, backtrace_depth); -} - -#endif - void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event) { struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer); @@ -366,7 +296,7 @@ static void wq_sync_buffer(struct work_struct *work) struct oprofile_cpu_buffer * b = container_of(work, struct oprofile_cpu_buffer, work.work); if (b->cpu != smp_processor_id()) { - printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n", + printk("WQ on CPU%d, prefer CPU%d\n", smp_processor_id(), b->cpu); } sync_buffer(b->cpu); diff --git a/trunk/drivers/oprofile/cpu_buffer.h b/trunk/drivers/oprofile/cpu_buffer.h index 9c44d004da69..c3e366b52261 100644 --- a/trunk/drivers/oprofile/cpu_buffer.h +++ b/trunk/drivers/oprofile/cpu_buffer.h @@ -55,7 +55,5 @@ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); /* transient events for the CPU buffer -> event buffer */ #define CPU_IS_KERNEL 1 #define CPU_TRACE_BEGIN 2 -#define IBS_FETCH_BEGIN 3 -#define IBS_OP_BEGIN 4 #endif /* OPROFILE_CPU_BUFFER_H */ diff --git a/trunk/drivers/parport/ChangeLog b/trunk/drivers/parport/ChangeLog index 8565bbbeb6ec..db717c1d62a5 100644 --- a/trunk/drivers/parport/ChangeLog +++ b/trunk/drivers/parport/ChangeLog @@ -311,7 +311,7 @@ * ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd on timeout. Matches 2.2.x behaviour. -2001-03-02 Andrew Morton +2001-03-02 Andrew Morton * parport_pc.c (registered_parport): New static variable. (parport_pc_find_ports): Set it when we register PCI driver. diff --git a/trunk/drivers/parport/ieee1284.c b/trunk/drivers/parport/ieee1284.c index ac2a805ac7ea..e97059415ab4 100644 --- a/trunk/drivers/parport/ieee1284.c +++ b/trunk/drivers/parport/ieee1284.c @@ -1,4 +1,4 @@ -/* +/* $Id: parport_ieee1284.c,v 1.4 1997/10/19 21:37:21 philip Exp $ * IEEE-1284 implementation for parport. * * Authors: Phil Blundell diff --git a/trunk/drivers/parport/parport_cs.c b/trunk/drivers/parport/parport_cs.c index b1899e9c1f65..00e1d9620f7c 100644 --- a/trunk/drivers/parport/parport_cs.c +++ b/trunk/drivers/parport/parport_cs.c @@ -149,44 +149,52 @@ static void parport_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int parport_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - if (epp_mode) - p_dev->conf.ConfigIndex |= FORCE_EPP_MODE; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (io->nwin == 2) { - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) - return -ENODEV; - return 0; - } - return -ENODEV; -} - static int parport_config(struct pcmcia_device *link) { parport_info_t *info = link->priv; + tuple_t tuple; + u_short buf[128]; + cisparse_t parse; + cistpl_cftable_entry_t *cfg = &parse.cftable_entry; + cistpl_cftable_entry_t dflt = { 0 }; struct parport *p; int last_ret, last_fn; - + DEBUG(0, "parport_config(0x%p)\n", link); - - last_ret = pcmcia_loop_config(link, parport_config_check, NULL); - if (last_ret) { - cs_error(link, RequestIO, last_ret); - goto failed; + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->conf.ConfigIndex = cfg->index; + if (epp_mode) + link->conf.ConfigIndex |= FORCE_EPP_MODE; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (io->nwin == 2) { + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + /* If we've got this far, we're done */ + break; + } + + next_entry: + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); diff --git a/trunk/drivers/parport/probe.c b/trunk/drivers/parport/probe.c index 0f6550719bcf..cd565bb4e1a9 100644 --- a/trunk/drivers/parport/probe.c +++ b/trunk/drivers/parport/probe.c @@ -1,4 +1,4 @@ -/* +/* $Id: parport_probe.c,v 1.1 1999/07/03 08:56:17 davem Exp $ * Parallel port device probing code * * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de diff --git a/trunk/drivers/parport/share.c b/trunk/drivers/parport/share.c index 0ebca450ed29..a8a62bbbb576 100644 --- a/trunk/drivers/parport/share.c +++ b/trunk/drivers/parport/share.c @@ -1,4 +1,4 @@ -/* +/* $Id: parport_share.c,v 1.15 1998/01/11 12:06:17 philip Exp $ * Parallel-port resource manager code. * * Authors: David Campbell diff --git a/trunk/drivers/pci/hotplug/rpaphp_slot.c b/trunk/drivers/pci/hotplug/rpaphp_slot.c index 50884507b8be..9b714ea93d20 100644 --- a/trunk/drivers/pci/hotplug/rpaphp_slot.c +++ b/trunk/drivers/pci/hotplug/rpaphp_slot.c @@ -147,5 +147,9 @@ int rpaphp_register_slot(struct slot *slot) list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); info("Slot [%s] registered\n", slot->name); return 0; + +sysfs_fail: + pci_hp_deregister(php_slot); + return retval; } diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index dd9161a054e1..36698e57b97f 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -1237,11 +1237,8 @@ EXPORT_SYMBOL(pci_scan_bridge); EXPORT_SYMBOL_GPL(pci_scan_child_bus); #endif -static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b) +static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b) { - const struct pci_dev *a = to_pci_dev(d_a); - const struct pci_dev *b = to_pci_dev(d_b); - if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1; else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1; @@ -1254,7 +1251,50 @@ static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device return 0; } +/* + * Yes, this forcably breaks the klist abstraction temporarily. It + * just wants to sort the klist, not change reference counts and + * take/drop locks rapidly in the process. It does all this while + * holding the lock for the list, so objects can't otherwise be + * added/removed while we're swizzling. + */ +static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list) +{ + struct list_head *pos; + struct klist_node *n; + struct device *dev; + struct pci_dev *b; + + list_for_each(pos, list) { + n = container_of(pos, struct klist_node, n_node); + dev = container_of(n, struct device, knode_bus); + b = to_pci_dev(dev); + if (pci_sort_bf_cmp(a, b) <= 0) { + list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node); + return; + } + } + list_move_tail(&a->dev.knode_bus.n_node, list); +} + void __init pci_sort_breadthfirst(void) { - bus_sort_breadthfirst(&pci_bus_type, &pci_sort_bf_cmp); + LIST_HEAD(sorted_devices); + struct list_head *pos, *tmp; + struct klist_node *n; + struct device *dev; + struct pci_dev *pdev; + struct klist *device_klist; + + device_klist = bus_get_device_klist(&pci_bus_type); + + spin_lock(&device_klist->k_lock); + list_for_each_safe(pos, tmp, &device_klist->k_list) { + n = container_of(pos, struct klist_node, n_node); + dev = container_of(n, struct device, knode_bus); + pdev = to_pci_dev(dev); + pci_insertion_sort_klist(pdev, &sorted_devices); + } + list_splice(&sorted_devices, &device_klist->k_list); + spin_unlock(&device_klist->k_lock); } diff --git a/trunk/drivers/pcmcia/Makefile b/trunk/drivers/pcmcia/Makefile index b46c60b72708..a87902de8d3b 100644 --- a/trunk/drivers/pcmcia/Makefile +++ b/trunk/drivers/pcmcia/Makefile @@ -2,6 +2,10 @@ # Makefile for the kernel pcmcia subsystem (c/o David Hinds) # +ifeq ($(CONFIG_PCMCIA_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif + pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o obj-$(CONFIG_PCCARD) += pcmcia_core.o @@ -64,11 +68,10 @@ sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o -pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o -pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o +pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o diff --git a/trunk/drivers/pcmcia/au1000_generic.c b/trunk/drivers/pcmcia/au1000_generic.c index fc1de46fd20a..75e8f8505e47 100644 --- a/trunk/drivers/pcmcia/au1000_generic.c +++ b/trunk/drivers/pcmcia/au1000_generic.c @@ -292,7 +292,7 @@ au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) skt->spd_io[map->map] = speed; } - map->start=(unsigned int)(u32)skt->virt_io; + map->start=(ioaddr_t)(u32)skt->virt_io; map->stop=map->start+MAP_SIZE; return 0; diff --git a/trunk/drivers/pcmcia/au1000_generic.h b/trunk/drivers/pcmcia/au1000_generic.h index 13a4fbc58711..a53ef5902518 100644 --- a/trunk/drivers/pcmcia/au1000_generic.h +++ b/trunk/drivers/pcmcia/au1000_generic.h @@ -116,7 +116,7 @@ struct au1000_pcmcia_socket { struct resource res_attr; void * virt_io; - unsigned int phys_io; + ioaddr_t phys_io; unsigned int phys_attr; unsigned int phys_mem; unsigned short speed_io, speed_attr, speed_mem; diff --git a/trunk/drivers/pcmcia/au1000_pb1x00.c b/trunk/drivers/pcmcia/au1000_pb1x00.c index d6b4bd1db7d7..aa1cd4d3aa29 100644 --- a/trunk/drivers/pcmcia/au1000_pb1x00.c +++ b/trunk/drivers/pcmcia/au1000_pb1x00.c @@ -37,6 +37,7 @@ #include #include #include +#include "cs_internal.h" #include #include diff --git a/trunk/drivers/pcmcia/au1000_xxs1500.c b/trunk/drivers/pcmcia/au1000_xxs1500.c index 9627390835ca..8a9b18cee847 100644 --- a/trunk/drivers/pcmcia/au1000_xxs1500.c +++ b/trunk/drivers/pcmcia/au1000_xxs1500.c @@ -41,6 +41,7 @@ #include #include #include +#include "cs_internal.h" #include #include diff --git a/trunk/drivers/pcmcia/cardbus.c b/trunk/drivers/pcmcia/cardbus.c index db77e1f3309a..911ca0e8dfc2 100644 --- a/trunk/drivers/pcmcia/cardbus.c +++ b/trunk/drivers/pcmcia/cardbus.c @@ -238,7 +238,7 @@ int __ref cb_alloc(struct pcmcia_socket * s) pci_bus_add_devices(bus); s->irq.AssignedIRQ = s->pci_irq; - return 0; + return CS_SUCCESS; } void cb_free(struct pcmcia_socket * s) diff --git a/trunk/drivers/pcmcia/cistpl.c b/trunk/drivers/pcmcia/cistpl.c index dcce9f5d8465..65129b54eb09 100644 --- a/trunk/drivers/pcmcia/cistpl.c +++ b/trunk/drivers/pcmcia/cistpl.c @@ -92,8 +92,7 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); if (mem->res == NULL) { - dev_printk(KERN_NOTICE, &s->dev, - "cs: unable to map card memory!\n"); + printk(KERN_NOTICE "cs: unable to map card memory!\n"); return NULL; } s->cis_virt = NULL; @@ -266,13 +265,13 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem); ======================================================================*/ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, - size_t len, void *ptr) + u_int len, void *ptr) { struct cis_cache_entry *cis; int ret; if (s->fake_cis) { - if (s->fake_cis_len >= addr+len) + if (s->fake_cis_len > addr+len) memcpy(ptr, s->fake_cis+addr, len); else memset(ptr, 0xff, len); @@ -352,9 +351,7 @@ int verify_cis_cache(struct pcmcia_socket *s) buf = kmalloc(256, GFP_KERNEL); if (buf == NULL) - dev_printk(KERN_WARNING, &s->dev, - "no memory for verifying CIS\n"); - return -ENOMEM; + return -1; list_for_each_entry(cis, &s->cis_cache, node) { int len = cis->len; @@ -383,22 +380,18 @@ int verify_cis_cache(struct pcmcia_socket *s) ======================================================================*/ -int pcmcia_replace_cis(struct pcmcia_socket *s, - const u8 *data, const size_t len) +int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis) { - if (len > CISTPL_MAX_CIS_SIZE) { - dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n"); - return -EINVAL; - } - kfree(s->fake_cis); - s->fake_cis = kmalloc(len, GFP_KERNEL); - if (s->fake_cis == NULL) { - dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n"); - return -ENOMEM; - } - s->fake_cis_len = len; - memcpy(s->fake_cis, data, len); - return 0; + kfree(s->fake_cis); + s->fake_cis = NULL; + if (cis->Length > CISTPL_MAX_CIS_SIZE) + return CS_BAD_SIZE; + s->fake_cis = kmalloc(cis->Length, GFP_KERNEL); + if (s->fake_cis == NULL) + return CS_OUT_OF_RESOURCE; + s->fake_cis_len = cis->Length; + memcpy(s->fake_cis, cis->Data, cis->Length); + return CS_SUCCESS; } EXPORT_SYMBOL(pcmcia_replace_cis); @@ -425,9 +418,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *t int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) { if (!s) - return -EINVAL; + return CS_BAD_HANDLE; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; tuple->TupleLink = tuple->Flags = 0; #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { @@ -447,10 +440,10 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple !(tuple->Attributes & TUPLE_RETURN_COMMON)) { cisdata_t req = tuple->DesiredTuple; tuple->DesiredTuple = CISTPL_LONGLINK_MFC; - if (pccard_get_next_tuple(s, function, tuple) == 0) { + if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) { tuple->DesiredTuple = CISTPL_LINKTARGET; - if (pccard_get_next_tuple(s, function, tuple) != 0) - return -ENOSPC; + if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS) + return CS_NO_MORE_ITEMS; } else tuple->CISOffset = tuple->TupleLink = 0; tuple->DesiredTuple = req; @@ -505,9 +498,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ int ofs, i, attr; if (!s) - return -EINVAL; + return CS_BAD_HANDLE; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; link[1] = tuple->TupleLink; ofs = tuple->CISOffset + tuple->TupleLink; @@ -526,7 +519,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ /* End of chain? Follow long link if possible */ if (link[0] == CISTPL_END) { if ((ofs = follow_link(s, tuple)) < 0) - return -ENOSPC; + return CS_NO_MORE_ITEMS; attr = SPACE(tuple->Flags); read_cis_cache(s, attr, ofs, 2, link); } @@ -584,13 +577,13 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ } if (i == MAX_TUPLES) { cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n"); - return -ENOSPC; + return CS_NO_MORE_ITEMS; } tuple->TupleCode = link[0]; tuple->TupleLink = link[1]; tuple->CISOffset = ofs + 2; - return 0; + return CS_SUCCESS; } EXPORT_SYMBOL(pccard_get_next_tuple); @@ -603,18 +596,18 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) u_int len; if (!s) - return -EINVAL; + return CS_BAD_HANDLE; if (tuple->TupleLink < tuple->TupleOffset) - return -ENOSPC; + return CS_NO_MORE_ITEMS; len = tuple->TupleLink - tuple->TupleOffset; tuple->TupleDataLen = tuple->TupleLink; if (len == 0) - return 0; + return CS_SUCCESS; read_cis_cache(s, SPACE(tuple->Flags), tuple->CISOffset + tuple->TupleOffset, _MIN(len, tuple->TupleDataMax), tuple->TupleData); - return 0; + return CS_SUCCESS; } EXPORT_SYMBOL(pccard_get_tuple_data); @@ -647,31 +640,25 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device) case 3: device->dev[i].speed = 150; break; case 4: device->dev[i].speed = 100; break; case 7: - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; device->dev[i].speed = SPEED_CVT(*p); while (*p & 0x80) - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; break; default: - return -EINVAL; + return CS_BAD_TUPLE; } - if (++p == q) - return -EINVAL; - if (*p == 0xff) - break; + if (++p == q) return CS_BAD_TUPLE; + if (*p == 0xff) break; scale = *p & 7; - if (scale == 7) - return -EINVAL; + if (scale == 7) return CS_BAD_TUPLE; device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); device->ndev++; - if (++p == q) - break; + if (++p == q) break; } - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -680,12 +667,12 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) { u_char *p; if (tuple->TupleDataLen < 5) - return -EINVAL; + return CS_BAD_TUPLE; p = (u_char *) tuple->TupleData; csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; csum->len = get_unaligned_le16(p + 2); csum->sum = *(p + 4); - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -693,9 +680,9 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) { if (tuple->TupleDataLen < 4) - return -EINVAL; + return CS_BAD_TUPLE; link->addr = get_unaligned_le32(tuple->TupleData); - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -710,13 +697,13 @@ static int parse_longlink_mfc(tuple_t *tuple, link->nfn = *p; p++; if (tuple->TupleDataLen <= link->nfn*5) - return -EINVAL; + return CS_BAD_TUPLE; for (i = 0; i < link->nfn; i++) { link->fn[i].space = *p; p++; link->fn[i].addr = get_unaligned_le32(p); p += 4; } - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -726,27 +713,24 @@ static int parse_strings(u_char *p, u_char *q, int max, { int i, j, ns; - if (p == q) - return -EINVAL; + if (p == q) return CS_BAD_TUPLE; ns = 0; j = 0; for (i = 0; i < max; i++) { - if (*p == 0xff) - break; + if (*p == 0xff) break; ofs[i] = j; ns++; for (;;) { s[j++] = (*p == 0xff) ? '\0' : *p; if ((*p == '\0') || (*p == 0xff)) break; - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; } if ((*p == 0xff) || (++p == q)) break; } if (found) { *found = ns; - return 0; + return CS_SUCCESS; } else { - return (ns == max) ? 0 : -EINVAL; + return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE; } } @@ -761,8 +745,7 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) vers_1->major = *p; p++; vers_1->minor = *p; p++; - if (p >= q) - return -EINVAL; + if (p >= q) return CS_BAD_TUPLE; return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, vers_1->str, vers_1->ofs, &vers_1->ns); @@ -798,7 +781,7 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) p += 2; } jedec->nid = nid; - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -806,10 +789,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) { if (tuple->TupleDataLen < 4) - return -EINVAL; + return CS_BAD_TUPLE; m->manf = get_unaligned_le16(tuple->TupleData); m->card = get_unaligned_le16(tuple->TupleData + 2); - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -818,11 +801,11 @@ static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f) { u_char *p; if (tuple->TupleDataLen < 2) - return -EINVAL; + return CS_BAD_TUPLE; p = (u_char *)tuple->TupleData; f->func = p[0]; f->sysinit = p[1]; - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -832,12 +815,12 @@ static int parse_funce(tuple_t *tuple, cistpl_funce_t *f) u_char *p; int i; if (tuple->TupleDataLen < 1) - return -EINVAL; + return CS_BAD_TUPLE; p = (u_char *)tuple->TupleData; f->type = p[0]; for (i = 1; i < tuple->TupleDataLen; i++) f->data[i-1] = p[i]; - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -851,7 +834,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config) rasz = *p & 0x03; rmsz = (*p & 0x3c) >> 2; if (tuple->TupleDataLen < rasz+rmsz+4) - return -EINVAL; + return CS_BAD_TUPLE; config->last_idx = *(++p); p++; config->base = 0; @@ -863,7 +846,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config) for (i = 0; i <= rmsz; i++) config->rmask[i>>2] += p[i] << (8*(i%4)); config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4); - return 0; + return CS_SUCCESS; } /*====================================================================== @@ -1019,12 +1002,10 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) { - if (p == q) - return NULL; + if (p == q) return NULL; irq->IRQInfo1 = *p; p++; if (irq->IRQInfo1 & IRQ_INFO2_VALID) { - if (p+2 > q) - return NULL; + if (p+2 > q) return NULL; irq->IRQInfo2 = (p[1]<<8) + p[0]; p += 2; } @@ -1045,8 +1026,7 @@ static int parse_cftable_entry(tuple_t *tuple, if (*p & 0x40) entry->flags |= CISTPL_CFTABLE_DEFAULT; if (*p & 0x80) { - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; if (*p & 0x10) entry->flags |= CISTPL_CFTABLE_BVDS; if (*p & 0x20) @@ -1060,35 +1040,30 @@ static int parse_cftable_entry(tuple_t *tuple, entry->interface = 0; /* Process optional features */ - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; features = *p; p++; /* Power options */ if ((features & 3) > 0) { p = parse_power(p, q, &entry->vcc); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->vcc.present = 0; if ((features & 3) > 1) { p = parse_power(p, q, &entry->vpp1); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->vpp1.present = 0; if ((features & 3) > 2) { p = parse_power(p, q, &entry->vpp2); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->vpp2.present = 0; /* Timing options */ if (features & 0x04) { p = parse_timing(p, q, &entry->timing); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else { entry->timing.wait = 0; entry->timing.ready = 0; @@ -1098,16 +1073,14 @@ static int parse_cftable_entry(tuple_t *tuple, /* I/O window options */ if (features & 0x08) { p = parse_io(p, q, &entry->io); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->io.nwin = 0; /* Interrupt options */ if (features & 0x10) { p = parse_irq(p, q, &entry->irq); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->irq.IRQInfo1 = 0; @@ -1121,8 +1094,7 @@ static int parse_cftable_entry(tuple_t *tuple, entry->mem.win[0].card_addr = 0; entry->mem.win[0].host_addr = 0; p += 2; - if (p > q) - return -EINVAL; + if (p > q) return CS_BAD_TUPLE; break; case 0x40: entry->mem.nwin = 1; @@ -1130,30 +1102,26 @@ static int parse_cftable_entry(tuple_t *tuple, entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8; entry->mem.win[0].host_addr = 0; p += 4; - if (p > q) - return -EINVAL; + if (p > q) return CS_BAD_TUPLE; break; case 0x60: p = parse_mem(p, q, &entry->mem); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; break; } /* Misc features */ if (features & 0x80) { - if (p == q) - return -EINVAL; + if (p == q) return CS_BAD_TUPLE; entry->flags |= (*p << 8); while (*p & 0x80) - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; p++; } entry->subtuples = q-p; - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -1164,12 +1132,12 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) { u_char *p; if (tuple->TupleDataLen < 6) - return -EINVAL; + return CS_BAD_TUPLE; p = (u_char *)tuple->TupleData; bar->attr = *p; p += 2; bar->size = get_unaligned_le32(p); - return 0; + return CS_SUCCESS; } static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) @@ -1178,12 +1146,12 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) p = (u_char *)tuple->TupleData; if ((*p != 3) || (tuple->TupleDataLen < 6)) - return -EINVAL; + return CS_BAD_TUPLE; config->last_idx = *(++p); p++; config->base = get_unaligned_le32(p); config->subtuples = tuple->TupleDataLen - 6; - return 0; + return CS_SUCCESS; } static int parse_cftable_entry_cb(tuple_t *tuple, @@ -1199,34 +1167,29 @@ static int parse_cftable_entry_cb(tuple_t *tuple, entry->flags |= CISTPL_CFTABLE_DEFAULT; /* Process optional features */ - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; features = *p; p++; /* Power options */ if ((features & 3) > 0) { p = parse_power(p, q, &entry->vcc); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->vcc.present = 0; if ((features & 3) > 1) { p = parse_power(p, q, &entry->vpp1); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->vpp1.present = 0; if ((features & 3) > 2) { p = parse_power(p, q, &entry->vpp2); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->vpp2.present = 0; /* I/O window options */ if (features & 0x08) { - if (p == q) - return -EINVAL; + if (p == q) return CS_BAD_TUPLE; entry->io = *p; p++; } else entry->io = 0; @@ -1234,37 +1197,32 @@ static int parse_cftable_entry_cb(tuple_t *tuple, /* Interrupt options */ if (features & 0x10) { p = parse_irq(p, q, &entry->irq); - if (p == NULL) - return -EINVAL; + if (p == NULL) return CS_BAD_TUPLE; } else entry->irq.IRQInfo1 = 0; if (features & 0x20) { - if (p == q) - return -EINVAL; + if (p == q) return CS_BAD_TUPLE; entry->mem = *p; p++; } else entry->mem = 0; /* Misc features */ if (features & 0x80) { - if (p == q) - return -EINVAL; + if (p == q) return CS_BAD_TUPLE; entry->flags |= (*p << 8); if (*p & 0x80) { - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; entry->flags |= (*p << 16); } while (*p & 0x80) - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; p++; } entry->subtuples = q-p; - return 0; + return CS_SUCCESS; } #endif @@ -1290,7 +1248,7 @@ static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo) p += 6; } geo->ngeo = n; - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -1300,7 +1258,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) u_char *p, *q; if (tuple->TupleDataLen < 10) - return -EINVAL; + return CS_BAD_TUPLE; p = tuple->TupleData; q = p + tuple->TupleDataLen; @@ -1324,18 +1282,15 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org) p = tuple->TupleData; q = p + tuple->TupleDataLen; - if (p == q) - return -EINVAL; + if (p == q) return CS_BAD_TUPLE; org->data_org = *p; - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; for (i = 0; i < 30; i++) { org->desc[i] = *p; if (*p == '\0') break; - if (++p == q) - return -EINVAL; + if (++p == q) return CS_BAD_TUPLE; } - return 0; + return CS_SUCCESS; } /*====================================================================*/ @@ -1345,7 +1300,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) u_char *p; if (tuple->TupleDataLen < 10) - return -EINVAL; + return CS_BAD_TUPLE; p = tuple->TupleData; @@ -1354,17 +1309,17 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) fmt->offset = get_unaligned_le32(p + 2); fmt->length = get_unaligned_le32(p + 6); - return 0; + return CS_SUCCESS; } /*====================================================================*/ -int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) +int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse) { - int ret = 0; + int ret = CS_SUCCESS; if (tuple->TupleDataLen > tuple->TupleDataMax) - return -EINVAL; + return CS_BAD_TUPLE; switch (tuple->TupleCode) { case CISTPL_DEVICE: case CISTPL_DEVICE_A: @@ -1432,17 +1387,15 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) break; case CISTPL_NO_LINK: case CISTPL_LINKTARGET: - ret = 0; + ret = CS_SUCCESS; break; default: - ret = -EINVAL; + ret = CS_UNSUPPORTED_FUNCTION; break; } - if (ret) - __cs_dbg(0, "parse_tuple failed %d\n", ret); return ret; } -EXPORT_SYMBOL(pcmcia_parse_tuple); +EXPORT_SYMBOL(pccard_parse_tuple); /*====================================================================== @@ -1457,22 +1410,18 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t int ret; buf = kmalloc(256, GFP_KERNEL); - if (buf == NULL) { - dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); - return -ENOMEM; - } + if (buf == NULL) + return CS_OUT_OF_RESOURCE; tuple.DesiredTuple = code; tuple.Attributes = TUPLE_RETURN_COMMON; ret = pccard_get_first_tuple(s, function, &tuple); - if (ret != 0) - goto done; + if (ret != CS_SUCCESS) goto done; tuple.TupleData = buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; ret = pccard_get_tuple_data(s, &tuple); - if (ret != 0) - goto done; - ret = pcmcia_parse_tuple(&tuple, parse); + if (ret != CS_SUCCESS) goto done; + ret = pccard_parse_tuple(&tuple, parse); done: kfree(buf); return ret; @@ -1497,40 +1446,37 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int ret, reserved, dev_ok = 0, ident_ok = 0; if (!s) - return -EINVAL; + return CS_BAD_HANDLE; tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); - if (tuple == NULL) { - dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); - return -ENOMEM; - } + if (tuple == NULL) + return CS_OUT_OF_RESOURCE; p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { - kfree(tuple); - dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); - return -ENOMEM; + kfree(tuple); + return CS_OUT_OF_RESOURCE; } count = reserved = 0; tuple->DesiredTuple = RETURN_FIRST_TUPLE; tuple->Attributes = TUPLE_RETURN_COMMON; ret = pccard_get_first_tuple(s, function, tuple); - if (ret != 0) + if (ret != CS_SUCCESS) goto done; /* First tuple should be DEVICE; we should really have either that or a CFTABLE_ENTRY of some sort */ if ((tuple->TupleCode == CISTPL_DEVICE) || - (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) || - (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0)) + (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) || + (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS)) dev_ok++; /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 tuple, for card identification. Certain old D-Link and Linksys cards have only a broken VERS_2 tuple; hence the bogus test. */ - if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) || - (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) || - (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC)) + if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) || + (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) || + (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS)) ident_ok++; if (!dev_ok && !ident_ok) @@ -1538,8 +1484,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned for (count = 1; count < MAX_TUPLES; count++) { ret = pccard_get_next_tuple(s, function, tuple); - if (ret != 0) - break; + if (ret != CS_SUCCESS) break; if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) @@ -1554,6 +1499,6 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned *info = count; kfree(tuple); kfree(p); - return 0; + return CS_SUCCESS; } EXPORT_SYMBOL(pccard_validate_cis); diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index c68c5d338285..d1207393fc3e 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -61,7 +61,7 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */ /* Access speed for attribute memory windows */ INT_MODULE_PARM(cis_speed, 300); /* ns */ -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG static int pc_debug; module_param(pc_debug, int, 0644); @@ -247,8 +247,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) wait_for_completion(&socket->thread_done); if (!socket->thread) { - dev_printk(KERN_WARNING, &socket->dev, - "PCMCIA: warning: socket thread did not start\n"); + printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket); return -EIO; } @@ -367,16 +366,16 @@ static int socket_reset(struct pcmcia_socket *skt) skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) - return -ENODEV; + return CS_NO_CARD; if (status & SS_READY) - return 0; + return CS_SUCCESS; msleep(unreset_check * 10); } cs_err(skt, "time out after reset.\n"); - return -ETIMEDOUT; + return CS_GENERAL_FAILURE; } /* @@ -413,8 +412,7 @@ static void socket_shutdown(struct pcmcia_socket *s) s->ops->get_status(s, &status); if (status & SS_POWERON) { - dev_printk(KERN_ERR, &s->dev, - "*** DANGER *** unable to remove socket power\n"); + printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); } cs_socket_put(s); @@ -428,14 +426,14 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) - return -ENODEV; + return CS_NO_CARD; msleep(initial_delay * 10); for (i = 0; i < 100; i++) { skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) - return -ENODEV; + return CS_NO_CARD; if (!(status & SS_PENDING)) break; @@ -445,13 +443,13 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) if (status & SS_PENDING) { cs_err(skt, "voltage interrogation timed out.\n"); - return -ETIMEDOUT; + return CS_GENERAL_FAILURE; } if (status & SS_CARDBUS) { if (!(skt->features & SS_CAP_CARDBUS)) { cs_err(skt, "cardbus cards are not supported.\n"); - return -EINVAL; + return CS_BAD_TYPE; } skt->state |= SOCKET_CARDBUS; } @@ -465,7 +463,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->socket.Vcc = skt->socket.Vpp = 50; else { cs_err(skt, "unsupported voltage key.\n"); - return -EIO; + return CS_BAD_TYPE; } if (skt->power_hook) @@ -482,7 +480,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->ops->get_status(skt, &status); if (!(status & SS_POWERON)) { cs_err(skt, "unable to apply power.\n"); - return -EIO; + return CS_BAD_TYPE; } status = socket_reset(skt); @@ -504,16 +502,15 @@ static int socket_insert(struct pcmcia_socket *skt) cs_dbg(skt, 4, "insert\n"); if (!cs_socket_get(skt)) - return -ENODEV; + return CS_NO_CARD; ret = socket_setup(skt, setup_delay); - if (ret == 0) { + if (ret == CS_SUCCESS) { skt->state |= SOCKET_PRESENT; - dev_printk(KERN_NOTICE, &skt->dev, - "pccard: %s card inserted into slot %d\n", - (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA", - skt->sock); + printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n", + (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA", + skt->sock); #ifdef CONFIG_CARDBUS if (skt->state & SOCKET_CARDBUS) { @@ -534,7 +531,7 @@ static int socket_insert(struct pcmcia_socket *skt) static int socket_suspend(struct pcmcia_socket *skt) { if (skt->state & SOCKET_SUSPEND) - return -EBUSY; + return CS_IN_USE; send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW); skt->socket = dead_socket; @@ -543,7 +540,7 @@ static int socket_suspend(struct pcmcia_socket *skt) skt->ops->suspend(skt); skt->state |= SOCKET_SUSPEND; - return 0; + return CS_SUCCESS; } /* @@ -556,7 +553,7 @@ static int socket_resume(struct pcmcia_socket *skt) int ret; if (!(skt->state & SOCKET_SUSPEND)) - return -EBUSY; + return CS_IN_USE; skt->socket = dead_socket; skt->ops->init(skt); @@ -568,7 +565,7 @@ static int socket_resume(struct pcmcia_socket *skt) } ret = socket_setup(skt, resume_delay); - if (ret == 0) { + if (ret == CS_SUCCESS) { /* * FIXME: need a better check here for cardbus cards. */ @@ -593,13 +590,12 @@ static int socket_resume(struct pcmcia_socket *skt) skt->state &= ~SOCKET_SUSPEND; - return 0; + return CS_SUCCESS; } static void socket_remove(struct pcmcia_socket *skt) { - dev_printk(KERN_NOTICE, &skt->dev, - "pccard: card ejected from slot %d\n", skt->sock); + printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); socket_shutdown(skt); } @@ -645,8 +641,8 @@ static int pccardd(void *__skt) /* register with the device core */ ret = device_register(&skt->dev); if (ret) { - dev_printk(KERN_WARNING, &skt->dev, - "PCMCIA: unable to register socket\n"); + printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", + skt); skt->thread = NULL; complete(&skt->thread_done); return 0; @@ -752,7 +748,7 @@ EXPORT_SYMBOL(pccard_register_pcmcia); * CIS register. */ -int pcmcia_reset_card(struct pcmcia_socket *skt) +int pccard_reset_card(struct pcmcia_socket *skt) { int ret; @@ -761,15 +757,15 @@ int pcmcia_reset_card(struct pcmcia_socket *skt) mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = -ENODEV; + ret = CS_NO_CARD; break; } if (skt->state & SOCKET_SUSPEND) { - ret = -EBUSY; + ret = CS_IN_USE; break; } if (skt->state & SOCKET_CARDBUS) { - ret = -EPERM; + ret = CS_UNSUPPORTED_FUNCTION; break; } @@ -778,20 +774,20 @@ int pcmcia_reset_card(struct pcmcia_socket *skt) send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); if (skt->callback) skt->callback->suspend(skt); - if (socket_reset(skt) == 0) { + if (socket_reset(skt) == CS_SUCCESS) { send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); if (skt->callback) skt->callback->resume(skt); } } - ret = 0; + ret = CS_SUCCESS; } while (0); mutex_unlock(&skt->skt_mutex); return ret; } /* reset_card */ -EXPORT_SYMBOL(pcmcia_reset_card); +EXPORT_SYMBOL(pccard_reset_card); /* These shut down or wake up a socket. They are sort of user @@ -806,11 +802,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = -ENODEV; + ret = CS_NO_CARD; break; } if (skt->state & SOCKET_CARDBUS) { - ret = -EPERM; + ret = CS_UNSUPPORTED_FUNCTION; break; } if (skt->callback) { @@ -836,11 +832,11 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = -ENODEV; + ret = CS_NO_CARD; break; } if (skt->state & SOCKET_CARDBUS) { - ret = -EPERM; + ret = CS_UNSUPPORTED_FUNCTION; break; } ret = socket_resume(skt); @@ -896,7 +892,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) ret = -EBUSY; break; } - if (socket_insert(skt) == -ENODEV) { + if (socket_insert(skt) == CS_NO_CARD) { ret = -ENODEV; break; } diff --git a/trunk/drivers/pcmcia/cs_internal.h b/trunk/drivers/pcmcia/cs_internal.h index 79615e6d540b..63dc1a28bda2 100644 --- a/trunk/drivers/pcmcia/cs_internal.h +++ b/trunk/drivers/pcmcia/cs_internal.h @@ -1,5 +1,5 @@ /* - * cs_internal.h -- definitions internal to the PCMCIA core modules + * cs_internal.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -10,12 +10,6 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds - * (C) 2003 - 2008 Dominik Brodowski - * - * - * This file contains definitions _only_ needed by the PCMCIA core modules. - * It must not be included by PCMCIA socket drivers or by PCMCIA device - * drivers. */ #ifndef _LINUX_CS_INTERNAL_H @@ -24,24 +18,29 @@ #include /* Flags in client state */ +#define CLIENT_CONFIG_LOCKED 0x0001 +#define CLIENT_IRQ_REQ 0x0002 +#define CLIENT_IO_REQ 0x0004 +#define CLIENT_UNBOUND 0x0008 +#define CLIENT_STALE 0x0010 #define CLIENT_WIN_REQ(i) (0x1<<(i)) +#define CLIENT_CARDBUS 0x8000 /* Each card function gets one of these guys */ typedef struct config_t { struct kref ref; - unsigned int state; - unsigned int Attributes; - unsigned int IntType; - unsigned int ConfigBase; - unsigned char Status, Pin, Copy, Option, ExtStatus; - unsigned int CardValues; - io_req_t io; - struct { - u_int Attributes; - } irq; + u_int state; + u_int Attributes; + u_int IntType; + u_int ConfigBase; + u_char Status, Pin, Copy, Option, ExtStatus; + u_int CardValues; + io_req_t io; + struct { + u_int Attributes; + } irq; } config_t; - struct cis_cache_entry { struct list_head node; unsigned int addr; @@ -50,30 +49,6 @@ struct cis_cache_entry { unsigned char cache[0]; }; -struct pccard_resource_ops { - int (*validate_mem) (struct pcmcia_socket *s); - int (*adjust_io_region) (struct resource *res, - unsigned long r_start, - unsigned long r_end, - struct pcmcia_socket *s); - struct resource* (*find_io) (unsigned long base, int num, - unsigned long align, - struct pcmcia_socket *s); - struct resource* (*find_mem) (unsigned long base, unsigned long num, - unsigned long align, int low, - struct pcmcia_socket *s); - int (*add_io) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); - int (*add_mem) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); - int (*init) (struct pcmcia_socket *s); - void (*exit) (struct pcmcia_socket *s); -}; - /* Flags in config state */ #define CONFIG_LOCKED 0x01 #define CONFIG_IRQ_REQ 0x02 @@ -84,6 +59,7 @@ struct pccard_resource_ops { #define SOCKET_INUSE 0x0010 #define SOCKET_SUSPEND 0x0080 #define SOCKET_WIN_REQ(i) (0x0100<<(i)) +#define SOCKET_REGION_INFO 0x4000 #define SOCKET_CARDBUS 0x8000 #define SOCKET_CARDBUS_CONFIG 0x10000 @@ -107,153 +83,69 @@ static inline void cs_socket_put(struct pcmcia_socket *skt) } } -#ifdef CONFIG_PCMCIA_DEBUG -extern int cs_debug_level(int); - -#define cs_dbg(skt, lvl, fmt, arg...) do { \ - if (cs_debug_level(lvl)) \ - dev_printk(KERN_DEBUG, &skt->dev, \ - "cs: " fmt, ## arg); \ -} while (0) -#define __cs_dbg(lvl, fmt, arg...) do { \ - if (cs_debug_level(lvl)) \ - printk(KERN_DEBUG \ - "cs: " fmt, ## arg); \ -} while (0) - -#else -#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0) -#define __cs_dbg(lvl, fmt, arg...) do { } while (0) -#endif - -#define cs_err(skt, fmt, arg...) \ - dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg) - - -/* - * Stuff internal to module "pcmcia_core": - */ +/* In cardbus.c */ +int cb_alloc(struct pcmcia_socket *s); +void cb_free(struct pcmcia_socket *s); +int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr); -/* cistpl.c */ +/* In cistpl.c */ +int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, + u_int addr, u_int len, void *ptr); +void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, + u_int addr, u_int len, void *ptr); +void release_cis_mem(struct pcmcia_socket *s); +void destroy_cis_cache(struct pcmcia_socket *s); int verify_cis_cache(struct pcmcia_socket *s); +int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse); -/* rsrc_mgr.c */ +/* In rsrc_mgr */ +int pcmcia_validate_mem(struct pcmcia_socket *s); +struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align, + struct pcmcia_socket *s); +int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, + unsigned long r_end, struct pcmcia_socket *s); +struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, + int low, struct pcmcia_socket *s); void release_resource_db(struct pcmcia_socket *s); -/* socket_sysfs.c */ +/* In socket_sysfs.c */ extern int pccard_sysfs_add_socket(struct device *dev); extern void pccard_sysfs_remove_socket(struct device *dev); -/* cardbus.c */ -int cb_alloc(struct pcmcia_socket *s); -void cb_free(struct pcmcia_socket *s); -int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, - void *ptr); - - +/* In cs.c */ +extern struct rw_semaphore pcmcia_socket_list_rwsem; +extern struct list_head pcmcia_socket_list; +int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req); +int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config); +int pccard_reset_card(struct pcmcia_socket *skt); -/* - * Stuff exported by module "pcmcia_core" to module "pcmcia" - */ struct pcmcia_callback{ struct module *owner; - int (*event) (struct pcmcia_socket *s, - event_t event, int priority); + int (*event) (struct pcmcia_socket *s, event_t event, int priority); void (*requery) (struct pcmcia_socket *s, int new_cis); int (*suspend) (struct pcmcia_socket *s); int (*resume) (struct pcmcia_socket *s); }; -/* cs.c */ -extern struct rw_semaphore pcmcia_socket_list_rwsem; -extern struct list_head pcmcia_socket_list; -extern struct class pcmcia_socket_class; - -int pcmcia_get_window(struct pcmcia_socket *s, - window_handle_t *handle, - int idx, - win_req_t *req); int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); -struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr); - -int pcmcia_suspend_card(struct pcmcia_socket *skt); -int pcmcia_resume_card(struct pcmcia_socket *skt); - -int pcmcia_eject_card(struct pcmcia_socket *skt); -int pcmcia_insert_card(struct pcmcia_socket *skt); - -struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt); -void pcmcia_put_socket(struct pcmcia_socket *skt); - -/* cistpl.c */ -int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, - u_int addr, u_int len, void *ptr); -void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, - u_int addr, u_int len, void *ptr); -void release_cis_mem(struct pcmcia_socket *s); -void destroy_cis_cache(struct pcmcia_socket *s); -int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, - cisdata_t code, void *parse); -int pcmcia_replace_cis(struct pcmcia_socket *s, - const u8 *data, const size_t len); -int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, - unsigned int *count); - -/* rsrc_mgr.c */ -int pcmcia_validate_mem(struct pcmcia_socket *s); -struct resource *pcmcia_find_io_region(unsigned long base, - int num, - unsigned long align, - struct pcmcia_socket *s); -int pcmcia_adjust_io_region(struct resource *res, - unsigned long r_start, - unsigned long r_end, - struct pcmcia_socket *s); -struct resource *pcmcia_find_mem_region(u_long base, - u_long num, - u_long align, - int low, - struct pcmcia_socket *s); - -/* - * Stuff internal to module "pcmcia". - */ -/* ds.c */ -extern struct bus_type pcmcia_bus_type; - -/* pcmcia_resource.c */ -extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); - -#ifdef CONFIG_PCMCIA_IOCTL -/* ds.c */ -extern spinlock_t pcmcia_dev_list_lock; - -extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev); -extern void pcmcia_put_dev(struct pcmcia_device *p_dev); -struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, - unsigned int function); +#define cs_socket_name(skt) ((skt)->dev.bus_id) -/* pcmcia_ioctl.c */ -extern void __init pcmcia_setup_ioctl(void); -extern void __exit pcmcia_cleanup_ioctl(void); -extern void handle_event(struct pcmcia_socket *s, event_t event); -extern int handle_request(struct pcmcia_socket *s, event_t event); +#ifdef DEBUG +extern int cs_debug_level(int); -#else /* CONFIG_PCMCIA_IOCTL */ +#define cs_dbg(skt, lvl, fmt, arg...) do { \ + if (cs_debug_level(lvl)) \ + printk(KERN_DEBUG "cs: %s: " fmt, \ + cs_socket_name(skt) , ## arg); \ +} while (0) -static inline void __init pcmcia_setup_ioctl(void) { return; } -static inline void __exit pcmcia_cleanup_ioctl(void) { return; } -static inline void handle_event(struct pcmcia_socket *s, event_t event) -{ - return; -} -static inline int handle_request(struct pcmcia_socket *s, event_t event) -{ - return 0; -} +#else +#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0) +#endif -#endif /* CONFIG_PCMCIA_IOCTL */ +#define cs_err(skt, fmt, arg...) \ + printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg) #endif /* _LINUX_CS_INTERNAL_H */ diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 795660255490..34c83d3ca0fa 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -32,6 +32,7 @@ #include #include "cs_internal.h" +#include "ds_internal.h" /*====================================================================*/ @@ -41,22 +42,17 @@ MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("PCMCIA Driver Services"); MODULE_LICENSE("GPL"); -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG int ds_pc_debug; module_param_named(pc_debug, ds_pc_debug, int, 0644); #define ds_dbg(lvl, fmt, arg...) do { \ - if (ds_pc_debug > (lvl)) \ - printk(KERN_DEBUG "ds: " fmt , ## arg); \ -} while (0) -#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \ if (ds_pc_debug > (lvl)) \ - dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \ + printk(KERN_DEBUG "ds: " fmt , ## arg); \ } while (0) #else #define ds_dbg(lvl, fmt, arg...) do { } while (0) -#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0) #endif spinlock_t pcmcia_dev_list_lock; @@ -68,19 +64,42 @@ spinlock_t pcmcia_dev_list_lock; /* String tables for error messages */ typedef struct lookup_t { - const int key; - const char *msg; + int key; + char *msg; } lookup_t; static const lookup_t error_table[] = { - { 0, "Operation succeeded" }, - { -EIO, "Input/Output error" }, - { -ENODEV, "No card present" }, - { -EINVAL, "Bad parameter" }, - { -EACCES, "Configuration locked" }, - { -EBUSY, "Resource in use" }, - { -ENOSPC, "No more items" }, - { -ENOMEM, "Out of resource" }, + { CS_SUCCESS, "Operation succeeded" }, + { CS_BAD_ADAPTER, "Bad adapter" }, + { CS_BAD_ATTRIBUTE, "Bad attribute", }, + { CS_BAD_BASE, "Bad base address" }, + { CS_BAD_EDC, "Bad EDC" }, + { CS_BAD_IRQ, "Bad IRQ" }, + { CS_BAD_OFFSET, "Bad offset" }, + { CS_BAD_PAGE, "Bad page number" }, + { CS_READ_FAILURE, "Read failure" }, + { CS_BAD_SIZE, "Bad size" }, + { CS_BAD_SOCKET, "Bad socket" }, + { CS_BAD_TYPE, "Bad type" }, + { CS_BAD_VCC, "Bad Vcc" }, + { CS_BAD_VPP, "Bad Vpp" }, + { CS_BAD_WINDOW, "Bad window" }, + { CS_WRITE_FAILURE, "Write failure" }, + { CS_NO_CARD, "No card present" }, + { CS_UNSUPPORTED_FUNCTION, "Usupported function" }, + { CS_UNSUPPORTED_MODE, "Unsupported mode" }, + { CS_BAD_SPEED, "Bad speed" }, + { CS_BUSY, "Resource busy" }, + { CS_GENERAL_FAILURE, "General failure" }, + { CS_WRITE_PROTECTED, "Write protected" }, + { CS_BAD_ARG_LENGTH, "Bad argument length" }, + { CS_BAD_ARGS, "Bad arguments" }, + { CS_CONFIGURATION_LOCKED, "Configuration locked" }, + { CS_IN_USE, "Resource in use" }, + { CS_NO_MORE_ITEMS, "No more items" }, + { CS_OUT_OF_RESOURCE, "Out of resource" }, + { CS_BAD_HANDLE, "Bad handle" }, + { CS_BAD_TUPLE, "Bad CIS tuple" } }; @@ -136,32 +155,46 @@ static const lookup_t service_table[] = { { ReplaceCIS, "ReplaceCIS" } }; -const char *pcmcia_error_func(int func) + +static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err) { int i; + char *serv; - for (i = 0; i < ARRAY_SIZE(service_table); i++) - if (service_table[i].key == func) - return service_table[i].msg; - - return "Unknown service number"; -} -EXPORT_SYMBOL(pcmcia_error_func); + if (!p_dev) + printk(KERN_NOTICE); + else + printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id); -const char *pcmcia_error_ret(int ret) -{ - int i; + for (i = 0; i < ARRAY_SIZE(service_table); i++) + if (service_table[i].key == err->func) + break; + if (i < ARRAY_SIZE(service_table)) + serv = service_table[i].msg; + else + serv = "Unknown service number"; for (i = 0; i < ARRAY_SIZE(error_table); i++) - if (error_table[i].key == ret) - return error_table[i].msg; + if (error_table[i].key == err->retcode) + break; + if (i < ARRAY_SIZE(error_table)) + printk("%s: %s\n", serv, error_table[i].msg); + else + printk("%s: Unknown error code %#x\n", serv, err->retcode); - return "unknown"; -} -EXPORT_SYMBOL(pcmcia_error_ret); + return CS_SUCCESS; +} /* report_error */ + +/* end of code which was in cs.c before */ /*======================================================================*/ +void cs_error(struct pcmcia_device *p_dev, int func, int ret) +{ + error_info_t err = { func, ret }; + pcmcia_report_error(p_dev, &err); +} +EXPORT_SYMBOL(cs_error); static void pcmcia_check_driver(struct pcmcia_driver *p_drv) @@ -358,7 +391,7 @@ static void pcmcia_release_function(struct kref *ref) static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - ds_dev_dbg(1, dev, "releasing device\n"); + ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id); pcmcia_put_socket(p_dev->socket); kfree(p_dev->devname); kref_put(&p_dev->function_config->ref, pcmcia_release_function); @@ -368,7 +401,7 @@ static void pcmcia_release_dev(struct device *dev) static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc) { if (!s->pcmcia_state.device_add_pending) { - ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary" + ds_dbg(1, "scheduling to add %s secondary" " device to %d\n", mfc ? "mfc" : "pfc", s->sock); s->pcmcia_state.device_add_pending = 1; s->pcmcia_state.mfc_pfc = mfc; @@ -406,7 +439,8 @@ static int pcmcia_device_probe(struct device * dev) */ did = p_dev->dev.driver_data; - ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name); + ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id, + p_drv->drv.name); if ((!p_drv->probe) || (!p_dev->function_config) || (!try_module_get(p_drv->owner))) { @@ -421,16 +455,15 @@ static int pcmcia_device_probe(struct device * dev) p_dev->conf.ConfigBase = cis_config.base; p_dev->conf.Present = cis_config.rmask[0]; } else { - dev_printk(KERN_INFO, dev, - "pcmcia: could not parse base and rmask0 of CIS\n"); + printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n"); p_dev->conf.ConfigBase = 0; p_dev->conf.Present = 0; } ret = p_drv->probe(p_dev); if (ret) { - ds_dev_dbg(1, dev, "binding to %s failed with %d\n", - p_drv->drv.name, ret); + ds_dbg(1, "binding %s to %s failed with %d\n", + p_dev->dev.bus_id, p_drv->drv.name, ret); goto put_module; } @@ -457,9 +490,8 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le struct pcmcia_device *tmp; unsigned long flags; - ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev, - "pcmcia_card_remove(%d) %s\n", s->sock, - leftover ? leftover->devname : ""); + ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock, + leftover ? leftover->devname : ""); if (!leftover) s->device_count = 0; @@ -476,7 +508,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le p_dev->_removed=1; spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - ds_dev_dbg(2, &p_dev->dev, "unregistering device\n"); + ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id); device_unregister(&p_dev->dev); } @@ -493,7 +525,7 @@ static int pcmcia_device_remove(struct device * dev) p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); - ds_dev_dbg(1, dev, "removing device\n"); + ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id); /* If we're removing the primary module driving a * pseudo multi-function card, we need to unbind @@ -516,15 +548,13 @@ static int pcmcia_device_remove(struct device * dev) /* check for proper unloading */ if (p_dev->_irq || p_dev->_io || p_dev->_locked) - dev_printk(KERN_INFO, dev, - "pcmcia: driver %s did not release config properly\n", - p_drv->drv.name); + printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", + p_drv->drv.name); for (i = 0; i < MAX_WIN; i++) if (p_dev->_win & CLIENT_WIN_REQ(i)) - dev_printk(KERN_INFO, dev, - "pcmcia: driver %s did not release window properly\n", - p_drv->drv.name); + printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", + p_drv->drv.name); /* references from pcmcia_probe_device */ pcmcia_put_dev(p_dev); @@ -573,9 +603,8 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) } if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_DEVICE_GEO, devgeo)) { - ds_dev_dbg(0, &p_dev->dev, - "mem device geometry probably means " - "FUNCID_MEMORY\n"); + ds_dbg(0, "mem device geometry probably means " + "FUNCID_MEMORY\n"); p_dev->func_id = CISTPL_FUNCID_MEMORY; p_dev->has_func_id = 1; } @@ -656,7 +685,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f if (!p_dev->devname) goto err_free; sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); - ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname); + ds_dbg(3, "devname is %s\n", p_dev->devname); spin_lock_irqsave(&pcmcia_dev_list_lock, flags); @@ -677,7 +706,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); if (!p_dev->function_config) { - ds_dev_dbg(3, &p_dev->dev, "creating config_t\n"); + ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id); p_dev->function_config = kzalloc(sizeof(struct config_t), GFP_KERNEL); if (!p_dev->function_config) @@ -685,9 +714,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f kref_init(&p_dev->function_config->ref); } - dev_printk(KERN_NOTICE, &p_dev->dev, - "pcmcia: registering new device %s\n", - p_dev->devname); + printk(KERN_NOTICE "pcmcia: registering new device %s\n", + p_dev->devname); pcmcia_device_query(p_dev); @@ -722,20 +750,19 @@ static int pcmcia_card_add(struct pcmcia_socket *s) int ret = 0; if (!(s->resource_setup_done)) { - ds_dev_dbg(3, &s->dev, - "no resources available, delaying card_add\n"); + ds_dbg(3, "no resources available, delaying card_add\n"); return -EAGAIN; /* try again, but later... */ } if (pcmcia_validate_mem(s)) { - ds_dev_dbg(3, &s->dev, "validating mem resources failed, " + ds_dbg(3, "validating mem resources failed, " "delaying card_add\n"); return -EAGAIN; /* try again, but later... */ } ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains); if (ret || !no_chains) { - ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n"); + ds_dbg(0, "invalid CIS or invalid resources\n"); return -ENODEV; } @@ -756,7 +783,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work) { struct pcmcia_socket *s = container_of(work, struct pcmcia_socket, device_add); - ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock); + ds_dbg(1, "adding additional device to %d\n", s->sock); pcmcia_device_add(s, s->pcmcia_state.mfc_pfc); s->pcmcia_state.device_add_pending = 0; s->pcmcia_state.mfc_pfc = 0; @@ -766,7 +793,8 @@ static int pcmcia_requery(struct device *dev, void * _data) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); if (!p_dev->dev.driver) { - ds_dev_dbg(1, dev, "update device information\n"); + ds_dbg(1, "update device information for %s\n", + p_dev->dev.bus_id); pcmcia_device_query(p_dev); } @@ -780,7 +808,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) unsigned long flags; /* must be called with skt_mutex held */ - ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock); + ds_dbg(0, "re-scanning socket %d\n", skt->sock); spin_lock_irqsave(&pcmcia_dev_list_lock, flags); if (list_empty(&skt->devices_list)) @@ -831,17 +859,17 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) int ret = -ENOMEM; int no_funcs; int old_funcs; + cisdump_t *cis; cistpl_longlink_mfc_t mfc; if (!filename) return -EINVAL; - ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename); + ds_dbg(1, "trying to load CIS file %s\n", filename); if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) { - dev_printk(KERN_WARNING, &dev->dev, - "pcmcia: CIS filename is too long [%s]\n", - filename); + printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n", + filename); return -EINVAL; } @@ -850,16 +878,23 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) if (request_firmware(&fw, path, &dev->dev) == 0) { if (fw->size >= CISTPL_MAX_CIS_SIZE) { ret = -EINVAL; - dev_printk(KERN_ERR, &dev->dev, - "pcmcia: CIS override is too big\n"); + printk(KERN_ERR "pcmcia: CIS override is too big\n"); goto release; } - if (!pcmcia_replace_cis(s, fw->data, fw->size)) + cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); + if (!cis) { + ret = -ENOMEM; + goto release; + } + + cis->Length = fw->size + 1; + memcpy(cis->Data, fw->data, fw->size); + + if (!pcmcia_replace_cis(s, cis)) ret = 0; else { - dev_printk(KERN_ERR, &dev->dev, - "pcmcia: CIS override failed\n"); + printk(KERN_ERR "pcmcia: CIS override failed\n"); goto release; } @@ -963,14 +998,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, * after it has re-checked that there is no possible module * with a prod_id/manf_id/card_id match. */ - ds_dev_dbg(0, &dev->dev, - "skipping FUNC_ID match until userspace interaction\n"); + ds_dbg(0, "skipping FUNC_ID match for %s until userspace " + "interaction\n", dev->dev.bus_id); if (!dev->allow_func_id_match) return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { - ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n"); + ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id); if (!dev->socket->fake_cis) pcmcia_load_firmware(dev, did->cisfile); @@ -1002,9 +1037,11 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { /* match dynamic devices first */ spin_lock(&p_drv->dynids.lock); list_for_each_entry(dynid, &p_drv->dynids.list, node) { - ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name); + ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, + drv->name); if (pcmcia_devmatch(p_dev, &dynid->id)) { - ds_dev_dbg(0, dev, "matched to %s\n", drv->name); + ds_dbg(0, "matched %s to %s\n", dev->bus_id, + drv->name); spin_unlock(&p_drv->dynids.lock); return 1; } @@ -1014,15 +1051,18 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { #ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) { - ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name); + ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id, + drv->name); return 1; } #endif while (did && did->match_flags) { - ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name); + ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, + drv->name); if (pcmcia_devmatch(p_dev, did)) { - ds_dev_dbg(0, dev, "matched to %s\n", drv->name); + ds_dbg(0, "matched %s to %s\n", dev->bus_id, + drv->name); return 1; } did++; @@ -1228,7 +1268,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) if (p_dev->suspended) return 0; - ds_dev_dbg(2, dev, "suspending\n"); + ds_dbg(2, "suspending %s\n", dev->bus_id); if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1239,16 +1279,15 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) if (p_drv->suspend) { ret = p_drv->suspend(p_dev); if (ret) { - dev_printk(KERN_ERR, dev, - "pcmcia: device %s (driver %s) did " - "not want to go to sleep (%d)\n", - p_dev->devname, p_drv->drv.name, ret); + printk(KERN_ERR "pcmcia: device %s (driver %s) did " + "not want to go to sleep (%d)\n", + p_dev->devname, p_drv->drv.name, ret); goto out; } } if (p_dev->device_no == p_dev->func) { - ds_dev_dbg(2, dev, "releasing configuration\n"); + ds_dbg(2, "releasing configuration for %s\n", dev->bus_id); pcmcia_release_configuration(p_dev); } @@ -1268,7 +1307,7 @@ static int pcmcia_dev_resume(struct device * dev) if (!p_dev->suspended) return 0; - ds_dev_dbg(2, dev, "resuming\n"); + ds_dbg(2, "resuming %s\n", dev->bus_id); if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1277,7 +1316,7 @@ static int pcmcia_dev_resume(struct device * dev) goto out; if (p_dev->device_no == p_dev->func) { - ds_dev_dbg(2, dev, "requesting configuration\n"); + ds_dbg(2, "requesting configuration for %s\n", dev->bus_id); ret = pcmcia_request_configuration(p_dev, &p_dev->conf); if (ret) goto out; @@ -1319,14 +1358,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data) static int pcmcia_bus_resume(struct pcmcia_socket *skt) { - ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock); + ds_dbg(2, "resuming socket %d\n", skt->sock); bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); return 0; } static int pcmcia_bus_suspend(struct pcmcia_socket *skt) { - ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock); + ds_dbg(2, "suspending socket %d\n", skt->sock); if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_suspend_callback)) { pcmcia_bus_resume(skt); @@ -1352,14 +1391,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) struct pcmcia_socket *s = pcmcia_get_socket(skt); if (!s) { - dev_printk(KERN_ERR, &skt->dev, - "PCMCIA obtaining reference to socket " \ - "failed, event 0x%x lost!\n", event); + printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \ + "failed, event 0x%x lost!\n", skt, event); return -ENODEV; } - ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", - event, priority, skt); + ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", + event, priority, skt); switch (event) { case CS_EVENT_CARD_REMOVAL: @@ -1434,8 +1472,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, socket = pcmcia_get_socket(socket); if (!socket) { - dev_printk(KERN_ERR, dev, - "PCMCIA obtaining reference to socket failed\n"); + printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket); return -ENODEV; } @@ -1455,7 +1492,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback); if (ret) { - dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n"); + printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket); pcmcia_put_socket(socket); return (ret); } diff --git a/trunk/drivers/pcmcia/ds_internal.h b/trunk/drivers/pcmcia/ds_internal.h new file mode 100644 index 000000000000..3a2b25e6ed73 --- /dev/null +++ b/trunk/drivers/pcmcia/ds_internal.h @@ -0,0 +1,23 @@ +/* ds_internal.h - internal header for 16-bit PCMCIA devices management */ + +extern spinlock_t pcmcia_dev_list_lock; +extern struct bus_type pcmcia_bus_type; + +extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev); +extern void pcmcia_put_dev(struct pcmcia_device *p_dev); + +struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function); + +extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); + +#ifdef CONFIG_PCMCIA_IOCTL +extern void __init pcmcia_setup_ioctl(void); +extern void __exit pcmcia_cleanup_ioctl(void); +extern void handle_event(struct pcmcia_socket *s, event_t event); +extern int handle_request(struct pcmcia_socket *s, event_t event); +#else +static inline void __init pcmcia_setup_ioctl(void) { return; } +static inline void __exit pcmcia_cleanup_ioctl(void) { return; } +static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; } +static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; } +#endif diff --git a/trunk/drivers/pcmcia/hd64465_ss.c b/trunk/drivers/pcmcia/hd64465_ss.c index 117dc12ab438..fb2bc1fb015d 100644 --- a/trunk/drivers/pcmcia/hd64465_ss.c +++ b/trunk/drivers/pcmcia/hd64465_ss.c @@ -46,6 +46,7 @@ #include #include #include +#include "cs_internal.h" #define MODNAME "hd64465_ss" diff --git a/trunk/drivers/pcmcia/i82365.c b/trunk/drivers/pcmcia/i82365.c index 71653ab84890..68f6b2702bc4 100644 --- a/trunk/drivers/pcmcia/i82365.c +++ b/trunk/drivers/pcmcia/i82365.c @@ -63,7 +63,7 @@ #include "vg468.h" #include "ricoh.h" -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG static const char version[] = "i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)"; diff --git a/trunk/drivers/pcmcia/m32r_cfc.c b/trunk/drivers/pcmcia/m32r_cfc.c index 2ab4f22c21de..3616da227152 100644 --- a/trunk/drivers/pcmcia/m32r_cfc.c +++ b/trunk/drivers/pcmcia/m32r_cfc.c @@ -38,7 +38,7 @@ #include "m32r_cfc.h" -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG static int m32r_cfc_debug; module_param(m32r_cfc_debug, int, 0644); #define debug(lvl, fmt, arg...) do { \ @@ -505,7 +505,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state) pcc_set(sock,(unsigned int)PLD_CFBUFCR,1); } -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG if(state->flags & SS_IOCARD){ debug(3, ":IOCARD"); } diff --git a/trunk/drivers/pcmcia/m32r_pcc.c b/trunk/drivers/pcmcia/m32r_pcc.c index 2f108c23dbd9..2b42b7155e34 100644 --- a/trunk/drivers/pcmcia/m32r_pcc.c +++ b/trunk/drivers/pcmcia/m32r_pcc.c @@ -45,7 +45,7 @@ #define PCC_DEBUG_DBEX -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG static int m32r_pcc_debug; module_param(m32r_pcc_debug, int, 0644); #define debug(lvl, fmt, arg...) do { \ @@ -460,7 +460,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state) pcc_set(sock,PCCSIGCR,reg); -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG if(state->flags & SS_IOCARD){ debug(3, ":IOCARD"); } diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index d1ad0966392d..ff66604e90d4 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -64,8 +64,8 @@ #include #include -#ifdef CONFIG_PCMCIA_DEBUG -static int pc_debug; +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0); #define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args); #else diff --git a/trunk/drivers/pcmcia/o2micro.h b/trunk/drivers/pcmcia/o2micro.h index 5554015a7813..a234ce1967a3 100644 --- a/trunk/drivers/pcmcia/o2micro.h +++ b/trunk/drivers/pcmcia/o2micro.h @@ -140,8 +140,7 @@ static int o2micro_override(struct yenta_socket *socket) a = config_readb(socket, O2_RESERVED1); b = config_readb(socket, O2_RESERVED2); - dev_printk(KERN_INFO, &socket->dev->dev, - "O2: res at 0x94/0xD4: %02x/%02x\n", a, b); + printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b); switch (socket->dev->device) { /* @@ -154,9 +153,7 @@ static int o2micro_override(struct yenta_socket *socket) case PCI_DEVICE_ID_O2_6812: case PCI_DEVICE_ID_O2_6832: case PCI_DEVICE_ID_O2_6836: - dev_printk(KERN_INFO, &socket->dev->dev, - "Yenta O2: old bridge, disabling read " - "prefetch/write burst\n"); + printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n"); config_writeb(socket, O2_RESERVED1, a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); config_writeb(socket, O2_RESERVED2, @@ -164,8 +161,7 @@ static int o2micro_override(struct yenta_socket *socket) break; default: - dev_printk(KERN_INFO , &socket->dev->dev, - "O2: enabling read prefetch/write burst\n"); + printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n"); config_writeb(socket, O2_RESERVED1, a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); config_writeb(socket, O2_RESERVED2, diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index 1703b20cad5d..419f97fc9a62 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -38,6 +38,7 @@ #include #include "cs_internal.h" +#include "ds_internal.h" static int major_dev = -1; @@ -57,7 +58,7 @@ typedef struct user_info_t { } user_info_t; -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG extern int ds_pc_debug; #define ds_dbg(lvl, fmt, arg...) do { \ @@ -148,7 +149,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) irq = adj->resource.irq.IRQ; if ((irq < 0) || (irq > 15)) - return -EINVAL; + return CS_BAD_IRQ; if (adj->Action != REMOVE_MANAGED_RESOURCE) return 0; @@ -166,7 +167,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) #else static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { - return 0; + return CS_SUCCESS; } #endif @@ -174,7 +175,7 @@ static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { static int pcmcia_adjust_resource_info(adjust_t *adj) { struct pcmcia_socket *s; - int ret = -ENOSYS; + int ret = CS_UNSUPPORTED_FUNCTION; unsigned long flags; down_read(&pcmcia_socket_list_rwsem); @@ -247,7 +248,7 @@ static int pccard_get_status(struct pcmcia_socket *s, if (s->state & SOCKET_SUSPEND) status->CardState |= CS_EVENT_PM_SUSPEND; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; c = (p_dev) ? p_dev->function_config : NULL; @@ -273,7 +274,7 @@ static int pccard_get_status(struct pcmcia_socket *s, status->CardState |= (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; } - return 0; + return CS_SUCCESS; } status->CardState |= (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; @@ -283,81 +284,9 @@ static int pccard_get_status(struct pcmcia_socket *s, (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; status->CardState |= (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; - return 0; + return CS_SUCCESS; } /* pccard_get_status */ -int pccard_get_configuration_info(struct pcmcia_socket *s, - struct pcmcia_device *p_dev, - config_info_t *config) -{ - config_t *c; - - if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; - - -#ifdef CONFIG_CARDBUS - if (s->state & SOCKET_CARDBUS) { - memset(config, 0, sizeof(config_info_t)); - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - config->Option = s->cb_dev->subordinate->number; - if (s->state & SOCKET_CARDBUS_CONFIG) { - config->Attributes = CONF_VALID_CLIENT; - config->IntType = INT_CARDBUS; - config->AssignedIRQ = s->irq.AssignedIRQ; - if (config->AssignedIRQ) - config->Attributes |= CONF_ENABLE_IRQ; - if (s->io[0].res) { - config->BasePort1 = s->io[0].res->start; - config->NumPorts1 = s->io[0].res->end - - config->BasePort1 + 1; - } - } - return 0; - } -#endif - - if (p_dev) { - c = p_dev->function_config; - config->Function = p_dev->func; - } else { - c = NULL; - config->Function = 0; - } - - if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { - config->Attributes = 0; - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - return 0; - } - - config->Attributes = c->Attributes | CONF_VALID_CLIENT; - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - config->IntType = c->IntType; - config->ConfigBase = c->ConfigBase; - config->Status = c->Status; - config->Pin = c->Pin; - config->Copy = c->Copy; - config->Option = c->Option; - config->ExtStatus = c->ExtStatus; - config->Present = config->CardValues = c->CardValues; - config->IRQAttributes = c->irq.Attributes; - config->AssignedIRQ = s->irq.AssignedIRQ; - config->BasePort1 = c->io.BasePort1; - config->NumPorts1 = c->io.NumPorts1; - config->Attributes1 = c->io.Attributes1; - config->BasePort2 = c->io.BasePort2; - config->NumPorts2 = c->io.NumPorts2; - config->Attributes2 = c->io.Attributes2; - config->IOAddrLines = c->io.IOAddrLines; - - return 0; -} /* pccard_get_configuration_info */ - - /*====================================================================== These manage a ring buffer of events pending for one user process @@ -835,7 +764,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, case DS_GET_CONFIGURATION_INFO: if (buf->config.Function && (buf->config.Function >= s->functions)) - ret = -EINVAL; + ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); ret = pccard_get_configuration_info(s, p_dev, &buf->config); @@ -858,15 +787,15 @@ static int ds_ioctl(struct inode * inode, struct file * file, break; case DS_PARSE_TUPLE: buf->tuple.TupleData = buf->tuple_parse.data; - ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); + ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); break; case DS_RESET_CARD: - ret = pcmcia_reset_card(s); + ret = pccard_reset_card(s); break; case DS_GET_STATUS: if (buf->status.Function && (buf->status.Function >= s->functions)) - ret = -EINVAL; + ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); ret = pccard_get_status(s, p_dev, &buf->status); @@ -897,7 +826,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, goto free_out; } - ret = -EINVAL; + ret = CS_BAD_ARGS; if (!(buf->conf_reg.Function && (buf->conf_reg.Function >= s->functions))) { @@ -938,7 +867,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, &buf->win_info.map); break; case DS_REPLACE_CIS: - ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length); + ret = pcmcia_replace_cis(s, &buf->cisdump); break; case DS_BIND_REQUEST: if (!capable(CAP_SYS_ADMIN)) { @@ -960,19 +889,22 @@ static int ds_ioctl(struct inode * inode, struct file * file, err = -EINVAL; } - if ((err == 0) && (ret != 0)) { + if ((err == 0) && (ret != CS_SUCCESS)) { ds_dbg(2, "ds_ioctl: ret = %d\n", ret); switch (ret) { - case -ENODEV: - case -EINVAL: - case -EBUSY: - case -ENOSYS: - err = ret; - break; - case -ENOMEM: + case CS_BAD_SOCKET: case CS_NO_CARD: + err = -ENODEV; break; + case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ: + case CS_BAD_TUPLE: + err = -EINVAL; break; + case CS_IN_USE: + err = -EBUSY; break; + case CS_OUT_OF_RESOURCE: err = -ENOSPC; break; - case -ENOSPC: + case CS_NO_MORE_ITEMS: err = -ENODATA; break; + case CS_UNSUPPORTED_FUNCTION: + err = -ENOSYS; break; default: err = -EIO; break; } diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index afea2b2558b5..4884a18cf9e6 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -29,6 +29,7 @@ #include #include "cs_internal.h" +#include "ds_internal.h" /* Access speed for IO windows */ @@ -43,17 +44,16 @@ static u8 pcmcia_used_irq[NR_IRQS]; #endif -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG extern int ds_pc_debug; #define ds_dbg(skt, lvl, fmt, arg...) do { \ if (ds_pc_debug >= lvl) \ - dev_printk(KERN_DEBUG, &skt->dev, \ - "pcmcia_resource: " fmt, \ - ## arg); \ + printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \ + cs_socket_name(skt) , ## arg); \ } while (0) #else -#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0) +#define ds_dbg(lvl, fmt, arg...) do { } while (0) #endif @@ -168,13 +168,13 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, u_char val; if (!p_dev || !p_dev->function_config) - return -EINVAL; + return CS_NO_CARD; s = p_dev->socket; c = p_dev->function_config; if (!(c->state & CONFIG_LOCKED)) - return -EACCES; + return CS_CONFIGURATION_LOCKED; addr = (c->ConfigBase + reg->Offset) >> 1; @@ -188,14 +188,93 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, pcmcia_write_cis_mem(s, 1, addr, 1, &val); break; default: - return -EINVAL; + return CS_BAD_ARGS; break; } - return 0; + return CS_SUCCESS; } /* pcmcia_access_configuration_register */ EXPORT_SYMBOL(pcmcia_access_configuration_register); +int pccard_get_configuration_info(struct pcmcia_socket *s, + struct pcmcia_device *p_dev, + config_info_t *config) +{ + config_t *c; + + if (!(s->state & SOCKET_PRESENT)) + return CS_NO_CARD; + + +#ifdef CONFIG_CARDBUS + if (s->state & SOCKET_CARDBUS) { + memset(config, 0, sizeof(config_info_t)); + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + config->Option = s->cb_dev->subordinate->number; + if (s->state & SOCKET_CARDBUS_CONFIG) { + config->Attributes = CONF_VALID_CLIENT; + config->IntType = INT_CARDBUS; + config->AssignedIRQ = s->irq.AssignedIRQ; + if (config->AssignedIRQ) + config->Attributes |= CONF_ENABLE_IRQ; + if (s->io[0].res) { + config->BasePort1 = s->io[0].res->start; + config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; + } + } + return CS_SUCCESS; + } +#endif + + if (p_dev) { + c = p_dev->function_config; + config->Function = p_dev->func; + } else { + c = NULL; + config->Function = 0; + } + + if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { + config->Attributes = 0; + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + return CS_SUCCESS; + } + + config->Attributes = c->Attributes | CONF_VALID_CLIENT; + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + config->IntType = c->IntType; + config->ConfigBase = c->ConfigBase; + config->Status = c->Status; + config->Pin = c->Pin; + config->Copy = c->Copy; + config->Option = c->Option; + config->ExtStatus = c->ExtStatus; + config->Present = config->CardValues = c->CardValues; + config->IRQAttributes = c->irq.Attributes; + config->AssignedIRQ = s->irq.AssignedIRQ; + config->BasePort1 = c->io.BasePort1; + config->NumPorts1 = c->io.NumPorts1; + config->Attributes1 = c->io.Attributes1; + config->BasePort2 = c->io.BasePort2; + config->NumPorts2 = c->io.NumPorts2; + config->Attributes2 = c->io.Attributes2; + config->IOAddrLines = c->io.IOAddrLines; + + return CS_SUCCESS; +} /* pccard_get_configuration_info */ + +int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, + config_info_t *config) +{ + return pccard_get_configuration_info(p_dev->socket, p_dev, + config); +} +EXPORT_SYMBOL(pcmcia_get_configuration_info); + + /** pcmcia_get_window */ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, @@ -205,12 +284,12 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int w; if (!s || !(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; for (w = idx; w < MAX_WIN; w++) if (s->state & SOCKET_WIN_REQ(w)) break; if (w == MAX_WIN) - return -EINVAL; + return CS_NO_MORE_ITEMS; win = &s->win[w]; req->Base = win->ctl.res->start; req->Size = win->ctl.res->end - win->ctl.res->start + 1; @@ -225,7 +304,7 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, if (win->ctl.flags & MAP_USE_WAIT) req->Attributes |= WIN_USE_WAIT; *handle = win; - return 0; + return CS_SUCCESS; } /* pcmcia_get_window */ EXPORT_SYMBOL(pcmcia_get_window); @@ -237,10 +316,10 @@ EXPORT_SYMBOL(pcmcia_get_window); int pcmcia_get_mem_page(window_handle_t win, memreq_t *req) { if ((win == NULL) || (win->magic != WINDOW_MAGIC)) - return -EINVAL; + return CS_BAD_HANDLE; req->Page = 0; req->CardOffset = win->ctl.card_start; - return 0; + return CS_SUCCESS; } /* pcmcia_get_mem_page */ EXPORT_SYMBOL(pcmcia_get_mem_page); @@ -249,18 +328,14 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req) { struct pcmcia_socket *s; if ((win == NULL) || (win->magic != WINDOW_MAGIC)) - return -EINVAL; + return CS_BAD_HANDLE; + if (req->Page != 0) + return CS_BAD_PAGE; s = win->sock; - if (req->Page != 0) { - ds_dbg(s, 0, "failure: requested page is zero\n"); - return -EINVAL; - } win->ctl.card_start = req->CardOffset; - if (s->ops->set_mem_map(s, &win->ctl) != 0) { - ds_dbg(s, 0, "failed to set_mem_map\n"); - return -EIO; - } - return 0; + if (s->ops->set_mem_map(s, &win->ctl) != 0) + return CS_BAD_OFFSET; + return CS_SUCCESS; } /* pcmcia_map_mem_page */ EXPORT_SYMBOL(pcmcia_map_mem_page); @@ -279,9 +354,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, c = p_dev->function_config; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; if (!(c->state & CONFIG_LOCKED)) - return -EACCES; + return CS_CONFIGURATION_LOCKED; if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { if (mod->Attributes & CONF_ENABLE_IRQ) { @@ -294,28 +369,20 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, s->ops->set_socket(s, &s->socket); } - if (mod->Attributes & CONF_VCC_CHANGE_VALID) { - ds_dbg(s, 0, "changing Vcc is not allowed at this time\n"); - return -EINVAL; - } + if (mod->Attributes & CONF_VCC_CHANGE_VALID) + return CS_BAD_VCC; /* We only allow changing Vpp1 and Vpp2 to the same value */ if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { if (mod->Vpp1 != mod->Vpp2) - ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n"); - return -EINVAL; + return CS_BAD_VPP; s->socket.Vpp = mod->Vpp1; - if (s->ops->set_socket(s, &s->socket)) { - dev_printk(KERN_WARNING, &s->dev, - "Unable to set VPP\n"); - return -EIO; - } + if (s->ops->set_socket(s, &s->socket)) + return CS_BAD_VPP; } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || - (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { - ds_dbg(s, 0, "changing Vcc is not allowed at this time\n"); - return -EINVAL; - } + (mod->Attributes & CONF_VPP2_CHANGE_VALID)) + return CS_BAD_VPP; if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { pccard_io_map io_off = { 0, 0, 0, 0, 1 }; @@ -339,7 +406,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, } } - return 0; + return CS_SUCCESS; } /* modify_configuration */ EXPORT_SYMBOL(pcmcia_modify_configuration); @@ -374,7 +441,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) } } - return 0; + return CS_SUCCESS; } /* pcmcia_release_configuration */ @@ -392,7 +459,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) config_t *c = p_dev->function_config; if (!p_dev->_io ) - return -EINVAL; + return CS_BAD_HANDLE; p_dev->_io = 0; @@ -400,7 +467,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) (c->io.NumPorts1 != req->NumPorts1) || (c->io.BasePort2 != req->BasePort2) || (c->io.NumPorts2 != req->NumPorts2)) - return -EINVAL; + return CS_BAD_ARGS; c->state &= ~CONFIG_IO_REQ; @@ -408,7 +475,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) if (req->NumPorts2) release_io_space(s, req->BasePort2, req->NumPorts2); - return 0; + return CS_SUCCESS; } /* pcmcia_release_io */ @@ -418,19 +485,15 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) config_t *c= p_dev->function_config; if (!p_dev->_irq) - return -EINVAL; + return CS_BAD_HANDLE; p_dev->_irq = 0; if (c->state & CONFIG_LOCKED) - return -EACCES; - if (c->irq.Attributes != req->Attributes) { - ds_dbg(s, 0, "IRQ attributes must match assigned ones\n"); - return -EINVAL; - } - if (s->irq.AssignedIRQ != req->AssignedIRQ) { - ds_dbg(s, 0, "IRQ must match assigned one\n"); - return -EINVAL; - } + return CS_CONFIGURATION_LOCKED; + if (c->irq.Attributes != req->Attributes) + return CS_BAD_ATTRIBUTE; + if (s->irq.AssignedIRQ != req->AssignedIRQ) + return CS_BAD_IRQ; if (--s->irq.Config == 0) { c->state &= ~CONFIG_IRQ_REQ; s->irq.AssignedIRQ = 0; @@ -444,7 +507,7 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) pcmcia_used_irq[req->AssignedIRQ]--; #endif - return 0; + return CS_SUCCESS; } /* pcmcia_release_irq */ @@ -453,10 +516,10 @@ int pcmcia_release_window(window_handle_t win) struct pcmcia_socket *s; if ((win == NULL) || (win->magic != WINDOW_MAGIC)) - return -EINVAL; + return CS_BAD_HANDLE; s = win->sock; if (!(win->handle->_win & CLIENT_WIN_REQ(win->index))) - return -EINVAL; + return CS_BAD_HANDLE; /* Shut down memory window */ win->ctl.flags &= ~MAP_ACTIVE; @@ -473,7 +536,7 @@ int pcmcia_release_window(window_handle_t win) win->magic = 0; - return 0; + return CS_SUCCESS; } /* pcmcia_release_window */ EXPORT_SYMBOL(pcmcia_release_window); @@ -488,23 +551,18 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, pccard_io_map iomap; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV;; + return CS_NO_CARD; - if (req->IntType & INT_CARDBUS) { - ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n"); - return -EINVAL; - } + if (req->IntType & INT_CARDBUS) + return CS_UNSUPPORTED_MODE; c = p_dev->function_config; if (c->state & CONFIG_LOCKED) - return -EACCES; + return CS_CONFIGURATION_LOCKED; /* Do power control. We don't allow changes in Vcc. */ s->socket.Vpp = req->Vpp; - if (s->ops->set_socket(s, &s->socket)) { - dev_printk(KERN_WARNING, &s->dev, - "Unable to set socket state\n"); - return -EINVAL; - } + if (s->ops->set_socket(s, &s->socket)) + return CS_BAD_VPP; /* Pick memory or I/O card, DMA mode, interrupt */ c->IntType = req->IntType; @@ -593,7 +651,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, c->state |= CONFIG_LOCKED; p_dev->_locked = 1; - return 0; + return CS_SUCCESS; } /* pcmcia_request_configuration */ EXPORT_SYMBOL(pcmcia_request_configuration); @@ -609,48 +667,37 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) config_t *c; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; if (!req) - return -EINVAL; + return CS_UNSUPPORTED_MODE; c = p_dev->function_config; if (c->state & CONFIG_LOCKED) - return -EACCES; - if (c->state & CONFIG_IO_REQ) { - ds_dbg(s, 0, "IO already configured\n"); - return -EBUSY; - } - if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) { - ds_dbg(s, 0, "bad attribute setting for IO region 1\n"); - return -EINVAL; - } + return CS_CONFIGURATION_LOCKED; + if (c->state & CONFIG_IO_REQ) + return CS_IN_USE; + if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) + return CS_BAD_ATTRIBUTE; if ((req->NumPorts2 > 0) && - (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) { - ds_dbg(s, 0, "bad attribute setting for IO region 2\n"); - return -EINVAL; - } + (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) + return CS_BAD_ATTRIBUTE; - ds_dbg(s, 1, "trying to allocate resource 1\n"); if (alloc_io_space(s, req->Attributes1, &req->BasePort1, - req->NumPorts1, req->IOAddrLines)) { - ds_dbg(s, 0, "allocation of resource 1 failed\n"); - return -EBUSY; - } + req->NumPorts1, req->IOAddrLines)) + return CS_IN_USE; if (req->NumPorts2) { - ds_dbg(s, 1, "trying to allocate resource 2\n"); if (alloc_io_space(s, req->Attributes2, &req->BasePort2, req->NumPorts2, req->IOAddrLines)) { - ds_dbg(s, 0, "allocation of resource 2 failed\n"); release_io_space(s, req->BasePort1, req->NumPorts1); - return -EBUSY; + return CS_IN_USE; } } c->io = *req; c->state |= CONFIG_IO_REQ; p_dev->_io = 1; - return 0; + return CS_SUCCESS; } /* pcmcia_request_io */ EXPORT_SYMBOL(pcmcia_request_io); @@ -676,18 +723,16 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) { struct pcmcia_socket *s = p_dev->socket; config_t *c; - int ret = -EINVAL, irq = 0; + int ret = CS_IN_USE, irq = 0; int type; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; + return CS_NO_CARD; c = p_dev->function_config; if (c->state & CONFIG_LOCKED) - return -EACCES; - if (c->state & CONFIG_IRQ_REQ) { - ds_dbg(s, 0, "IRQ already configured\n"); - return -EBUSY; - } + return CS_CONFIGURATION_LOCKED; + if (c->state & CONFIG_IRQ_REQ) + return CS_IN_USE; /* Decide what type of interrupt we are registering */ type = 0; @@ -750,19 +795,15 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) { - ret = request_irq(irq, req->Handler, type, - p_dev->devname, req->Instance); - if (ret) - return ret; + if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance)) + return CS_IN_USE; } /* Make sure the fact the request type was overridden is passed back */ if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; - dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " - "request for exclusive IRQ could not be fulfilled.\n"); - dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " - "needs updating to supported shared IRQ lines.\n"); + printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n"); + printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n"); } c->irq.Attributes = req->Attributes; s->irq.AssignedIRQ = req->AssignedIRQ = irq; @@ -775,7 +816,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) pcmcia_used_irq[irq]++; #endif - return 0; + return CS_SUCCESS; } /* pcmcia_request_irq */ EXPORT_SYMBOL(pcmcia_request_irq); @@ -793,11 +834,9 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h int w; if (!(s->state & SOCKET_PRESENT)) - return -ENODEV; - if (req->Attributes & (WIN_PAGED | WIN_SHARED)) { - ds_dbg(s, 0, "bad attribute setting for iomem region\n"); - return -EINVAL; - } + return CS_NO_CARD; + if (req->Attributes & (WIN_PAGED | WIN_SHARED)) + return CS_BAD_ATTRIBUTE; /* Window size defaults to smallest available */ if (req->Size == 0) @@ -805,25 +844,19 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h align = (((s->features & SS_CAP_MEM_ALIGN) || (req->Attributes & WIN_STRICT_ALIGN)) ? req->Size : s->map_size); - if (req->Size & (s->map_size-1)) { - ds_dbg(s, 0, "invalid map size\n"); - return -EINVAL; - } + if (req->Size & (s->map_size-1)) + return CS_BAD_SIZE; if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || - (req->Base & (align-1))) { - ds_dbg(s, 0, "invalid base address\n"); - return -EINVAL; - } + (req->Base & (align-1))) + return CS_BAD_BASE; if (req->Base) align = 0; /* Allocate system memory window */ for (w = 0; w < MAX_WIN; w++) if (!(s->state & SOCKET_WIN_REQ(w))) break; - if (w == MAX_WIN) { - ds_dbg(s, 0, "all windows are used already\n"); - return -EINVAL; - } + if (w == MAX_WIN) + return CS_OUT_OF_RESOURCE; win = &s->win[w]; win->magic = WINDOW_MAGIC; @@ -834,10 +867,8 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h if (!(s->features & SS_CAP_STATIC_MAP)) { win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align, (req->Attributes & WIN_MAP_BELOW_1MB), s); - if (!win->ctl.res) { - ds_dbg(s, 0, "allocating mem region failed\n"); - return -EINVAL; - } + if (!win->ctl.res) + return CS_IN_USE; } (*p_dev)->_win |= CLIENT_WIN_REQ(w); @@ -854,10 +885,8 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h if (req->Attributes & WIN_USE_WAIT) win->ctl.flags |= MAP_USE_WAIT; win->ctl.card_start = 0; - if (s->ops->set_mem_map(s, &win->ctl) != 0) { - ds_dbg(s, 0, "failed to set memory mapping\n"); - return -EIO; - } + if (s->ops->set_mem_map(s, &win->ctl) != 0) + return CS_BAD_ARGS; s->state |= SOCKET_WIN_REQ(w); /* Return window handle */ @@ -868,7 +897,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h } *wh = win; - return 0; + return CS_SUCCESS; } /* pcmcia_request_window */ EXPORT_SYMBOL(pcmcia_request_window); @@ -880,79 +909,3 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { pcmcia_release_window(p_dev->win); } EXPORT_SYMBOL(pcmcia_disable_device); - - -struct pcmcia_cfg_mem { - tuple_t tuple; - cisparse_t parse; - u8 buf[256]; - cistpl_cftable_entry_t dflt; -}; - -/** - * pcmcia_loop_config() - loop over configuration options - * @p_dev: the struct pcmcia_device which we need to loop for. - * @conf_check: function to call for each configuration option. - * It gets passed the struct pcmcia_device, the CIS data - * describing the configuration option, and private data - * being passed to pcmcia_loop_config() - * @priv_data: private data to be passed to the conf_check function. - * - * pcmcia_loop_config() loops over all configuration options, and calls - * the driver-specific conf_check() for each one, checking whether - * it is a valid one. - */ -int pcmcia_loop_config(struct pcmcia_device *p_dev, - int (*conf_check) (struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data), - void *priv_data) -{ - struct pcmcia_cfg_mem *cfg_mem; - - tuple_t *tuple; - int ret = -ENODEV; - unsigned int vcc; - - cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); - if (cfg_mem == NULL) - return -ENOMEM; - - /* get the current Vcc setting */ - vcc = p_dev->socket->socket.Vcc; - - tuple = &cfg_mem->tuple; - tuple->TupleData = cfg_mem->buf; - tuple->TupleDataMax = 255; - tuple->TupleOffset = 0; - tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple->Attributes = 0; - - ret = pcmcia_get_first_tuple(p_dev, tuple); - while (!ret) { - cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry; - - if (pcmcia_get_tuple_data(p_dev, tuple)) - goto next_entry; - - if (pcmcia_parse_tuple(tuple, &cfg_mem->parse)) - goto next_entry; - - /* default values */ - p_dev->conf.ConfigIndex = cfg->index; - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - cfg_mem->dflt = *cfg; - - ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data); - if (!ret) - break; - -next_entry: - ret = pcmcia_get_next_tuple(p_dev, tuple); - } - - return ret; -} -EXPORT_SYMBOL(pcmcia_loop_config); diff --git a/trunk/drivers/pcmcia/pxa2xx_base.c b/trunk/drivers/pcmcia/pxa2xx_base.c index bb9ddb9532e3..13f1e0fd3f31 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.c +++ b/trunk/drivers/pcmcia/pxa2xx_base.c @@ -36,6 +36,7 @@ #include #include +#include "cs_internal.h" #include "soc_common.h" #include "pxa2xx_base.h" diff --git a/trunk/drivers/pcmcia/rsrc_nonstatic.c b/trunk/drivers/pcmcia/rsrc_nonstatic.c index 17f4ecf1c0c5..203e579ebbd2 100644 --- a/trunk/drivers/pcmcia/rsrc_nonstatic.c +++ b/trunk/drivers/pcmcia/rsrc_nonstatic.c @@ -122,22 +122,19 @@ static void free_region(struct resource *res) static int add_interval(struct resource_map *map, u_long base, u_long num) { - struct resource_map *p, *q; + struct resource_map *p, *q; - for (p = map; ; p = p->next) { - if ((p != map) && (p->base+p->num-1 >= base)) - return -1; - if ((p->next == map) || (p->next->base > base+num-1)) - break; - } - q = kmalloc(sizeof(struct resource_map), GFP_KERNEL); - if (!q) { - printk(KERN_WARNING "out of memory to update resources\n"); - return -ENOMEM; - } - q->base = base; q->num = num; - q->next = p->next; p->next = q; - return 0; + for (p = map; ; p = p->next) { + if ((p != map) && (p->base+p->num-1 >= base)) + return -1; + if ((p->next == map) || (p->next->base > base+num-1)) + break; + } + q = kmalloc(sizeof(struct resource_map), GFP_KERNEL); + if (!q) return CS_OUT_OF_RESOURCE; + q->base = base; q->num = num; + q->next = p->next; p->next = q; + return CS_SUCCESS; } /*====================================================================*/ @@ -169,10 +166,7 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num) } else { /* Split the block into two pieces */ p = kmalloc(sizeof(struct resource_map), GFP_KERNEL); - if (!p) { - printk(KERN_WARNING "out of memory to update resources\n"); - return -ENOMEM; - } + if (!p) return CS_OUT_OF_RESOURCE; p->base = base+num; p->num = q->base+q->num - p->base; q->num = base - q->base; @@ -180,7 +174,7 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num) } } } - return 0; + return CS_SUCCESS; } /*====================================================================== @@ -200,14 +194,13 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, int any; u_char *b, hole, most; - dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:", - base, base+num-1); + printk(KERN_INFO "cs: IO port probe %#x-%#x:", + base, base+num-1); /* First, what does a floating port look like? */ b = kzalloc(256, GFP_KERNEL); if (!b) { - dev_printk(KERN_ERR, &s->dev, - "do_io_probe: unable to kmalloc 256 bytes"); + printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); return; } for (i = base, most = 0; i < base+num; i += 8) { @@ -373,8 +366,8 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s) struct socket_data *s_data = s->resource_data; u_long i, j, bad, fail, step; - dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:", - base, base+num-1); + printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:", + base, base+num-1); bad = fail = 0; step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff); /* don't allow too large steps */ @@ -438,8 +431,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) if (probe_mask & MEM_PROBE_HIGH) { if (inv_probe(s_data->mem_db.next, s) > 0) return 0; - dev_printk(KERN_NOTICE, &s->dev, - "cs: warning: no high memory space available!\n"); + printk(KERN_NOTICE "cs: warning: no high memory space " + "available!\n"); return -ENODEV; } @@ -801,11 +794,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_IO) { if (res == &ioport_resource) continue; - dev_printk(KERN_INFO, &s->cb_dev->dev, - "pcmcia: parent PCI bridge I/O " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + printk(KERN_INFO "pcmcia: parent PCI bridge I/O " + "window: 0x%llx - 0x%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_IO; @@ -814,11 +806,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_MEM) { if (res == &iomem_resource) continue; - dev_printk(KERN_INFO, &s->cb_dev->dev, - "pcmcia: parent PCI bridge Memory " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + printk(KERN_INFO "pcmcia: parent PCI bridge Memory " + "window: 0x%llx - 0x%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_MEM; } diff --git a/trunk/drivers/pcmcia/soc_common.c b/trunk/drivers/pcmcia/soc_common.c index f49ac6666153..da3972153226 100644 --- a/trunk/drivers/pcmcia/soc_common.c +++ b/trunk/drivers/pcmcia/soc_common.c @@ -54,7 +54,7 @@ #include #endif -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG static int pc_debug; module_param(pc_debug, int, 0644); diff --git a/trunk/drivers/pcmcia/soc_common.h b/trunk/drivers/pcmcia/soc_common.h index 38c67375f363..91ef6a0da3ab 100644 --- a/trunk/drivers/pcmcia/soc_common.h +++ b/trunk/drivers/pcmcia/soc_common.h @@ -15,6 +15,7 @@ #include #include #include +#include "cs_internal.h" struct device; @@ -136,7 +137,7 @@ extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_lev extern int soc_common_drv_pcmcia_remove(struct device *dev); -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, int lvl, const char *fmt, ...); diff --git a/trunk/drivers/pcmcia/socket_sysfs.c b/trunk/drivers/pcmcia/socket_sysfs.c index ff9a3bb3c88d..006a29e91d83 100644 --- a/trunk/drivers/pcmcia/socket_sysfs.c +++ b/trunk/drivers/pcmcia/socket_sysfs.c @@ -316,18 +316,27 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj)); + cisdump_t *cis; int error; if (off) return -EINVAL; - if (count >= CISTPL_MAX_CIS_SIZE) + if (count >= 0x200) return -EINVAL; if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - error = pcmcia_replace_cis(s, buf, count); + cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); + if (!cis) + return -ENOMEM; + + cis->Length = count + 1; + memcpy(cis->Data, buf, count); + + error = pcmcia_replace_cis(s, cis); + kfree(cis); if (error) return -EIO; diff --git a/trunk/drivers/pcmcia/tcic.c b/trunk/drivers/pcmcia/tcic.c index 2a613e920fd4..5792bd5c54f9 100644 --- a/trunk/drivers/pcmcia/tcic.c +++ b/trunk/drivers/pcmcia/tcic.c @@ -55,7 +55,7 @@ #include #include "tcic.h" -#ifdef CONFIG_PCMCIA_DEBUG +#ifdef DEBUG static int pc_debug; module_param(pc_debug, int, 0644); diff --git a/trunk/drivers/pcmcia/ti113x.h b/trunk/drivers/pcmcia/ti113x.h index aaa70227bfb0..129db7bd06c3 100644 --- a/trunk/drivers/pcmcia/ti113x.h +++ b/trunk/drivers/pcmcia/ti113x.h @@ -339,8 +339,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket) mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); devctl = config_readb(socket, TI113X_DEVICE_CONTROL); - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl); + printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n", + pci_name(socket->dev), mfunc, devctl); /* make sure PCI interrupts are enabled before probing */ ti_init(socket); @@ -354,8 +354,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket) * We're here which means PCI interrupts are _not_ delivered. try to * find the right setting (all serial or parallel) */ - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: probing PCI interrupt failed, trying to fix\n"); + printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n", + pci_name(socket->dev)); /* for serial PCI make sure MFUNC3 is set to IRQSER */ if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) { @@ -379,8 +379,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket) pci_irq_status = yenta_probe_cb_irq(socket); if (pci_irq_status == 1) { - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: all-serial interrupts ok\n"); + printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts ok\n", + pci_name(socket->dev)); mfunc_old = mfunc; goto out; } @@ -395,8 +395,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket) } /* serial PCI interrupts not working fall back to parallel */ - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: falling back to parallel PCI interrupts\n"); + printk(KERN_INFO "Yenta TI: socket %s falling back to parallel PCI interrupts\n", + pci_name(socket->dev)); devctl &= ~TI113X_DCR_IMODE_MASK; devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */ config_writeb(socket, TI113X_DEVICE_CONTROL, devctl); @@ -427,8 +427,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket) pci_irq_status = yenta_probe_cb_irq(socket); if (pci_irq_status == 1) { mfunc_old = mfunc; - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: parallel PCI interrupts ok\n"); + printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n", + pci_name(socket->dev)); } else { /* not working, back to old value */ mfunc = mfunc_old; @@ -440,9 +440,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket) out: if (pci_irq_status < 1) { socket->cb_irq = 0; - dev_printk(KERN_INFO, &socket->dev->dev, - "Yenta TI: no PCI interrupts. Fish. " - "Please report.\n"); + printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n", + pci_name(socket->dev)); } } @@ -514,9 +513,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); devctl = config_readb(socket, TI113X_DEVICE_CONTROL); - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: mfunc 0x%08x, devctl 0x%02x\n", - mfunc, devctl); + printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n", + pci_name(socket->dev), mfunc, devctl); /* if IRQs are configured as tied, align irq of func1 with func0 */ sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); @@ -535,8 +533,9 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) * We're here which means PCI interrupts are _not_ delivered. try to * find the right setting */ - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: probing PCI interrupt failed, trying to fix\n"); + printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n", + pci_name(socket->dev)); + /* if all serial: set INTRTIE, probe again */ if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) { @@ -545,8 +544,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) if (ti12xx_tie_interrupts(socket, &old_irq)) { pci_irq_status = yenta_probe_cb_irq(socket); if (pci_irq_status == 1) { - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: all-serial interrupts, tied ok\n"); + printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts, tied ok\n", + pci_name(socket->dev)); goto out; } @@ -583,8 +582,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) pci_irq_status = yenta_probe_cb_irq(socket); if (pci_irq_status == 1) { - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: parallel PCI interrupts ok\n"); + printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n", + pci_name(socket->dev)); goto out; } @@ -594,13 +593,13 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) if (pci_irq_status == -1) goto out; } - + /* still nothing: set INTRTIE */ if (ti12xx_tie_interrupts(socket, &old_irq)) { pci_irq_status = yenta_probe_cb_irq(socket); if (pci_irq_status == 1) { - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: parallel PCI interrupts, tied ok\n"); + printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts, tied ok\n", + pci_name(socket->dev)); goto out; } @@ -611,8 +610,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) out: if (pci_irq_status < 1) { socket->cb_irq = 0; - dev_printk(KERN_INFO, &socket->dev->dev, - "TI: no PCI interrupts. Fish. Please report.\n"); + printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n", + pci_name(socket->dev)); } } @@ -816,13 +815,11 @@ static int ti12xx_override(struct yenta_socket *socket) /* make sure that memory burst is active */ val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL); if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) { - dev_printk(KERN_INFO, &socket->dev->dev, - "Disabling CLKRUN feature\n"); + printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n"); val |= TI113X_SCR_KEEPCLK; } if (!(val & TI122X_SCR_MRBURSTUP)) { - dev_printk(KERN_INFO, &socket->dev->dev, - "Enabling burst memory read transactions\n"); + printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n"); val |= TI122X_SCR_MRBURSTUP; } if (val_orig != val) @@ -833,12 +830,10 @@ static int ti12xx_override(struct yenta_socket *socket) * CSC interrupts to PCI rather than INTVAL. */ val = config_readb(socket, TI1250_DIAGNOSTIC); - dev_printk(KERN_INFO, &socket->dev->dev, - "Using %s to route CSC interrupts to PCI\n", - (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL"); - dev_printk(KERN_INFO, &socket->dev->dev, - "Routing CardBus interrupts to %s\n", - (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA"); + printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n", + (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL"); + printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n", + (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA"); /* do irqrouting, depending on function */ if (PCI_FUNC(socket->dev->devfn) == 0) @@ -863,9 +858,8 @@ static int ti1250_override(struct yenta_socket *socket) diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; if (diag != old) { - dev_printk(KERN_INFO, &socket->dev->dev, - "adjusting diagnostic: %02x -> %02x\n", - old, diag); + printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n", + old, diag); config_writeb(socket, TI1250_DIAGNOSTIC, diag); } @@ -930,9 +924,7 @@ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) /* default to clear TLTEnable bit, old behaviour */ test_c9 &= ~ENE_TEST_C9_TLTENABLE; - dev_printk(KERN_INFO, &socket->dev->dev, - "EnE: chaning testregister 0xC9, %02x -> %02x\n", - old_c9, test_c9); + printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9); config_writeb(socket, ENE_TEST_C9, test_c9); } diff --git a/trunk/drivers/pcmcia/yenta_socket.c b/trunk/drivers/pcmcia/yenta_socket.c index 3ecd7c99d8eb..0ab1fb65cdc3 100644 --- a/trunk/drivers/pcmcia/yenta_socket.c +++ b/trunk/drivers/pcmcia/yenta_socket.c @@ -38,7 +38,11 @@ static int pwr_irqs_off; module_param(pwr_irqs_off, bool, 0644); MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!"); -#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args) +#if 0 +#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) +#else +#define debug(x,args...) +#endif /* Don't ask.. */ #define to_cycles(ns) ((ns)/120) @@ -65,13 +69,13 @@ MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation"); static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg) { u32 val = readl(socket->base + reg); - debug("%04x %08x\n", socket, reg, val); + debug("%p %04x %08x\n", socket, reg, val); return val; } static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val) { - debug("%04x %08x\n", socket, reg, val); + debug("%p %04x %08x\n", socket, reg, val); writel(val, socket->base + reg); readl(socket->base + reg); /* avoid problems with PCI write posting */ } @@ -80,7 +84,7 @@ static inline u8 config_readb(struct yenta_socket *socket, unsigned offset) { u8 val; pci_read_config_byte(socket->dev, offset, &val); - debug("%04x %02x\n", socket, offset, val); + debug("%p %04x %02x\n", socket, offset, val); return val; } @@ -88,7 +92,7 @@ static inline u16 config_readw(struct yenta_socket *socket, unsigned offset) { u16 val; pci_read_config_word(socket->dev, offset, &val); - debug("%04x %04x\n", socket, offset, val); + debug("%p %04x %04x\n", socket, offset, val); return val; } @@ -96,32 +100,32 @@ static inline u32 config_readl(struct yenta_socket *socket, unsigned offset) { u32 val; pci_read_config_dword(socket->dev, offset, &val); - debug("%04x %08x\n", socket, offset, val); + debug("%p %04x %08x\n", socket, offset, val); return val; } static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val) { - debug("%04x %02x\n", socket, offset, val); + debug("%p %04x %02x\n", socket, offset, val); pci_write_config_byte(socket->dev, offset, val); } static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val) { - debug("%04x %04x\n", socket, offset, val); + debug("%p %04x %04x\n", socket, offset, val); pci_write_config_word(socket->dev, offset, val); } static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val) { - debug("%04x %08x\n", socket, offset, val); + debug("%p %04x %08x\n", socket, offset, val); pci_write_config_dword(socket->dev, offset, val); } static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg) { u8 val = readb(socket->base + 0x800 + reg); - debug("%04x %02x\n", socket, reg, val); + debug("%p %04x %02x\n", socket, reg, val); return val; } @@ -130,20 +134,20 @@ static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg) u16 val; val = readb(socket->base + 0x800 + reg); val |= readb(socket->base + 0x800 + reg + 1) << 8; - debug("%04x %04x\n", socket, reg, val); + debug("%p %04x %04x\n", socket, reg, val); return val; } static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val) { - debug("%04x %02x\n", socket, reg, val); + debug("%p %04x %02x\n", socket, reg, val); writeb(val, socket->base + 0x800 + reg); readb(socket->base + 0x800 + reg); /* PCI write posting... */ } static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val) { - debug("%04x %04x\n", socket, reg, val); + debug("%p %04x %04x\n", socket, reg, val); writeb(val, socket->base + 0x800 + reg); writeb(val >> 8, socket->base + 0x800 + reg + 1); @@ -203,7 +207,7 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value) if (state & CB_CBCARD) { - val |= SS_CARDBUS; + val |= SS_CARDBUS; val |= (state & CB_CARDSTS) ? SS_STSCHG : 0; val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT; val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0; @@ -646,10 +650,8 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type root = pci_find_parent_resource(socket->dev, res); if (root && (request_resource(root, res) == 0)) return 0; - dev_printk(KERN_INFO, &socket->dev->dev, - "Preassigned resource %d busy or not available, " - "reconfiguring...\n", - nr); + printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n", + pci_name(socket->dev), nr); } if (type & IORESOURCE_IO) { @@ -672,9 +674,8 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type return 1; } - dev_printk(KERN_INFO, &socket->dev->dev, - "no resource of type %x available, trying to continue...\n", - type); + printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n", + pci_name(socket->dev), type); res->start = res->end = res->flags = 0; return 0; } @@ -922,8 +923,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) socket->probe_status = 0; if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) { - dev_printk(KERN_WARNING, &socket->dev->dev, - "request_irq() in yenta_probe_cb_irq() failed!\n"); + printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n"); return -1; } @@ -960,9 +960,8 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i else socket->socket.irq_mask = 0; - dev_printk(KERN_INFO, &socket->dev->dev, - "ISA IRQ mask 0x%04x, PCI irq %d\n", - socket->socket.irq_mask, socket->cb_irq); + printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", + socket->socket.irq_mask, socket->cb_irq); } /* @@ -1052,9 +1051,8 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) /* Show that the wanted subordinate number is not possible: */ if (cardbus_bridge->subordinate > upper_limit) - dev_printk(KERN_WARNING, &cardbus_bridge->dev, - "Upper limit for fixing this " - "bridge's parent bridge: #%02x\n", upper_limit); + printk(KERN_WARNING "Yenta: Upper limit for fixing this " + "bridge's parent bridge: #%02x\n", upper_limit); /* If we have room to increase the bridge's subordinate number, */ if (bridge_to_fix->subordinate < upper_limit) { @@ -1063,11 +1061,10 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) unsigned char subordinate_to_assign = min(cardbus_bridge->subordinate, upper_limit); - dev_printk(KERN_INFO, &bridge_to_fix->dev, - "Raising subordinate bus# of parent " - "bus (#%02x) from #%02x to #%02x\n", - bridge_to_fix->number, - bridge_to_fix->subordinate, subordinate_to_assign); + printk(KERN_INFO "Yenta: Raising subordinate bus# of parent " + "bus (#%02x) from #%02x to #%02x\n", + bridge_to_fix->number, + bridge_to_fix->subordinate, subordinate_to_assign); /* Save the new subordinate in the bus struct of the bridge */ bridge_to_fix->subordinate = subordinate_to_assign; @@ -1094,8 +1091,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i * Bail out if so. */ if (!dev->subordinate) { - dev_printk(KERN_ERR, &dev->dev, "no bus associated! " - "(try 'pci=assign-busses')\n"); + printk(KERN_ERR "Yenta: no bus associated with %s! " + "(try 'pci=assign-busses')\n", pci_name(dev)); return -ENODEV; } @@ -1130,7 +1127,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i goto disable; if (!pci_resource_start(dev, 0)) { - dev_printk(KERN_ERR, &dev->dev, "No cardbus resource!\n"); + printk(KERN_ERR "No cardbus resource!\n"); ret = -ENODEV; goto release; } @@ -1149,8 +1146,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i * report the subsystem vendor and device for help debugging * the irq stuff... */ - dev_printk(KERN_INFO, &dev->dev, "CardBus bridge found [%04x:%04x]\n", - dev->subsystem_vendor, dev->subsystem_device); + printk(KERN_INFO "Yenta: CardBus bridge found at %s [%04x:%04x]\n", + pci_name(dev), dev->subsystem_vendor, dev->subsystem_device); yenta_config_init(socket); @@ -1182,12 +1179,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i socket->poll_timer.data = (unsigned long)socket; socket->poll_timer.expires = jiffies + HZ; add_timer(&socket->poll_timer); - dev_printk(KERN_INFO, &dev->dev, - "no PCI IRQ, CardBus support disabled for this " - "socket.\n"); - dev_printk(KERN_INFO, &dev->dev, - "check your BIOS CardBus, BIOS IRQ or ACPI " - "settings.\n"); + printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n" + KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n"); } else { socket->socket.features |= SS_CAP_CARDBUS; } @@ -1195,8 +1188,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i /* Figure out what the dang thing can do for the PCMCIA layer... */ yenta_interrogate(socket); yenta_get_socket_capabilities(socket, isa_interrupts); - dev_printk(KERN_INFO, &dev->dev, - "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); + printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); yenta_fixup_parent_bridge(dev->subordinate); diff --git a/trunk/drivers/pnp/base.h b/trunk/drivers/pnp/base.h index 3b8b9d3cb03d..9fd7bb9b7dce 100644 --- a/trunk/drivers/pnp/base.h +++ b/trunk/drivers/pnp/base.h @@ -4,7 +4,6 @@ */ extern spinlock_t pnp_lock; -extern struct device_attribute pnp_interface_attrs[]; void *pnp_alloc(long size); int pnp_register_protocol(struct pnp_protocol *protocol); @@ -17,6 +16,7 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid); int pnp_add_device(struct pnp_dev *dev); struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id); +int pnp_interface_attach_device(struct pnp_dev *dev); int pnp_add_card(struct pnp_card *card); void pnp_remove_card(struct pnp_card *card); @@ -147,7 +147,7 @@ char *pnp_resource_type_name(struct resource *res); void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); void pnp_free_resources(struct pnp_dev *dev); -unsigned long pnp_resource_type(struct resource *res); +int pnp_resource_type(struct resource *res); struct pnp_resource { struct list_head list; diff --git a/trunk/drivers/pnp/core.c b/trunk/drivers/pnp/core.c index 817fe626e15b..a411582bcd72 100644 --- a/trunk/drivers/pnp/core.c +++ b/trunk/drivers/pnp/core.c @@ -159,13 +159,21 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid int __pnp_add_device(struct pnp_dev *dev) { + int ret; + pnp_fixup_device(dev); dev->status = PNP_READY; spin_lock(&pnp_lock); list_add_tail(&dev->global_list, &pnp_global); list_add_tail(&dev->protocol_list, &dev->protocol->devices); spin_unlock(&pnp_lock); - return device_register(&dev->dev); + + ret = device_register(&dev->dev); + if (ret) + return ret; + + pnp_interface_attach_device(dev); + return 0; } /* @@ -210,6 +218,7 @@ void __pnp_remove_device(struct pnp_dev *dev) static int __init pnp_init(void) { + printk(KERN_INFO "Linux Plug and Play Support v0.97 (c) Adam Belay\n"); return bus_register(&pnp_bus_type); } diff --git a/trunk/drivers/pnp/driver.c b/trunk/drivers/pnp/driver.c index e3f7e89c4dfb..d3f869ee1d92 100644 --- a/trunk/drivers/pnp/driver.c +++ b/trunk/drivers/pnp/driver.c @@ -206,7 +206,6 @@ struct bus_type pnp_bus_type = { .remove = pnp_device_remove, .suspend = pnp_bus_suspend, .resume = pnp_bus_resume, - .dev_attrs = pnp_interface_attrs, }; int pnp_register_driver(struct pnp_driver *drv) diff --git a/trunk/drivers/pnp/interface.c b/trunk/drivers/pnp/interface.c index 478a4a739c00..a876ecf7028c 100644 --- a/trunk/drivers/pnp/interface.c +++ b/trunk/drivers/pnp/interface.c @@ -243,6 +243,8 @@ static ssize_t pnp_show_options(struct device *dmdev, return ret; } +static DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL); + static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_attribute *attr, char *buf) @@ -418,6 +420,9 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, return count; } +static DEVICE_ATTR(resources, S_IRUGO | S_IWUSR, + pnp_show_current_resources, pnp_set_current_resources); + static ssize_t pnp_show_current_ids(struct device *dmdev, struct device_attribute *attr, char *buf) { @@ -432,11 +437,27 @@ static ssize_t pnp_show_current_ids(struct device *dmdev, return (str - buf); } -struct device_attribute pnp_interface_attrs[] = { - __ATTR(resources, S_IRUGO | S_IWUSR, - pnp_show_current_resources, - pnp_set_current_resources), - __ATTR(options, S_IRUGO, pnp_show_options, NULL), - __ATTR(id, S_IRUGO, pnp_show_current_ids, NULL), - __ATTR_NULL, -}; +static DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL); + +int pnp_interface_attach_device(struct pnp_dev *dev) +{ + int rc = device_create_file(&dev->dev, &dev_attr_options); + + if (rc) + goto err; + rc = device_create_file(&dev->dev, &dev_attr_resources); + if (rc) + goto err_opt; + rc = device_create_file(&dev->dev, &dev_attr_id); + if (rc) + goto err_res; + + return 0; + +err_res: + device_remove_file(&dev->dev, &dev_attr_resources); +err_opt: + device_remove_file(&dev->dev, &dev_attr_options); +err: + return rc; +} diff --git a/trunk/drivers/pnp/isapnp/core.c b/trunk/drivers/pnp/isapnp/core.c index 46455fbab6d5..101a835e8759 100644 --- a/trunk/drivers/pnp/isapnp/core.c +++ b/trunk/drivers/pnp/isapnp/core.c @@ -1012,7 +1012,7 @@ static int __init isapnp_init(void) printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n"); return 0; } -#ifdef CONFIG_PPC +#ifdef CONFIG_PPC_MERGE if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP)) return -EINVAL; #endif diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index 2bfe13369df5..662dfcddedc6 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -519,7 +519,7 @@ static int __init pnpbios_init(void) { int ret; -#if defined(CONFIG_PPC) +#if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(PNPBIOS_BASE)) return -ENODEV; #endif @@ -577,7 +577,7 @@ static int __init pnpbios_thread_init(void) { struct task_struct *task; -#if defined(CONFIG_PPC) +#if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(PNPBIOS_BASE)) return 0; #endif diff --git a/trunk/drivers/pnp/quirks.c b/trunk/drivers/pnp/quirks.c index d15e2b77af88..0bdf9b8a5e58 100644 --- a/trunk/drivers/pnp/quirks.c +++ b/trunk/drivers/pnp/quirks.c @@ -245,7 +245,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) */ for_each_pci_dev(pdev) { for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - unsigned long type; + unsigned int type; type = pci_resource_flags(pdev, i) & (IORESOURCE_IO | IORESOURCE_MEM); diff --git a/trunk/drivers/pnp/resource.c b/trunk/drivers/pnp/resource.c index dbae23acdd5b..4cfe3a1efdfb 100644 --- a/trunk/drivers/pnp/resource.c +++ b/trunk/drivers/pnp/resource.c @@ -467,14 +467,14 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) #endif } -unsigned long pnp_resource_type(struct resource *res) +int pnp_resource_type(struct resource *res) { return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_IRQ | IORESOURCE_DMA); } struct resource *pnp_get_resource(struct pnp_dev *dev, - unsigned long type, unsigned int num) + unsigned int type, unsigned int num) { struct pnp_resource *pnp_res; struct resource *res; diff --git a/trunk/drivers/power/olpc_battery.c b/trunk/drivers/power/olpc_battery.c index 5fbca2681baa..32570af3c5c9 100644 --- a/trunk/drivers/power/olpc_battery.c +++ b/trunk/drivers/power/olpc_battery.c @@ -205,9 +205,9 @@ static int olpc_bat_get_property(struct power_supply *psy, union power_supply_propval *val) { int ret = 0; - __be16 ec_word; + int16_t ec_word; uint8_t ec_byte; - __be64 ser_buf; + uint64_t ser_buf; ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1); if (ret) @@ -257,14 +257,16 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32; + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 9760L / 32; break; case POWER_SUPPLY_PROP_CURRENT_AVG: ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120; + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 15625L / 120; break; case POWER_SUPPLY_PROP_CAPACITY: ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); @@ -276,22 +278,24 @@ static int olpc_bat_get_property(struct power_supply *psy, ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; - - val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 100 / 256; break; case POWER_SUPPLY_PROP_TEMP_AMBIENT: ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 100 / 256; break; case POWER_SUPPLY_PROP_CHARGE_COUNTER: ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15; + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 6250 / 15; break; case POWER_SUPPLY_PROP_SERIAL_NUMBER: ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8); diff --git a/trunk/drivers/power/power_supply_core.c b/trunk/drivers/power/power_supply_core.c index 3007695f90c8..cb1ccb472921 100644 --- a/trunk/drivers/power/power_supply_core.c +++ b/trunk/drivers/power/power_supply_core.c @@ -91,8 +91,8 @@ int power_supply_register(struct device *parent, struct power_supply *psy) { int rc = 0; - psy->dev = device_create(power_supply_class, parent, 0, psy, - "%s", psy->name); + psy->dev = device_create_drvdata(power_supply_class, parent, 0, + psy, "%s", psy->name); if (IS_ERR(psy->dev)) { rc = PTR_ERR(psy->dev); goto dev_create_failed; diff --git a/trunk/drivers/regulator/Kconfig b/trunk/drivers/regulator/Kconfig index 4dada6ee1119..a656128f1fdd 100644 --- a/trunk/drivers/regulator/Kconfig +++ b/trunk/drivers/regulator/Kconfig @@ -56,28 +56,4 @@ config REGULATOR_BQ24022 charging select between 100 mA and 500 mA charging current limit. -config REGULATOR_WM8350 - tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC" - depends on MFD_WM8350 - select REGULATOR - help - This driver provides support for the voltage and current regulators - of the WM8350 AudioPlus PMIC. - -config REGULATOR_WM8400 - tristate "Wolfson Microelectroncis WM8400 AudioPlus PMIC" - depends on MFD_WM8400 - select REGULATOR - help - This driver provides support for the voltage regulators of the - WM8400 AudioPlus PMIC. - -config REGULATOR_DA903X - tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC" - depends on PMIC_DA903X - select REGULATOR - help - Say y here to support the BUCKs and LDOs regulators found on - Dialog Semiconductor DA9030/DA9034 PMIC. - endmenu diff --git a/trunk/drivers/regulator/Makefile b/trunk/drivers/regulator/Makefile index 254d40c02ee8..ac2c64efe65c 100644 --- a/trunk/drivers/regulator/Makefile +++ b/trunk/drivers/regulator/Makefile @@ -8,8 +8,5 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o -obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o -obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o -obj-$(CONFIG_REGULATOR_DA903X) += da903x.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/trunk/drivers/regulator/bq24022.c b/trunk/drivers/regulator/bq24022.c index 366565aba865..263699d6152d 100644 --- a/trunk/drivers/regulator/bq24022.c +++ b/trunk/drivers/regulator/bq24022.c @@ -18,13 +18,13 @@ #include #include - static int bq24022_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct platform_device *pdev = rdev_get_drvdata(rdev); + struct bq24022_mach_info *pdata = pdev->dev.platform_data; - dev_dbg(rdev_get_dev(rdev), "setting current limit to %s mA\n", + dev_dbg(&pdev->dev, "setting current limit to %s mA\n", max_uA >= 500000 ? "500" : "100"); /* REVISIT: maybe return error if min_uA != 0 ? */ @@ -34,16 +34,18 @@ static int bq24022_set_current_limit(struct regulator_dev *rdev, static int bq24022_get_current_limit(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct platform_device *pdev = rdev_get_drvdata(rdev); + struct bq24022_mach_info *pdata = pdev->dev.platform_data; return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000; } static int bq24022_enable(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct platform_device *pdev = rdev_get_drvdata(rdev); + struct bq24022_mach_info *pdata = pdev->dev.platform_data; - dev_dbg(rdev_get_dev(rdev), "enabling charger\n"); + dev_dbg(&pdev->dev, "enabling charger\n"); gpio_set_value(pdata->gpio_nce, 0); return 0; @@ -51,9 +53,10 @@ static int bq24022_enable(struct regulator_dev *rdev) static int bq24022_disable(struct regulator_dev *rdev) { - struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev); + struct platform_device *pdev = rdev_get_drvdata(rdev); + struct bq24022_mach_info *pdata = pdev->dev.platform_data; - dev_dbg(rdev_get_dev(rdev), "disabling charger\n"); + dev_dbg(&pdev->dev, "disabling charger\n"); gpio_set_value(pdata->gpio_nce, 1); return 0; @@ -105,7 +108,7 @@ static int __init bq24022_probe(struct platform_device *pdev) ret = gpio_direction_output(pdata->gpio_iset2, 0); ret = gpio_direction_output(pdata->gpio_nce, 1); - bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata); + bq24022 = regulator_register(&bq24022_desc, pdev); if (IS_ERR(bq24022)) { dev_dbg(&pdev->dev, "couldn't register regulator\n"); ret = PTR_ERR(bq24022); diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index 02a774424e8d..9c7986261568 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -2,9 +2,8 @@ * core.c -- Voltage/Current Regulator framework. * * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * Copyright 2008 SlimLogic Ltd. * - * Author: Liam Girdwood + * Author: Liam Girdwood * * 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 @@ -65,9 +64,14 @@ struct regulator_map { struct list_head list; struct device *dev; const char *supply; - struct regulator_dev *regulator; + const char *regulator; }; +static inline struct regulator_dev *to_rdev(struct device *d) +{ + return container_of(d, struct regulator_dev, dev); +} + /* * struct regulator * @@ -223,7 +227,7 @@ static ssize_t device_requested_uA_show(struct device *dev, static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); ssize_t ret; mutex_lock(&rdev->mutex); @@ -236,31 +240,15 @@ static ssize_t regulator_uV_show(struct device *dev, static ssize_t regulator_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev)); } -static ssize_t regulator_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct regulator_dev *rdev = dev_get_drvdata(dev); - const char *name; - - if (rdev->constraints->name) - name = rdev->constraints->name; - else if (rdev->desc->name) - name = rdev->desc->name; - else - name = ""; - - return sprintf(buf, "%s\n", name); -} - static ssize_t regulator_opmode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); int mode = _regulator_get_mode(rdev); switch (mode) { @@ -279,7 +267,7 @@ static ssize_t regulator_opmode_show(struct device *dev, static ssize_t regulator_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); int state = _regulator_is_enabled(rdev); if (state > 0) @@ -293,7 +281,7 @@ static ssize_t regulator_state_show(struct device *dev, static ssize_t regulator_min_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); @@ -304,7 +292,7 @@ static ssize_t regulator_min_uA_show(struct device *dev, static ssize_t regulator_max_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); @@ -315,7 +303,7 @@ static ssize_t regulator_max_uA_show(struct device *dev, static ssize_t regulator_min_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); @@ -326,7 +314,7 @@ static ssize_t regulator_min_uV_show(struct device *dev, static ssize_t regulator_max_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); @@ -337,7 +325,7 @@ static ssize_t regulator_max_uV_show(struct device *dev, static ssize_t regulator_total_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); struct regulator *regulator; int uA = 0; @@ -351,14 +339,14 @@ static ssize_t regulator_total_uA_show(struct device *dev, static ssize_t regulator_num_users_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); return sprintf(buf, "%d\n", rdev->use_count); } static ssize_t regulator_type_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); switch (rdev->desc->type) { case REGULATOR_VOLTAGE: @@ -372,7 +360,7 @@ static ssize_t regulator_type_show(struct device *dev, static ssize_t regulator_suspend_mem_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -382,7 +370,7 @@ static ssize_t regulator_suspend_mem_uV_show(struct device *dev, static ssize_t regulator_suspend_disk_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -392,7 +380,7 @@ static ssize_t regulator_suspend_disk_uV_show(struct device *dev, static ssize_t regulator_suspend_standby_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -418,7 +406,7 @@ static ssize_t suspend_opmode_show(struct regulator_dev *rdev, static ssize_t regulator_suspend_mem_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -429,7 +417,7 @@ static ssize_t regulator_suspend_mem_mode_show(struct device *dev, static ssize_t regulator_suspend_disk_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -440,7 +428,7 @@ static ssize_t regulator_suspend_disk_mode_show(struct device *dev, static ssize_t regulator_suspend_standby_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -451,7 +439,7 @@ static ssize_t regulator_suspend_standby_mode_show(struct device *dev, static ssize_t regulator_suspend_mem_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -465,7 +453,7 @@ static ssize_t regulator_suspend_mem_state_show(struct device *dev, static ssize_t regulator_suspend_disk_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -479,7 +467,7 @@ static ssize_t regulator_suspend_disk_state_show(struct device *dev, static ssize_t regulator_suspend_standby_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); if (!rdev->constraints) return sprintf(buf, "not defined\n"); @@ -489,9 +477,7 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev, else return sprintf(buf, "disabled\n"); } - static struct device_attribute regulator_dev_attrs[] = { - __ATTR(name, 0444, regulator_name_show, NULL), __ATTR(microvolts, 0444, regulator_uV_show, NULL), __ATTR(microamps, 0444, regulator_uA_show, NULL), __ATTR(opmode, 0444, regulator_opmode_show, NULL), @@ -526,7 +512,7 @@ static struct device_attribute regulator_dev_attrs[] = { static void regulator_dev_release(struct device *dev) { - struct regulator_dev *rdev = dev_get_drvdata(dev); + struct regulator_dev *rdev = to_rdev(dev); kfree(rdev); } @@ -583,11 +569,8 @@ static int suspend_set_state(struct regulator_dev *rdev, /* enable & disable are mandatory for suspend control */ if (!rdev->desc->ops->set_suspend_enable || - !rdev->desc->ops->set_suspend_disable) { - printk(KERN_ERR "%s: no way to set suspend state\n", - __func__); + !rdev->desc->ops->set_suspend_disable) return -EINVAL; - } if (rstate->enabled) ret = rdev->desc->ops->set_suspend_enable(rdev); @@ -673,155 +656,6 @@ static void print_constraints(struct regulator_dev *rdev) printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf); } -/** - * set_machine_constraints - sets regulator constraints - * @regulator: regulator source - * - * Allows platform initialisation code to define and constrain - * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: - * Constraints *must* be set by platform code in order for some - * regulator operations to proceed i.e. set_voltage, set_current_limit, - * set_mode. - */ -static int set_machine_constraints(struct regulator_dev *rdev, - struct regulation_constraints *constraints) -{ - int ret = 0; - const char *name; - struct regulator_ops *ops = rdev->desc->ops; - - if (constraints->name) - name = constraints->name; - else if (rdev->desc->name) - name = rdev->desc->name; - else - name = "regulator"; - - rdev->constraints = constraints; - - /* do we need to apply the constraint voltage */ - if (rdev->constraints->apply_uV && - rdev->constraints->min_uV == rdev->constraints->max_uV && - ops->set_voltage) { - ret = ops->set_voltage(rdev, - rdev->constraints->min_uV, rdev->constraints->max_uV); - if (ret < 0) { - printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n", - __func__, - rdev->constraints->min_uV, name); - rdev->constraints = NULL; - goto out; - } - } - - /* are we enabled at boot time by firmware / bootloader */ - if (rdev->constraints->boot_on) - rdev->use_count = 1; - - /* do we need to setup our suspend state */ - if (constraints->initial_state) { - ret = suspend_prepare(rdev, constraints->initial_state); - if (ret < 0) { - printk(KERN_ERR "%s: failed to set suspend state for %s\n", - __func__, name); - rdev->constraints = NULL; - goto out; - } - } - - /* if always_on is set then turn the regulator on if it's not - * already on. */ - if (constraints->always_on && ops->enable && - ((ops->is_enabled && !ops->is_enabled(rdev)) || - (!ops->is_enabled && !constraints->boot_on))) { - ret = ops->enable(rdev); - if (ret < 0) { - printk(KERN_ERR "%s: failed to enable %s\n", - __func__, name); - rdev->constraints = NULL; - goto out; - } - } - - print_constraints(rdev); -out: - return ret; -} - -/** - * set_supply - set regulator supply regulator - * @regulator: regulator name - * @supply: supply regulator name - * - * Called by platform initialisation code to set the supply regulator for this - * regulator. This ensures that a regulators supply will also be enabled by the - * core if it's child is enabled. - */ -static int set_supply(struct regulator_dev *rdev, - struct regulator_dev *supply_rdev) -{ - int err; - - err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, - "supply"); - if (err) { - printk(KERN_ERR - "%s: could not add device link %s err %d\n", - __func__, supply_rdev->dev.kobj.name, err); - goto out; - } - rdev->supply = supply_rdev; - list_add(&rdev->slist, &supply_rdev->supply_list); -out: - return err; -} - -/** - * set_consumer_device_supply: Bind a regulator to a symbolic supply - * @regulator: regulator source - * @dev: device the supply applies to - * @supply: symbolic name for supply - * - * Allows platform initialisation code to map physical regulator - * sources to symbolic names for supplies for use by devices. Devices - * should use these symbolic names to request regulators, avoiding the - * need to provide board-specific regulator names as platform data. - */ -static int set_consumer_device_supply(struct regulator_dev *rdev, - struct device *consumer_dev, const char *supply) -{ - struct regulator_map *node; - - if (supply == NULL) - return -EINVAL; - - node = kmalloc(sizeof(struct regulator_map), GFP_KERNEL); - if (node == NULL) - return -ENOMEM; - - node->regulator = rdev; - node->dev = consumer_dev; - node->supply = supply; - - list_add(&node->list, ®ulator_map_list); - return 0; -} - -static void unset_consumer_device_supply(struct regulator_dev *rdev, - struct device *consumer_dev) -{ - struct regulator_map *node, *n; - - list_for_each_entry_safe(node, n, ®ulator_map_list, list) { - if (rdev == node->regulator && - consumer_dev == node->dev) { - list_del(&node->list); - kfree(node); - return; - } - } -} - #define REG_STR_SIZE 32 static struct regulator *create_regulator(struct regulator_dev *rdev, @@ -912,6 +746,7 @@ struct regulator *regulator_get(struct device *dev, const char *id) struct regulator_dev *rdev; struct regulator_map *map; struct regulator *regulator = ERR_PTR(-ENODEV); + const char *supply = id; if (id == NULL) { printk(KERN_ERR "regulator: get() with no identifier\n"); @@ -923,26 +758,28 @@ struct regulator *regulator_get(struct device *dev, const char *id) list_for_each_entry(map, ®ulator_map_list, list) { if (dev == map->dev && strcmp(map->supply, id) == 0) { - rdev = map->regulator; - goto found; + supply = map->regulator; + break; } } + + list_for_each_entry(rdev, ®ulator_list, list) { + if (strcmp(supply, rdev->desc->name) == 0 && + try_module_get(rdev->owner)) + goto found; + } printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n", id); mutex_unlock(®ulator_list_mutex); return regulator; found: - if (!try_module_get(rdev->owner)) - goto out; - regulator = create_regulator(rdev, dev, id); if (regulator == NULL) { regulator = ERR_PTR(-ENOMEM); module_put(rdev->owner); } -out: mutex_unlock(®ulator_list_mutex); return regulator; } @@ -1722,12 +1559,11 @@ EXPORT_SYMBOL_GPL(regulator_notifier_call_chain); * Returns 0 on success. */ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, - struct device *dev, void *driver_data) + void *reg_data) { static atomic_t regulator_no = ATOMIC_INIT(0); struct regulator_dev *rdev; - struct regulator_init_data *init_data = dev->platform_data; - int ret, i; + int ret; if (regulator_desc == NULL) return ERR_PTR(-EINVAL); @@ -1739,9 +1575,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, !regulator_desc->type == REGULATOR_CURRENT) return ERR_PTR(-EINVAL); - if (!init_data) - return ERR_PTR(-EINVAL); - rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); if (rdev == NULL) return ERR_PTR(-ENOMEM); @@ -1749,7 +1582,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, mutex_lock(®ulator_list_mutex); mutex_init(&rdev->mutex); - rdev->reg_data = driver_data; + rdev->reg_data = reg_data; rdev->owner = regulator_desc->owner; rdev->desc = regulator_desc; INIT_LIST_HEAD(&rdev->consumer_list); @@ -1758,68 +1591,20 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, INIT_LIST_HEAD(&rdev->slist); BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); - /* preform any regulator specific init */ - if (init_data->regulator_init) { - ret = init_data->regulator_init(rdev->reg_data); - if (ret < 0) { - kfree(rdev); - rdev = ERR_PTR(ret); - goto out; - } - } - - /* set regulator constraints */ - ret = set_machine_constraints(rdev, &init_data->constraints); - if (ret < 0) { - kfree(rdev); - rdev = ERR_PTR(ret); - goto out; - } - - /* register with sysfs */ rdev->dev.class = ®ulator_class; - rdev->dev.parent = dev; + device_initialize(&rdev->dev); snprintf(rdev->dev.bus_id, sizeof(rdev->dev.bus_id), - "regulator.%d", atomic_inc_return(®ulator_no) - 1); - ret = device_register(&rdev->dev); - if (ret != 0) { + "regulator_%ld_%s", + (unsigned long)atomic_inc_return(®ulator_no) - 1, + regulator_desc->name); + + ret = device_add(&rdev->dev); + if (ret == 0) + list_add(&rdev->list, ®ulator_list); + else { kfree(rdev); rdev = ERR_PTR(ret); - goto out; - } - - dev_set_drvdata(&rdev->dev, rdev); - - /* set supply regulator if it exists */ - if (init_data->supply_regulator_dev) { - ret = set_supply(rdev, - dev_get_drvdata(init_data->supply_regulator_dev)); - if (ret < 0) { - device_unregister(&rdev->dev); - kfree(rdev); - rdev = ERR_PTR(ret); - goto out; - } } - - /* add consumers devices */ - for (i = 0; i < init_data->num_consumer_supplies; i++) { - ret = set_consumer_device_supply(rdev, - init_data->consumer_supplies[i].dev, - init_data->consumer_supplies[i].supply); - if (ret < 0) { - for (--i; i >= 0; i--) - unset_consumer_device_supply(rdev, - init_data->consumer_supplies[i].dev); - device_unregister(&rdev->dev); - kfree(rdev); - rdev = ERR_PTR(ret); - goto out; - } - } - - list_add(&rdev->list, ®ulator_list); -out: mutex_unlock(®ulator_list_mutex); return rdev; } @@ -1845,6 +1630,187 @@ void regulator_unregister(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_unregister); +/** + * regulator_set_supply - set regulator supply regulator + * @regulator: regulator name + * @supply: supply regulator name + * + * Called by platform initialisation code to set the supply regulator for this + * regulator. This ensures that a regulators supply will also be enabled by the + * core if it's child is enabled. + */ +int regulator_set_supply(const char *regulator, const char *supply) +{ + struct regulator_dev *rdev, *supply_rdev; + int err; + + if (regulator == NULL || supply == NULL) + return -EINVAL; + + mutex_lock(®ulator_list_mutex); + + list_for_each_entry(rdev, ®ulator_list, list) { + if (!strcmp(rdev->desc->name, regulator)) + goto found_regulator; + } + mutex_unlock(®ulator_list_mutex); + return -ENODEV; + +found_regulator: + list_for_each_entry(supply_rdev, ®ulator_list, list) { + if (!strcmp(supply_rdev->desc->name, supply)) + goto found_supply; + } + mutex_unlock(®ulator_list_mutex); + return -ENODEV; + +found_supply: + err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, + "supply"); + if (err) { + printk(KERN_ERR + "%s: could not add device link %s err %d\n", + __func__, supply_rdev->dev.kobj.name, err); + goto out; + } + rdev->supply = supply_rdev; + list_add(&rdev->slist, &supply_rdev->supply_list); +out: + mutex_unlock(®ulator_list_mutex); + return err; +} +EXPORT_SYMBOL_GPL(regulator_set_supply); + +/** + * regulator_get_supply - get regulator supply regulator + * @regulator: regulator name + * + * Returns the supply supply regulator name or NULL if no supply regulator + * exists (i.e the regulator is supplied directly from USB, Line, Battery, etc) + */ +const char *regulator_get_supply(const char *regulator) +{ + struct regulator_dev *rdev; + + if (regulator == NULL) + return NULL; + + mutex_lock(®ulator_list_mutex); + list_for_each_entry(rdev, ®ulator_list, list) { + if (!strcmp(rdev->desc->name, regulator)) + goto found; + } + mutex_unlock(®ulator_list_mutex); + return NULL; + +found: + mutex_unlock(®ulator_list_mutex); + if (rdev->supply) + return rdev->supply->desc->name; + else + return NULL; +} +EXPORT_SYMBOL_GPL(regulator_get_supply); + +/** + * regulator_set_machine_constraints - sets regulator constraints + * @regulator: regulator source + * + * Allows platform initialisation code to define and constrain + * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: + * Constraints *must* be set by platform code in order for some + * regulator operations to proceed i.e. set_voltage, set_current_limit, + * set_mode. + */ +int regulator_set_machine_constraints(const char *regulator_name, + struct regulation_constraints *constraints) +{ + struct regulator_dev *rdev; + int ret = 0; + + if (regulator_name == NULL) + return -EINVAL; + + mutex_lock(®ulator_list_mutex); + + list_for_each_entry(rdev, ®ulator_list, list) { + if (!strcmp(regulator_name, rdev->desc->name)) + goto found; + } + ret = -ENODEV; + goto out; + +found: + mutex_lock(&rdev->mutex); + rdev->constraints = constraints; + + /* do we need to apply the constraint voltage */ + if (rdev->constraints->apply_uV && + rdev->constraints->min_uV == rdev->constraints->max_uV && + rdev->desc->ops->set_voltage) { + ret = rdev->desc->ops->set_voltage(rdev, + rdev->constraints->min_uV, rdev->constraints->max_uV); + if (ret < 0) { + printk(KERN_ERR "%s: failed to apply %duV" + " constraint\n", __func__, + rdev->constraints->min_uV); + rdev->constraints = NULL; + goto out; + } + } + + /* are we enabled at boot time by firmware / bootloader */ + if (rdev->constraints->boot_on) + rdev->use_count = 1; + + /* do we need to setup our suspend state */ + if (constraints->initial_state) + ret = suspend_prepare(rdev, constraints->initial_state); + + print_constraints(rdev); + mutex_unlock(&rdev->mutex); + +out: + mutex_unlock(®ulator_list_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(regulator_set_machine_constraints); + + +/** + * regulator_set_device_supply: Bind a regulator to a symbolic supply + * @regulator: regulator source + * @dev: device the supply applies to + * @supply: symbolic name for supply + * + * Allows platform initialisation code to map physical regulator + * sources to symbolic names for supplies for use by devices. Devices + * should use these symbolic names to request regulators, avoiding the + * need to provide board-specific regulator names as platform data. + */ +int regulator_set_device_supply(const char *regulator, struct device *dev, + const char *supply) +{ + struct regulator_map *node; + + if (regulator == NULL || supply == NULL) + return -EINVAL; + + node = kmalloc(sizeof(struct regulator_map), GFP_KERNEL); + if (node == NULL) + return -ENOMEM; + + node->regulator = regulator; + node->dev = dev; + node->supply = supply; + + mutex_lock(®ulator_list_mutex); + list_add(&node->list, ®ulator_map_list); + mutex_unlock(®ulator_list_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(regulator_set_device_supply); + /** * regulator_suspend_prepare: prepare regulators for system wide suspend * @state: system suspend state @@ -1927,18 +1893,6 @@ int rdev_get_id(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(rdev_get_id); -struct device *rdev_get_dev(struct regulator_dev *rdev) -{ - return &rdev->dev; -} -EXPORT_SYMBOL_GPL(rdev_get_dev); - -void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data) -{ - return reg_init_data->driver_data; -} -EXPORT_SYMBOL_GPL(regulator_get_init_drvdata); - static int __init regulator_init(void) { printk(KERN_INFO "regulator: core version %s\n", REGULATOR_VERSION); diff --git a/trunk/drivers/regulator/da903x.c b/trunk/drivers/regulator/da903x.c deleted file mode 100644 index 3688e339db87..000000000000 --- a/trunk/drivers/regulator/da903x.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Regulators driver for Dialog Semiconductor DA903x - * - * Copyright (C) 2006-2008 Marvell International Ltd. - * Copyright (C) 2008 Compulab Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* DA9030 Registers */ -#define DA9030_INVAL (-1) -#define DA9030_LDO1011 (0x10) -#define DA9030_LDO15 (0x11) -#define DA9030_LDO1416 (0x12) -#define DA9030_LDO1819 (0x13) -#define DA9030_LDO17 (0x14) -#define DA9030_BUCK2DVM1 (0x15) -#define DA9030_BUCK2DVM2 (0x16) -#define DA9030_RCTL11 (0x17) -#define DA9030_RCTL21 (0x18) -#define DA9030_LDO1 (0x90) -#define DA9030_LDO23 (0x91) -#define DA9030_LDO45 (0x92) -#define DA9030_LDO6 (0x93) -#define DA9030_LDO78 (0x94) -#define DA9030_LDO912 (0x95) -#define DA9030_BUCK (0x96) -#define DA9030_RCTL12 (0x97) -#define DA9030_RCTL22 (0x98) -#define DA9030_LDO_UNLOCK (0xa0) -#define DA9030_LDO_UNLOCK_MASK (0xe0) -#define DA9034_OVER1 (0x10) - -/* DA9034 Registers */ -#define DA9034_INVAL (-1) -#define DA9034_OVER2 (0x11) -#define DA9034_OVER3 (0x12) -#define DA9034_LDO643 (0x13) -#define DA9034_LDO987 (0x14) -#define DA9034_LDO1110 (0x15) -#define DA9034_LDO1312 (0x16) -#define DA9034_LDO1514 (0x17) -#define DA9034_VCC1 (0x20) -#define DA9034_ADTV1 (0x23) -#define DA9034_ADTV2 (0x24) -#define DA9034_AVRC (0x25) -#define DA9034_CDTV1 (0x26) -#define DA9034_CDTV2 (0x27) -#define DA9034_CVRC (0x28) -#define DA9034_SDTV1 (0x29) -#define DA9034_SDTV2 (0x2a) -#define DA9034_SVRC (0x2b) -#define DA9034_MDTV1 (0x32) -#define DA9034_MDTV2 (0x33) -#define DA9034_MVRC (0x34) - -struct da903x_regulator_info { - struct regulator_desc desc; - - int min_uV; - int max_uV; - int step_uV; - int vol_reg; - int vol_shift; - int vol_nbits; - int update_reg; - int update_bit; - int enable_reg; - int enable_bit; -}; - -static inline int check_range(struct da903x_regulator_info *info, - int min_uV, int max_uV) -{ - if (min_uV < info->min_uV || min_uV > info->max_uV) - return -EINVAL; - - return 0; -} - -/* DA9030/DA9034 common operations */ -static int da903x_set_ldo_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - - if (check_range(info, min_uV, max_uV)) { - pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV); - return -EINVAL; - } - - val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; - val <<= info->vol_shift; - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - - return da903x_update(da9034_dev, info->vol_reg, val, mask); -} - -static int da903x_get_voltage(struct regulator_dev *rdev) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - int ret; - - ret = da903x_read(da9034_dev, info->vol_reg, &val); - if (ret) - return ret; - - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - val = (val & mask) >> info->vol_shift; - - return info->min_uV + info->step_uV * val; -} - -static int da903x_enable(struct regulator_dev *rdev) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - - return da903x_set_bits(da9034_dev, info->enable_reg, - 1 << info->enable_bit); -} - -static int da903x_disable(struct regulator_dev *rdev) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - - return da903x_clr_bits(da9034_dev, info->enable_reg, - 1 << info->enable_bit); -} - -static int da903x_is_enabled(struct regulator_dev *rdev) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - uint8_t reg_val; - int ret; - - ret = da903x_read(da9034_dev, info->enable_reg, ®_val); - if (ret) - return ret; - - return reg_val & (1 << info->enable_bit); -} - -/* DA9030 specific operations */ -static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da903x_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - int ret; - - if (check_range(info, min_uV, max_uV)) { - pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV); - return -EINVAL; - } - - val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; - val <<= info->vol_shift; - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */ - mask |= DA9030_LDO_UNLOCK_MASK; - - /* write twice */ - ret = da903x_update(da903x_dev, info->vol_reg, val, mask); - if (ret) - return ret; - - return da903x_update(da903x_dev, info->vol_reg, val, mask); -} - -static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da903x_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - int thresh; - - if (check_range(info, min_uV, max_uV)) { - pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV); - return -EINVAL; - } - - thresh = (info->max_uV + info->min_uV) / 2; - if (min_uV < thresh) { - val = (thresh - min_uV + info->step_uV - 1) / info->step_uV; - val |= 0x4; - } else { - val = (min_uV - thresh + info->step_uV - 1) / info->step_uV; - } - - val <<= info->vol_shift; - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - - return da903x_update(da903x_dev, info->vol_reg, val, mask); -} - -static int da9030_get_ldo14_voltage(struct regulator_dev *rdev) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da903x_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - int ret; - - ret = da903x_read(da903x_dev, info->vol_reg, &val); - if (ret) - return ret; - - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - val = (val & mask) >> info->vol_shift; - - if (val & 0x4) - return info->min_uV + info->step_uV * (3 - (val & ~0x4)); - else - return (info->max_uV + info->min_uV) / 2 + - info->step_uV * (val & ~0x4); -} - -/* DA9034 specific operations */ -static int da9034_set_dvc_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - int ret; - - if (check_range(info, min_uV, max_uV)) { - pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV); - return -EINVAL; - } - - val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; - val <<= info->vol_shift; - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - - ret = da903x_update(da9034_dev, info->vol_reg, val, mask); - if (ret) - return ret; - - ret = da903x_set_bits(da9034_dev, info->update_reg, - 1 << info->update_bit); - return ret; -} - -static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - - if (check_range(info, min_uV, max_uV)) { - pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV); - return -EINVAL; - } - - val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; - val = (val > 7 || val < 20) ? 8 : val - 12; - val <<= info->vol_shift; - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - - return da903x_update(da9034_dev, info->vol_reg, val, mask); -} - -static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) -{ - struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - struct device *da9034_dev = rdev_get_dev(rdev)->parent; - uint8_t val, mask; - int ret; - - ret = da903x_read(da9034_dev, info->vol_reg, &val); - if (ret) - return ret; - - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - val = (val & mask) >> info->vol_shift; - - if (val >= 8) - return 2700000 + info->step_uV * (val - 8); - - return info->min_uV + info->step_uV * val; -} - -static struct regulator_ops da903x_regulator_ldo_ops = { - .set_voltage = da903x_set_ldo_voltage, - .get_voltage = da903x_get_voltage, - .enable = da903x_enable, - .disable = da903x_disable, - .is_enabled = da903x_is_enabled, -}; - -/* NOTE: this is dedicated for the insane DA9030 LDO14 */ -static struct regulator_ops da9030_regulator_ldo14_ops = { - .set_voltage = da9030_set_ldo14_voltage, - .get_voltage = da9030_get_ldo14_voltage, - .enable = da903x_enable, - .disable = da903x_disable, - .is_enabled = da903x_is_enabled, -}; - -/* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */ -static struct regulator_ops da9030_regulator_ldo1_15_ops = { - .set_voltage = da9030_set_ldo1_15_voltage, - .get_voltage = da903x_get_voltage, - .enable = da903x_enable, - .disable = da903x_disable, - .is_enabled = da903x_is_enabled, -}; - -static struct regulator_ops da9034_regulator_dvc_ops = { - .set_voltage = da9034_set_dvc_voltage, - .get_voltage = da903x_get_voltage, - .enable = da903x_enable, - .disable = da903x_disable, - .is_enabled = da903x_is_enabled, -}; - -/* NOTE: this is dedicated for the insane LDO12 */ -static struct regulator_ops da9034_regulator_ldo12_ops = { - .set_voltage = da9034_set_ldo12_voltage, - .get_voltage = da9034_get_ldo12_voltage, - .enable = da903x_enable, - .disable = da903x_disable, - .is_enabled = da903x_is_enabled, -}; - -#define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \ -{ \ - .desc = { \ - .name = "LDO" #_id, \ - .ops = &da903x_regulator_ldo_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = _pmic##_ID_LDO##_id, \ - .owner = THIS_MODULE, \ - }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .step_uV = (step) * 1000, \ - .vol_reg = _pmic##_##vreg, \ - .vol_shift = (shift), \ - .vol_nbits = (nbits), \ - .enable_reg = _pmic##_##ereg, \ - .enable_bit = (ebit), \ -} - -#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ -{ \ - .desc = { \ - .name = #_id, \ - .ops = &da9034_regulator_dvc_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = DA9034_ID_##_id, \ - .owner = THIS_MODULE, \ - }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .step_uV = (step) * 1000, \ - .vol_reg = DA9034_##vreg, \ - .vol_shift = (0), \ - .vol_nbits = (nbits), \ - .update_reg = DA9034_##ureg, \ - .update_bit = (ubit), \ - .enable_reg = DA9034_##ereg, \ - .enable_bit = (ebit), \ -} - -#define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ - DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit) - -#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ - DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit) - -static struct da903x_regulator_info da903x_regulator_info[] = { - /* DA9030 */ - DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1), - DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2), - DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3), - DA9030_LDO( 4, 1800, 3200, 100, LDO45, 0, 4, RCTL12, 4), - DA9030_LDO( 5, 1800, 3200, 100, LDO45, 4, 4, RCTL12, 5), - DA9030_LDO( 6, 1800, 3200, 100, LDO6, 0, 4, RCTL12, 6), - DA9030_LDO( 7, 1800, 3200, 100, LDO78, 0, 4, RCTL12, 7), - DA9030_LDO( 8, 1800, 3200, 100, LDO78, 4, 4, RCTL22, 0), - DA9030_LDO( 9, 1800, 3200, 100, LDO912, 0, 4, RCTL22, 1), - DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2), - DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3), - DA9030_LDO(12, 1800, 3200, 100, LDO912, 4, 4, RCTL22, 4), - DA9030_LDO(14, 2760, 2940, 30, LDO1416, 0, 3, RCTL11, 4), - DA9030_LDO(15, 1100, 2650, 50, LDO15, 0, 5, RCTL11, 5), - DA9030_LDO(16, 1100, 2650, 50, LDO1416, 3, 5, RCTL11, 6), - DA9030_LDO(17, 1800, 3200, 100, LDO17, 0, 4, RCTL11, 7), - DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2), - DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1), - DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */ - - /* DA9034 */ - DA9034_DVC(BUCK1, 725, 1500, 25, ADTV1, 5, VCC1, 0, OVER1, 0), - DA9034_DVC(BUCK2, 725, 1500, 25, CDTV1, 5, VCC1, 2, OVER1, 1), - DA9034_DVC(LDO2, 725, 1500, 25, SDTV1, 5, VCC1, 4, OVER1, 2), - DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4), - - DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5), - DA9034_LDO( 4, 1800, 2900,1100, LDO643, 4, 1, OVER3, 6), - DA9034_LDO( 6, 2500, 2850, 50, LDO643, 5, 3, OVER2, 0), - DA9034_LDO( 7, 2700, 3050, 50, LDO987, 0, 3, OVER2, 1), - DA9034_LDO( 8, 2700, 2850, 50, LDO987, 3, 2, OVER2, 2), - DA9034_LDO( 9, 2700, 3050, 50, LDO987, 5, 3, OVER2, 3), - DA9034_LDO(10, 2700, 3050, 50, LDO1110, 0, 3, OVER2, 4), - DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5), - DA9034_LDO(12, 1700, 3050, 50, LDO1312, 0, 4, OVER3, 6), - DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7), - DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0), - DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1), - DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */ -}; - -static inline struct da903x_regulator_info *find_regulator_info(int id) -{ - struct da903x_regulator_info *ri; - int i; - - for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) { - ri = &da903x_regulator_info[i]; - if (ri->desc.id == id) - return ri; - } - return NULL; -} - -static int __devinit da903x_regulator_probe(struct platform_device *pdev) -{ - struct da903x_regulator_info *ri = NULL; - struct regulator_dev *rdev; - - ri = find_regulator_info(pdev->id); - if (ri == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); - return -EINVAL; - } - - /* Workaround for the weird LDO12 voltage setting */ - if (ri->desc.id == DA9034_ID_LDO12) - ri->desc.ops = &da9034_regulator_ldo12_ops; - - if (ri->desc.id == DA9030_ID_LDO14) - ri->desc.ops = &da9030_regulator_ldo14_ops; - - if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15) - ri->desc.ops = &da9030_regulator_ldo1_15_ops; - - rdev = regulator_register(&ri->desc, pdev->dev.parent, ri); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - ri->desc.name); - return PTR_ERR(rdev); - } - - platform_set_drvdata(pdev, rdev); - return 0; -} - -static int __devexit da903x_regulator_remove(struct platform_device *pdev) -{ - struct regulator_dev *rdev = platform_get_drvdata(pdev); - - regulator_unregister(rdev); - return 0; -} - -static struct platform_driver da903x_regulator_driver = { - .driver = { - .name = "da903x-regulator", - .owner = THIS_MODULE, - }, - .probe = da903x_regulator_probe, - .remove = da903x_regulator_remove, -}; - -static int __init da903x_regulator_init(void) -{ - return platform_driver_register(&da903x_regulator_driver); -} -module_init(da903x_regulator_init); - -static void __exit da903x_regulator_exit(void) -{ - platform_driver_unregister(&da903x_regulator_driver); -} -module_exit(da903x_regulator_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Eric Miao " - "Mike Rapoport "); -MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC"); -MODULE_ALIAS("platform:da903x-regulator"); diff --git a/trunk/drivers/regulator/wm8350-regulator.c b/trunk/drivers/regulator/wm8350-regulator.c deleted file mode 100644 index 1f44b17e23b1..000000000000 --- a/trunk/drivers/regulator/wm8350-regulator.c +++ /dev/null @@ -1,1431 +0,0 @@ -/* - * wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Microamps */ -static const int isink_cur[] = { - 4, - 5, - 6, - 7, - 8, - 10, - 11, - 14, - 16, - 19, - 23, - 27, - 32, - 39, - 46, - 54, - 65, - 77, - 92, - 109, - 130, - 154, - 183, - 218, - 259, - 308, - 367, - 436, - 518, - 616, - 733, - 872, - 1037, - 1233, - 1466, - 1744, - 2073, - 2466, - 2933, - 3487, - 4147, - 4932, - 5865, - 6975, - 8294, - 9864, - 11730, - 13949, - 16589, - 19728, - 23460, - 27899, - 33178, - 39455, - 46920, - 55798, - 66355, - 78910, - 93840, - 111596, - 132710, - 157820, - 187681, - 223191 -}; - -static int get_isink_val(int min_uA, int max_uA, u16 *setting) -{ - int i; - - for (i = ARRAY_SIZE(isink_cur) - 1; i >= 0; i--) { - if (min_uA <= isink_cur[i] && max_uA >= isink_cur[i]) { - *setting = i; - return 0; - } - } - return -EINVAL; -} - -static inline int wm8350_ldo_val_to_mvolts(unsigned int val) -{ - if (val < 16) - return (val * 50) + 900; - else - return ((val - 16) * 100) + 1800; - -} - -static inline unsigned int wm8350_ldo_mvolts_to_val(int mV) -{ - if (mV < 1800) - return (mV - 900) / 50; - else - return ((mV - 1800) / 100) + 16; -} - -static inline int wm8350_dcdc_val_to_mvolts(unsigned int val) -{ - return (val * 25) + 850; -} - -static inline unsigned int wm8350_dcdc_mvolts_to_val(int mV) -{ - return (mV - 850) / 25; -} - -static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA, - int max_uA) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - u16 val, setting; - int ret; - - ret = get_isink_val(min_uA, max_uA, &setting); - if (ret != 0) - return ret; - - switch (isink) { - case WM8350_ISINK_A: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - ~WM8350_CS1_ISEL_MASK; - wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_A, - val | setting); - break; - case WM8350_ISINK_B: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - ~WM8350_CS1_ISEL_MASK; - wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_B, - val | setting); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int wm8350_isink_get_current(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - u16 val; - - switch (isink) { - case WM8350_ISINK_A: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - WM8350_CS1_ISEL_MASK; - break; - case WM8350_ISINK_B: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - WM8350_CS1_ISEL_MASK; - break; - default: - return 0; - } - - return (isink_cur[val] + 50) / 100; -} - -/* turn on ISINK followed by DCDC */ -static int wm8350_isink_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - - switch (isink) { - case WM8350_ISINK_A: - switch (wm8350->pmic.isink_A_dcdc) { - case WM8350_DCDC_2: - case WM8350_DCDC_5: - wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7, - WM8350_CS1_ENA); - wm8350_set_bits(wm8350, WM8350_CSA_FLASH_CONTROL, - WM8350_CS1_DRIVE); - wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, - 1 << (wm8350->pmic.isink_A_dcdc - - WM8350_DCDC_1)); - break; - default: - return -EINVAL; - } - break; - case WM8350_ISINK_B: - switch (wm8350->pmic.isink_B_dcdc) { - case WM8350_DCDC_2: - case WM8350_DCDC_5: - wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7, - WM8350_CS2_ENA); - wm8350_set_bits(wm8350, WM8350_CSB_FLASH_CONTROL, - WM8350_CS2_DRIVE); - wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, - 1 << (wm8350->pmic.isink_B_dcdc - - WM8350_DCDC_1)); - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } - return 0; -} - -static int wm8350_isink_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - - switch (isink) { - case WM8350_ISINK_A: - switch (wm8350->pmic.isink_A_dcdc) { - case WM8350_DCDC_2: - case WM8350_DCDC_5: - wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, - 1 << (wm8350->pmic.isink_A_dcdc - - WM8350_DCDC_1)); - wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7, - WM8350_CS1_ENA); - break; - default: - return -EINVAL; - } - break; - case WM8350_ISINK_B: - switch (wm8350->pmic.isink_B_dcdc) { - case WM8350_DCDC_2: - case WM8350_DCDC_5: - wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, - 1 << (wm8350->pmic.isink_B_dcdc - - WM8350_DCDC_1)); - wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7, - WM8350_CS2_ENA); - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } - return 0; -} - -static int wm8350_isink_is_enabled(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - - switch (isink) { - case WM8350_ISINK_A: - return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - 0x8000; - case WM8350_ISINK_B: - return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - 0x8000; - } - return -EINVAL; -} - -int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode, - u16 trigger, u16 duration, u16 on_ramp, u16 off_ramp, - u16 drive) -{ - switch (isink) { - case WM8350_ISINK_A: - wm8350_reg_write(wm8350, WM8350_CSA_FLASH_CONTROL, - (mode ? WM8350_CS1_FLASH_MODE : 0) | - (trigger ? WM8350_CS1_TRIGSRC : 0) | - duration | on_ramp | off_ramp | drive); - break; - case WM8350_ISINK_B: - wm8350_reg_write(wm8350, WM8350_CSB_FLASH_CONTROL, - (mode ? WM8350_CS2_FLASH_MODE : 0) | - (trigger ? WM8350_CS2_TRIGSRC : 0) | - duration | on_ramp | off_ramp | drive); - break; - default: - return -EINVAL; - } - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_isink_set_flash); - -static int wm8350_dcdc_set_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, dcdc = rdev_get_id(rdev), mV, - min_mV = min_uV / 1000, max_mV = max_uV / 1000; - u16 val; - - if (min_mV < 850 || min_mV > 4025) - return -EINVAL; - if (max_mV < 850 || max_mV > 4025) - return -EINVAL; - - /* step size is 25mV */ - mV = (min_mV - 826) / 25; - if (wm8350_dcdc_val_to_mvolts(mV) > max_mV) - return -EINVAL; - BUG_ON(wm8350_dcdc_val_to_mvolts(mV) < min_mV); - - switch (dcdc) { - case WM8350_DCDC_1: - volt_reg = WM8350_DCDC1_CONTROL; - break; - case WM8350_DCDC_3: - volt_reg = WM8350_DCDC3_CONTROL; - break; - case WM8350_DCDC_4: - volt_reg = WM8350_DCDC4_CONTROL; - break; - case WM8350_DCDC_6: - volt_reg = WM8350_DCDC6_CONTROL; - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - /* all DCDCs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, val | mV); - return 0; -} - -static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, dcdc = rdev_get_id(rdev); - u16 val; - - switch (dcdc) { - case WM8350_DCDC_1: - volt_reg = WM8350_DCDC1_CONTROL; - break; - case WM8350_DCDC_3: - volt_reg = WM8350_DCDC3_CONTROL; - break; - case WM8350_DCDC_4: - volt_reg = WM8350_DCDC4_CONTROL; - break; - case WM8350_DCDC_6: - volt_reg = WM8350_DCDC6_CONTROL; - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - /* all DCDCs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & WM8350_DC1_VSEL_MASK; - return wm8350_dcdc_val_to_mvolts(val) * 1000; -} - -static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, mV = uV / 1000, dcdc = rdev_get_id(rdev); - u16 val; - - dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, mV); - - if (mV && (mV < 850 || mV > 4025)) { - dev_err(wm8350->dev, - "DCDC%d suspend voltage %d mV out of range\n", - dcdc, mV); - return -EINVAL; - } - if (mV == 0) - mV = 850; - - switch (dcdc) { - case WM8350_DCDC_1: - volt_reg = WM8350_DCDC1_LOW_POWER; - break; - case WM8350_DCDC_3: - volt_reg = WM8350_DCDC3_LOW_POWER; - break; - case WM8350_DCDC_4: - volt_reg = WM8350_DCDC4_LOW_POWER; - break; - case WM8350_DCDC_6: - volt_reg = WM8350_DCDC6_LOW_POWER; - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - /* all DCDCs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, - val | wm8350_dcdc_mvolts_to_val(mV)); - return 0; -} - -static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 val; - - switch (dcdc) { - case WM8350_DCDC_1: - val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER) - & ~WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER, - wm8350->pmic.dcdc1_hib_mode); - break; - case WM8350_DCDC_3: - val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER) - & ~WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER, - wm8350->pmic.dcdc3_hib_mode); - break; - case WM8350_DCDC_4: - val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER) - & ~WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER, - wm8350->pmic.dcdc4_hib_mode); - break; - case WM8350_DCDC_6: - val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER) - & ~WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER, - wm8350->pmic.dcdc6_hib_mode); - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - return 0; -} - -static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 val; - - switch (dcdc) { - case WM8350_DCDC_1: - val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER); - wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); - break; - case WM8350_DCDC_3: - val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER); - wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); - break; - case WM8350_DCDC_4: - val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER); - wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); - break; - case WM8350_DCDC_6: - val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER); - wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - return 0; -} - -static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 val; - - switch (dcdc) { - case WM8350_DCDC_2: - val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) - & ~WM8350_DC2_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - WM8350_DC2_HIB_MODE_ACTIVE); - break; - case WM8350_DCDC_5: - val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~WM8350_DC2_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - WM8350_DC5_HIB_MODE_ACTIVE); - break; - default: - return -EINVAL; - } - return 0; -} - -static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 val; - - switch (dcdc) { - case WM8350_DCDC_2: - val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) - & ~WM8350_DC2_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - WM8350_DC2_HIB_MODE_DISABLE); - break; - case WM8350_DCDC_5: - val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~WM8350_DC2_HIB_MODE_MASK; - wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - WM8350_DC2_HIB_MODE_DISABLE); - break; - default: - return -EINVAL; - } - return 0; -} - -static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev, - unsigned int mode) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 *hib_mode; - - switch (dcdc) { - case WM8350_DCDC_1: - hib_mode = &wm8350->pmic.dcdc1_hib_mode; - break; - case WM8350_DCDC_3: - hib_mode = &wm8350->pmic.dcdc3_hib_mode; - break; - case WM8350_DCDC_4: - hib_mode = &wm8350->pmic.dcdc4_hib_mode; - break; - case WM8350_DCDC_6: - hib_mode = &wm8350->pmic.dcdc6_hib_mode; - break; - case WM8350_DCDC_2: - case WM8350_DCDC_5: - default: - return -EINVAL; - } - - switch (mode) { - case REGULATOR_MODE_NORMAL: - *hib_mode = WM8350_DCDC_HIB_MODE_IMAGE; - break; - case REGULATOR_MODE_IDLE: - *hib_mode = WM8350_DCDC_HIB_MODE_STANDBY; - break; - case REGULATOR_MODE_STANDBY: - *hib_mode = WM8350_DCDC_HIB_MODE_LDO_IM; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, mV = uV / 1000, ldo = rdev_get_id(rdev); - u16 val; - - dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, mV); - - if (mV < 900 || mV > 3300) { - dev_err(wm8350->dev, "LDO%d voltage %d mV out of range\n", - ldo, mV); - return -EINVAL; - } - - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_LOW_POWER; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_LOW_POWER; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_LOW_POWER; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_LOW_POWER; - break; - default: - return -EINVAL; - } - - /* all LDOs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, - val | wm8350_ldo_mvolts_to_val(mV)); - return 0; -} - -static int wm8350_ldo_set_suspend_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, ldo = rdev_get_id(rdev); - u16 val; - - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_LOW_POWER; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_LOW_POWER; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_LOW_POWER; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_LOW_POWER; - break; - default: - return -EINVAL; - } - - /* all LDOs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK; - wm8350_reg_write(wm8350, volt_reg, val); - return 0; -} - -static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, ldo = rdev_get_id(rdev); - u16 val; - - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_LOW_POWER; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_LOW_POWER; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_LOW_POWER; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_LOW_POWER; - break; - default: - return -EINVAL; - } - - /* all LDOs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK; - wm8350_reg_write(wm8350, volt_reg, WM8350_LDO1_HIB_MODE_DIS); - return 0; -} - -static int wm8350_ldo_set_voltage(struct regulator_dev *rdev, int min_uV, - int max_uV) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, ldo = rdev_get_id(rdev), mV, min_mV = min_uV / 1000, - max_mV = max_uV / 1000; - u16 val; - - if (min_mV < 900 || min_mV > 3300) - return -EINVAL; - if (max_mV < 900 || max_mV > 3300) - return -EINVAL; - - if (min_mV < 1800) { - /* step size is 50mV < 1800mV */ - mV = (min_mV - 851) / 50; - if (wm8350_ldo_val_to_mvolts(mV) > max_mV) - return -EINVAL; - BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); - } else { - /* step size is 100mV > 1800mV */ - mV = ((min_mV - 1701) / 100) + 16; - if (wm8350_ldo_val_to_mvolts(mV) > max_mV) - return -EINVAL; - BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV); - } - - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_CONTROL; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_CONTROL; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_CONTROL; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_CONTROL; - break; - default: - return -EINVAL; - } - - /* all LDOs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK; - wm8350_reg_write(wm8350, volt_reg, val | mV); - return 0; -} - -static int wm8350_ldo_get_voltage(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int volt_reg, ldo = rdev_get_id(rdev); - u16 val; - - switch (ldo) { - case WM8350_LDO_1: - volt_reg = WM8350_LDO1_CONTROL; - break; - case WM8350_LDO_2: - volt_reg = WM8350_LDO2_CONTROL; - break; - case WM8350_LDO_3: - volt_reg = WM8350_LDO3_CONTROL; - break; - case WM8350_LDO_4: - volt_reg = WM8350_LDO4_CONTROL; - break; - default: - return -EINVAL; - } - - /* all LDOs have same mV bits */ - val = wm8350_reg_read(wm8350, volt_reg) & WM8350_LDO1_VSEL_MASK; - return wm8350_ldo_val_to_mvolts(val) * 1000; -} - -int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start, - u16 stop, u16 fault) -{ - int slot_reg; - u16 val; - - dev_dbg(wm8350->dev, "%s %d start %d stop %d\n", - __func__, dcdc, start, stop); - - /* slot valid ? */ - if (start > 15 || stop > 15) - return -EINVAL; - - switch (dcdc) { - case WM8350_DCDC_1: - slot_reg = WM8350_DCDC1_TIMEOUTS; - break; - case WM8350_DCDC_2: - slot_reg = WM8350_DCDC2_TIMEOUTS; - break; - case WM8350_DCDC_3: - slot_reg = WM8350_DCDC3_TIMEOUTS; - break; - case WM8350_DCDC_4: - slot_reg = WM8350_DCDC4_TIMEOUTS; - break; - case WM8350_DCDC_5: - slot_reg = WM8350_DCDC5_TIMEOUTS; - break; - case WM8350_DCDC_6: - slot_reg = WM8350_DCDC6_TIMEOUTS; - break; - default: - return -EINVAL; - } - - val = wm8350_reg_read(wm8350, slot_reg) & - ~(WM8350_DC1_ENSLOT_MASK | WM8350_DC1_SDSLOT_MASK | - WM8350_DC1_ERRACT_MASK); - wm8350_reg_write(wm8350, slot_reg, - val | (start << WM8350_DC1_ENSLOT_SHIFT) | - (stop << WM8350_DC1_SDSLOT_SHIFT) | - (fault << WM8350_DC1_ERRACT_SHIFT)); - - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_dcdc_set_slot); - -int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop) -{ - int slot_reg; - u16 val; - - dev_dbg(wm8350->dev, "%s %d start %d stop %d\n", - __func__, ldo, start, stop); - - /* slot valid ? */ - if (start > 15 || stop > 15) - return -EINVAL; - - switch (ldo) { - case WM8350_LDO_1: - slot_reg = WM8350_LDO1_TIMEOUTS; - break; - case WM8350_LDO_2: - slot_reg = WM8350_LDO2_TIMEOUTS; - break; - case WM8350_LDO_3: - slot_reg = WM8350_LDO3_TIMEOUTS; - break; - case WM8350_LDO_4: - slot_reg = WM8350_LDO4_TIMEOUTS; - break; - default: - return -EINVAL; - } - - val = wm8350_reg_read(wm8350, slot_reg) & ~WM8350_LDO1_SDSLOT_MASK; - wm8350_reg_write(wm8350, slot_reg, val | ((start << 10) | (stop << 6))); - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_ldo_set_slot); - -int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode, - u16 ilim, u16 ramp, u16 feedback) -{ - u16 val; - - dev_dbg(wm8350->dev, "%s %d mode: %s %s\n", __func__, dcdc, - mode ? "normal" : "boost", ilim ? "low" : "normal"); - - switch (dcdc) { - case WM8350_DCDC_2: - val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) - & ~(WM8350_DC2_MODE_MASK | WM8350_DC2_ILIM_MASK | - WM8350_DC2_RMP_MASK | WM8350_DC2_FBSRC_MASK); - wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - (mode << WM8350_DC2_MODE_SHIFT) | - (ilim << WM8350_DC2_ILIM_SHIFT) | - (ramp << WM8350_DC2_RMP_SHIFT) | - (feedback << WM8350_DC2_FBSRC_SHIFT)); - break; - case WM8350_DCDC_5: - val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~(WM8350_DC5_MODE_MASK | WM8350_DC5_ILIM_MASK | - WM8350_DC5_RMP_MASK | WM8350_DC5_FBSRC_MASK); - wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - (mode << WM8350_DC5_MODE_SHIFT) | - (ilim << WM8350_DC5_ILIM_SHIFT) | - (ramp << WM8350_DC5_RMP_SHIFT) | - (feedback << WM8350_DC5_FBSRC_SHIFT)); - break; - default: - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode); - -static int wm8350_dcdc_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 shift; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - shift = dcdc - WM8350_DCDC_1; - wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - return 0; -} - -static int wm8350_dcdc_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 shift; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - shift = dcdc - WM8350_DCDC_1; - wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - - return 0; -} - -static int wm8350_ldo_enable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int ldo = rdev_get_id(rdev); - u16 shift; - - if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) - return -EINVAL; - - shift = (ldo - WM8350_LDO_1) + 8; - wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - return 0; -} - -static int wm8350_ldo_disable(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int ldo = rdev_get_id(rdev); - u16 shift; - - if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) - return -EINVAL; - - shift = (ldo - WM8350_LDO_1) + 8; - wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED, 1 << shift); - return 0; -} - -static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable) -{ - int reg = 0, ret; - - switch (dcdc) { - case WM8350_DCDC_1: - reg = WM8350_DCDC1_FORCE_PWM; - break; - case WM8350_DCDC_3: - reg = WM8350_DCDC3_FORCE_PWM; - break; - case WM8350_DCDC_4: - reg = WM8350_DCDC4_FORCE_PWM; - break; - case WM8350_DCDC_6: - reg = WM8350_DCDC6_FORCE_PWM; - break; - default: - return -EINVAL; - } - - if (enable) - ret = wm8350_set_bits(wm8350, reg, - WM8350_DCDC1_FORCE_PWM_ENA); - else - ret = wm8350_clear_bits(wm8350, reg, - WM8350_DCDC1_FORCE_PWM_ENA); - return ret; -} - -static int wm8350_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 val; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5) - return -EINVAL; - - val = 1 << (dcdc - WM8350_DCDC_1); - - switch (mode) { - case REGULATOR_MODE_FAST: - /* force continuous mode */ - wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val); - wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val); - force_continuous_enable(wm8350, dcdc, 1); - break; - case REGULATOR_MODE_NORMAL: - /* active / pulse skipping */ - wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val); - wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val); - force_continuous_enable(wm8350, dcdc, 0); - break; - case REGULATOR_MODE_IDLE: - /* standby mode */ - force_continuous_enable(wm8350, dcdc, 0); - wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val); - wm8350_clear_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val); - break; - case REGULATOR_MODE_STANDBY: - /* LDO mode */ - force_continuous_enable(wm8350, dcdc, 0); - wm8350_set_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val); - break; - } - - return 0; -} - -static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev); - u16 mask, sleep, active, force; - int mode = REGULATOR_MODE_NORMAL; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5) - return -EINVAL; - - mask = 1 << (dcdc - WM8350_DCDC_1); - active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask; - sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask; - force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM) - & WM8350_DCDC1_FORCE_PWM_ENA; - dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x", - mask, active, sleep, force); - - if (active && !sleep) { - if (force) - mode = REGULATOR_MODE_FAST; - else - mode = REGULATOR_MODE_NORMAL; - } else if (!active && !sleep) - mode = REGULATOR_MODE_IDLE; - else if (!sleep) - mode = REGULATOR_MODE_STANDBY; - - return mode; -} - -static unsigned int wm8350_ldo_get_mode(struct regulator_dev *rdev) -{ - return REGULATOR_MODE_NORMAL; -} - -struct wm8350_dcdc_efficiency { - int uA_load_min; - int uA_load_max; - unsigned int mode; -}; - -static const struct wm8350_dcdc_efficiency dcdc1_6_efficiency[] = { - {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */ - {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */ - {100000, 1000000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */ - {-1, -1, REGULATOR_MODE_NORMAL}, -}; - -static const struct wm8350_dcdc_efficiency dcdc3_4_efficiency[] = { - {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */ - {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */ - {100000, 800000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */ - {-1, -1, REGULATOR_MODE_NORMAL}, -}; - -static unsigned int get_mode(int uA, const struct wm8350_dcdc_efficiency *eff) -{ - int i = 0; - - while (eff[i].uA_load_min != -1) { - if (uA >= eff[i].uA_load_min && uA <= eff[i].uA_load_max) - return eff[i].mode; - } - return REGULATOR_MODE_NORMAL; -} - -/* Query the regulator for it's most efficient mode @ uV,uA - * WM8350 regulator efficiency is pretty similar over - * different input and output uV. - */ -static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev, - int input_uV, int output_uV, - int output_uA) -{ - int dcdc = rdev_get_id(rdev), mode; - - switch (dcdc) { - case WM8350_DCDC_1: - case WM8350_DCDC_6: - mode = get_mode(output_uA, dcdc1_6_efficiency); - break; - case WM8350_DCDC_3: - case WM8350_DCDC_4: - mode = get_mode(output_uA, dcdc3_4_efficiency); - break; - default: - mode = REGULATOR_MODE_NORMAL; - break; - } - return mode; -} - -static int wm8350_dcdc_is_enabled(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int dcdc = rdev_get_id(rdev), shift; - - if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) - return -EINVAL; - - shift = dcdc - WM8350_DCDC_1; - return wm8350_reg_read(wm8350, WM8350_DCDC_LDO_REQUESTED) - & (1 << shift); -} - -static int wm8350_ldo_is_enabled(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int ldo = rdev_get_id(rdev), shift; - - if (ldo < WM8350_LDO_1 || ldo > WM8350_LDO_4) - return -EINVAL; - - shift = (ldo - WM8350_LDO_1) + 8; - return wm8350_reg_read(wm8350, WM8350_DCDC_LDO_REQUESTED) - & (1 << shift); -} - -static struct regulator_ops wm8350_dcdc_ops = { - .set_voltage = wm8350_dcdc_set_voltage, - .get_voltage = wm8350_dcdc_get_voltage, - .enable = wm8350_dcdc_enable, - .disable = wm8350_dcdc_disable, - .get_mode = wm8350_dcdc_get_mode, - .set_mode = wm8350_dcdc_set_mode, - .get_optimum_mode = wm8350_dcdc_get_optimum_mode, - .is_enabled = wm8350_dcdc_is_enabled, - .set_suspend_voltage = wm8350_dcdc_set_suspend_voltage, - .set_suspend_enable = wm8350_dcdc_set_suspend_enable, - .set_suspend_disable = wm8350_dcdc_set_suspend_disable, - .set_suspend_mode = wm8350_dcdc_set_suspend_mode, -}; - -static struct regulator_ops wm8350_dcdc2_5_ops = { - .enable = wm8350_dcdc_enable, - .disable = wm8350_dcdc_disable, - .is_enabled = wm8350_dcdc_is_enabled, - .set_suspend_enable = wm8350_dcdc25_set_suspend_enable, - .set_suspend_disable = wm8350_dcdc25_set_suspend_disable, -}; - -static struct regulator_ops wm8350_ldo_ops = { - .set_voltage = wm8350_ldo_set_voltage, - .get_voltage = wm8350_ldo_get_voltage, - .enable = wm8350_ldo_enable, - .disable = wm8350_ldo_disable, - .is_enabled = wm8350_ldo_is_enabled, - .get_mode = wm8350_ldo_get_mode, - .set_suspend_voltage = wm8350_ldo_set_suspend_voltage, - .set_suspend_enable = wm8350_ldo_set_suspend_enable, - .set_suspend_disable = wm8350_ldo_set_suspend_disable, -}; - -static struct regulator_ops wm8350_isink_ops = { - .set_current_limit = wm8350_isink_set_current, - .get_current_limit = wm8350_isink_get_current, - .enable = wm8350_isink_enable, - .disable = wm8350_isink_disable, - .is_enabled = wm8350_isink_is_enabled, -}; - -static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { - { - .name = "DCDC1", - .id = WM8350_DCDC_1, - .ops = &wm8350_dcdc_ops, - .irq = WM8350_IRQ_UV_DC1, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC2", - .id = WM8350_DCDC_2, - .ops = &wm8350_dcdc2_5_ops, - .irq = WM8350_IRQ_UV_DC2, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC3", - .id = WM8350_DCDC_3, - .ops = &wm8350_dcdc_ops, - .irq = WM8350_IRQ_UV_DC3, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC4", - .id = WM8350_DCDC_4, - .ops = &wm8350_dcdc_ops, - .irq = WM8350_IRQ_UV_DC4, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC5", - .id = WM8350_DCDC_5, - .ops = &wm8350_dcdc2_5_ops, - .irq = WM8350_IRQ_UV_DC5, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC6", - .id = WM8350_DCDC_6, - .ops = &wm8350_dcdc_ops, - .irq = WM8350_IRQ_UV_DC6, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO1", - .id = WM8350_LDO_1, - .ops = &wm8350_ldo_ops, - .irq = WM8350_IRQ_UV_LDO1, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO2", - .id = WM8350_LDO_2, - .ops = &wm8350_ldo_ops, - .irq = WM8350_IRQ_UV_LDO2, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO3", - .id = WM8350_LDO_3, - .ops = &wm8350_ldo_ops, - .irq = WM8350_IRQ_UV_LDO3, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO4", - .id = WM8350_LDO_4, - .ops = &wm8350_ldo_ops, - .irq = WM8350_IRQ_UV_LDO4, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "ISINKA", - .id = WM8350_ISINK_A, - .ops = &wm8350_isink_ops, - .irq = WM8350_IRQ_CS1, - .type = REGULATOR_CURRENT, - .owner = THIS_MODULE, - }, - { - .name = "ISINKB", - .id = WM8350_ISINK_B, - .ops = &wm8350_isink_ops, - .irq = WM8350_IRQ_CS2, - .type = REGULATOR_CURRENT, - .owner = THIS_MODULE, - }, -}; - -static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data) -{ - struct regulator_dev *rdev = (struct regulator_dev *)data; - - if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2) - regulator_notifier_call_chain(rdev, - REGULATOR_EVENT_REGULATION_OUT, - wm8350); - else - regulator_notifier_call_chain(rdev, - REGULATOR_EVENT_UNDER_VOLTAGE, - wm8350); -} - -static int wm8350_regulator_probe(struct platform_device *pdev) -{ - struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); - struct regulator_dev *rdev; - int ret; - u16 val; - - if (pdev->id < WM8350_DCDC_1 || pdev->id > WM8350_ISINK_B) - return -ENODEV; - - /* do any regulatior specific init */ - switch (pdev->id) { - case WM8350_DCDC_1: - val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER); - wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - break; - case WM8350_DCDC_3: - val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER); - wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - break; - case WM8350_DCDC_4: - val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER); - wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - break; - case WM8350_DCDC_6: - val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER); - wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; - break; - } - - - /* register regulator */ - rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev, - dev_get_drvdata(&pdev->dev)); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register %s\n", - wm8350_reg[pdev->id].name); - return PTR_ERR(rdev); - } - - /* register regulator IRQ */ - ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq, - pmic_uv_handler, rdev); - if (ret < 0) { - regulator_unregister(rdev); - dev_err(&pdev->dev, "failed to register regulator %s IRQ\n", - wm8350_reg[pdev->id].name); - return ret; - } - - wm8350_unmask_irq(wm8350, wm8350_reg[pdev->id].irq); - - return 0; -} - -static int wm8350_regulator_remove(struct platform_device *pdev) -{ - struct regulator_dev *rdev = platform_get_drvdata(pdev); - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - - wm8350_mask_irq(wm8350, wm8350_reg[pdev->id].irq); - wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq); - - regulator_unregister(rdev); - - return 0; -} - -int wm8350_register_regulator(struct wm8350 *wm8350, int reg, - struct regulator_init_data *initdata) -{ - struct platform_device *pdev; - int ret; - - if (wm8350->pmic.pdev[reg]) - return -EBUSY; - - pdev = platform_device_alloc("wm8350-regulator", reg); - if (!pdev) - return -ENOMEM; - - wm8350->pmic.pdev[reg] = pdev; - - initdata->driver_data = wm8350; - - pdev->dev.platform_data = initdata; - pdev->dev.parent = wm8350->dev; - platform_set_drvdata(pdev, wm8350); - - ret = platform_device_add(pdev); - - if (ret != 0) { - dev_err(wm8350->dev, "Failed to register regulator %d: %d\n", - reg, ret); - platform_device_del(pdev); - wm8350->pmic.pdev[reg] = NULL; - } - - return ret; -} -EXPORT_SYMBOL_GPL(wm8350_register_regulator); - -static struct platform_driver wm8350_regulator_driver = { - .probe = wm8350_regulator_probe, - .remove = wm8350_regulator_remove, - .driver = { - .name = "wm8350-regulator", - }, -}; - -static int __init wm8350_regulator_init(void) -{ - return platform_driver_register(&wm8350_regulator_driver); -} -subsys_initcall(wm8350_regulator_init); - -static void __exit wm8350_regulator_exit(void) -{ - platform_driver_unregister(&wm8350_regulator_driver); -} -module_exit(wm8350_regulator_exit); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood"); -MODULE_DESCRIPTION("WM8350 voltage and current regulator driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/regulator/wm8400-regulator.c b/trunk/drivers/regulator/wm8400-regulator.c deleted file mode 100644 index 48b372e038a8..000000000000 --- a/trunk/drivers/regulator/wm8400-regulator.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Regulator support for WM8400 - * - * Copyright 2008 Wolfson Microelectronics PLC. - * - * Author: Mark Brown - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include - -static int wm8400_ldo_is_enabled(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - u16 val; - - val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); - return (val & WM8400_LDO1_ENA) != 0; -} - -static int wm8400_ldo_enable(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - - return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), - WM8400_LDO1_ENA, WM8400_LDO1_ENA); -} - -static int wm8400_ldo_disable(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - - return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), - WM8400_LDO1_ENA, 0); -} - -static int wm8400_ldo_get_voltage(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - u16 val; - - val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); - val &= WM8400_LDO1_VSEL_MASK; - - if (val < 15) - return 900000 + (val * 50000); - else - return 1600000 + ((val - 14) * 100000); -} - -static int wm8400_ldo_set_voltage(struct regulator_dev *dev, - int min_uV, int max_uV) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - u16 val; - - if (min_uV < 900000 || min_uV > 3300000) - return -EINVAL; - - if (min_uV < 1700000) { - /* Steps of 50mV from 900mV; */ - val = (min_uV - 850001) / 50000; - - if ((val * 50000) + 900000 > max_uV) - return -EINVAL; - BUG_ON((val * 50000) + 900000 < min_uV); - } else { - /* Steps of 100mV from 1700mV */ - val = ((min_uV - 1600001) / 100000); - - if ((val * 100000) + 1700000 > max_uV) - return -EINVAL; - BUG_ON((val * 100000) + 1700000 < min_uV); - - val += 0xf; - } - - return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), - WM8400_LDO1_VSEL_MASK, val); -} - -static struct regulator_ops wm8400_ldo_ops = { - .is_enabled = wm8400_ldo_is_enabled, - .enable = wm8400_ldo_enable, - .disable = wm8400_ldo_disable, - .get_voltage = wm8400_ldo_get_voltage, - .set_voltage = wm8400_ldo_set_voltage, -}; - -static int wm8400_dcdc_is_enabled(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - u16 val; - - val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); - return (val & WM8400_DC1_ENA) != 0; -} - -static int wm8400_dcdc_enable(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_ENA, WM8400_DC1_ENA); -} - -static int wm8400_dcdc_disable(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_ENA, 0); -} - -static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - u16 val; - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - - val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); - val &= WM8400_DC1_VSEL_MASK; - - return 850000 + (25000 * val); -} - -static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, - int min_uV, int max_uV) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - u16 val; - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - - if (min_uV < 850000) - return -EINVAL; - - val = (min_uV - 825001) / 25000; - - if (850000 + (25000 * val) > max_uV) - return -EINVAL; - BUG_ON(850000 + (25000 * val) < min_uV); - - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_VSEL_MASK, val); -} - -static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - u16 data[2]; - int ret; - - ret = wm8400_block_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 2, - data); - if (ret != 0) - return 0; - - /* Datasheet: hibernate */ - if (data[0] & WM8400_DC1_SLEEP) - return REGULATOR_MODE_STANDBY; - - /* Datasheet: standby */ - if (!(data[0] & WM8400_DC1_ACTIVE)) - return REGULATOR_MODE_IDLE; - - /* Datasheet: active with or without force PWM */ - if (data[1] & WM8400_DC1_FRC_PWM) - return REGULATOR_MODE_FAST; - else - return REGULATOR_MODE_NORMAL; -} - -static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode) -{ - struct wm8400 *wm8400 = rdev_get_drvdata(dev); - int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; - int ret; - - switch (mode) { - case REGULATOR_MODE_FAST: - /* Datasheet: active with force PWM */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, - WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM); - if (ret != 0) - return ret; - - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, - WM8400_DC1_ACTIVE); - - case REGULATOR_MODE_NORMAL: - /* Datasheet: active */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, - WM8400_DC1_FRC_PWM, 0); - if (ret != 0) - return ret; - - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, - WM8400_DC1_ACTIVE); - - case REGULATOR_MODE_IDLE: - /* Datasheet: standby */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_ACTIVE, 0); - if (ret != 0) - return ret; - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, - WM8400_DC1_SLEEP, 0); - - default: - return -EINVAL; - } -} - -static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev, - int input_uV, int output_uV, - int load_uA) -{ - return REGULATOR_MODE_NORMAL; -} - -static struct regulator_ops wm8400_dcdc_ops = { - .is_enabled = wm8400_dcdc_is_enabled, - .enable = wm8400_dcdc_enable, - .disable = wm8400_dcdc_disable, - .get_voltage = wm8400_dcdc_get_voltage, - .set_voltage = wm8400_dcdc_set_voltage, - .get_mode = wm8400_dcdc_get_mode, - .set_mode = wm8400_dcdc_set_mode, - .get_optimum_mode = wm8400_dcdc_get_optimum_mode, -}; - -static struct regulator_desc regulators[] = { - { - .name = "LDO1", - .id = WM8400_LDO1, - .ops = &wm8400_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO2", - .id = WM8400_LDO2, - .ops = &wm8400_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO3", - .id = WM8400_LDO3, - .ops = &wm8400_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "LDO4", - .id = WM8400_LDO4, - .ops = &wm8400_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC1", - .id = WM8400_DCDC1, - .ops = &wm8400_dcdc_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, - { - .name = "DCDC2", - .id = WM8400_DCDC2, - .ops = &wm8400_dcdc_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, -}; - -static int __init wm8400_regulator_probe(struct platform_device *pdev) -{ - struct regulator_dev *rdev; - - rdev = regulator_register(®ulators[pdev->id], &pdev->dev, - pdev->dev.driver_data); - - if (IS_ERR(rdev)) - return PTR_ERR(rdev); - - return 0; -} - -static int __devexit wm8400_regulator_remove(struct platform_device *pdev) -{ - struct regulator_dev *rdev = platform_get_drvdata(pdev); - - regulator_unregister(rdev); - - return 0; -} - -static struct platform_driver wm8400_regulator_driver = { - .driver = { - .name = "wm8400-regulator", - }, - .probe = wm8400_regulator_probe, - .remove = __devexit_p(wm8400_regulator_remove), -}; - -/** - * wm8400_register_regulator - enable software control of a WM8400 regulator - * - * This function enables software control of a WM8400 regulator via - * the regulator API. It is intended to be called from the - * platform_init() callback of the WM8400 MFD driver. - * - * @param dev The WM8400 device to operate on. - * @param reg The regulator to control. - * @param initdata Regulator initdata for the regulator. - */ -int wm8400_register_regulator(struct device *dev, int reg, - struct regulator_init_data *initdata) -{ - struct wm8400 *wm8400 = dev->driver_data; - - if (wm8400->regulators[reg].name) - return -EBUSY; - - initdata->driver_data = wm8400; - - wm8400->regulators[reg].name = "wm8400-regulator"; - wm8400->regulators[reg].id = reg; - wm8400->regulators[reg].dev.parent = dev; - wm8400->regulators[reg].dev.driver_data = wm8400; - wm8400->regulators[reg].dev.platform_data = initdata; - - return platform_device_register(&wm8400->regulators[reg]); -} -EXPORT_SYMBOL_GPL(wm8400_register_regulator); - -static int __init wm8400_regulator_init(void) -{ - return platform_driver_register(&wm8400_regulator_driver); -} -module_init(wm8400_regulator_init); - -static void __exit wm8400_regulator_exit(void) -{ - platform_driver_unregister(&wm8400_regulator_driver); -} -module_exit(wm8400_regulator_exit); - -MODULE_AUTHOR("Mark Brown "); -MODULE_DESCRIPTION("WM8400 regulator driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:wm8400-regulator"); diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index f660ef3e5b29..b57fba5c6d02 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -220,22 +220,22 @@ config RTC_DRV_PCF8583 will be called rtc-pcf8583. config RTC_DRV_M41T80 - tristate "ST M41T65/M41T80/81/82/83/84/85/87" + tristate "ST M41T80/81/82/83/84/85/87" help - If you say Y here you will get support for the ST M41T60 - and M41T80 RTC chips series. Currently, the following chips are - supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84, - M41ST85, and M41ST87. + If you say Y here you will get support for the + ST M41T80 RTC chips series. Currently following chips are + supported: M41T80, M41T81, M41T82, M41T83, M41ST84, M41ST85 + and M41ST87. This driver can also be built as a module. If so, the module will be called rtc-m41t80. config RTC_DRV_M41T80_WDT - bool "ST M41T65/M41T80 series RTC watchdog timer" + bool "ST M41T80 series RTC watchdog timer" depends on RTC_DRV_M41T80 help If you say Y here you will get support for the - watchdog timer in the ST M41T60 and M41T80 RTC chips series. + watchdog timer in ST M41T80 RTC chips series. config RTC_DRV_TWL92330 boolean "TI TWL92330/Menelaus" @@ -319,15 +319,6 @@ config RTC_DRV_RS5C348 This driver can also be built as a module. If so, the module will be called rtc-rs5c348. -config RTC_DRV_DS3234 - tristate "Maxim/Dallas DS3234" - help - If you say yes here you get support for the - Maxim/Dallas DS3234 SPI RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-ds3234. - endif # SPI_MASTER comment "Platform RTC drivers" @@ -361,11 +352,6 @@ config RTC_DRV_DS1216 help If you say yes here you get support for the Dallas DS1216 RTC chips. -config RTC_DRV_DS1286 - tristate "Dallas DS1286" - help - If you say yes here you get support for the Dallas DS1286 RTC chips. - config RTC_DRV_DS1302 tristate "Dallas DS1302" depends on SH_SECUREEDGE5410 @@ -419,15 +405,6 @@ config RTC_DRV_M48T86 This driver can also be built as a module. If so, the module will be called rtc-m48t86. -config RTC_DRV_M48T35 - tristate "ST M48T35" - help - If you say Y here you will get support for the - ST M48T35 RTC chip. - - This driver can also be built as a module, if so, the module - will be called "rtc-m48t35". - config RTC_DRV_M48T59 tristate "ST M48T59/M48T08/M48T02" help @@ -612,7 +589,7 @@ config RTC_DRV_RS5C313 config RTC_DRV_PPC tristate "PowerPC machine dependent RTC support" - depends on PPC + depends on PPC_MERGE help The PowerPC kernel has machine-specific functions for accessing the RTC. This exposes that functionality through the generic RTC diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index d05928b3ca94..10f41f85c38a 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o -obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o @@ -32,13 +31,11 @@ obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o -obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o -obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o diff --git a/trunk/drivers/rtc/rtc-at91rm9200.c b/trunk/drivers/rtc/rtc-at91rm9200.c index 37082616482b..4e888cc8be5b 100644 --- a/trunk/drivers/rtc/rtc-at91rm9200.c +++ b/trunk/drivers/rtc/rtc-at91rm9200.c @@ -29,10 +29,10 @@ #include #include - #include +#define AT91_RTC_FREQ 1 #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ static DECLARE_COMPLETION(at91_rtc_updated); @@ -228,6 +228,8 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); seq_printf(seq, "periodic_IRQ\t: %s\n", (imr & AT91_RTC_SECEV) ? "yes" : "no"); + seq_printf(seq, "periodic_freq\t: %ld\n", + (unsigned long) AT91_RTC_FREQ); return 0; } diff --git a/trunk/drivers/rtc/rtc-cmos.c b/trunk/drivers/rtc/rtc-cmos.c index 963ad0b6a4e9..b23af0c2a869 100644 --- a/trunk/drivers/rtc/rtc-cmos.c +++ b/trunk/drivers/rtc/rtc-cmos.c @@ -913,92 +913,6 @@ static inline int cmos_poweroff(struct device *dev) * predate even PNPBIOS should set up platform_bus devices. */ -#ifdef CONFIG_ACPI - -#include - -#ifdef CONFIG_PM -static u32 rtc_handler(void *context) -{ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); - return ACPI_INTERRUPT_HANDLED; -} - -static inline void rtc_wake_setup(void) -{ - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); - /* - * After the RTC handler is installed, the Fixed_RTC event should - * be disabled. Only when the RTC alarm is set will it be enabled. - */ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); -} - -static void rtc_wake_on(struct device *dev) -{ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_enable_event(ACPI_EVENT_RTC, 0); -} - -static void rtc_wake_off(struct device *dev) -{ - acpi_disable_event(ACPI_EVENT_RTC, 0); -} -#else -#define rtc_wake_setup() do{}while(0) -#define rtc_wake_on NULL -#define rtc_wake_off NULL -#endif - -/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find - * its device node and pass extra config data. This helps its driver use - * capabilities that the now-obsolete mc146818 didn't have, and informs it - * that this board's RTC is wakeup-capable (per ACPI spec). - */ -static struct cmos_rtc_board_info acpi_rtc_info; - -static void __devinit -cmos_wake_setup(struct device *dev) -{ - if (acpi_disabled) - return; - - rtc_wake_setup(); - acpi_rtc_info.wake_on = rtc_wake_on; - acpi_rtc_info.wake_off = rtc_wake_off; - - /* workaround bug in some ACPI tables */ - if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { - dev_dbg(dev, "bogus FADT month_alarm (%d)\n", - acpi_gbl_FADT.month_alarm); - acpi_gbl_FADT.month_alarm = 0; - } - - acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; - acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; - acpi_rtc_info.rtc_century = acpi_gbl_FADT.century; - - /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ - if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) - dev_info(dev, "RTC can wake from S4\n"); - - dev->platform_data = &acpi_rtc_info; - - /* RTC always wakes from S1/S2/S3, and often S4/STD */ - device_init_wakeup(dev, 1); -} - -#else - -static void __devinit -cmos_wake_setup(struct device *dev) -{ -} - -#endif - #ifdef CONFIG_PNP #include @@ -1006,8 +920,6 @@ cmos_wake_setup(struct device *dev) static int __devinit cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) { - cmos_wake_setup(&pnp->dev); - if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0)) /* Some machines contain a PNP entry for the RTC, but * don't define the IRQ. It should always be safe to @@ -1085,7 +997,6 @@ static struct pnp_driver cmos_pnp_driver = { static int __init cmos_platform_probe(struct platform_device *pdev) { - cmos_wake_setup(&pdev->dev); return cmos_do_probe(&pdev->dev, platform_get_resource(pdev, IORESOURCE_IO, 0), platform_get_irq(pdev, 0)); @@ -1120,32 +1031,29 @@ static struct platform_driver cmos_platform_driver = { static int __init cmos_init(void) { - int retval = 0; - #ifdef CONFIG_PNP - pnp_register_driver(&cmos_pnp_driver); -#endif - - if (!cmos_rtc.dev) - retval = platform_driver_probe(&cmos_platform_driver, - cmos_platform_probe); - - if (retval == 0) - return 0; - -#ifdef CONFIG_PNP - pnp_unregister_driver(&cmos_pnp_driver); -#endif - return retval; + if (pnp_platform_devices) + return pnp_register_driver(&cmos_pnp_driver); + else + return platform_driver_probe(&cmos_platform_driver, + cmos_platform_probe); +#else + return platform_driver_probe(&cmos_platform_driver, + cmos_platform_probe); +#endif /* CONFIG_PNP */ } module_init(cmos_init); static void __exit cmos_exit(void) { #ifdef CONFIG_PNP - pnp_unregister_driver(&cmos_pnp_driver); -#endif + if (pnp_platform_devices) + pnp_unregister_driver(&cmos_pnp_driver); + else + platform_driver_unregister(&cmos_platform_driver); +#else platform_driver_unregister(&cmos_platform_driver); +#endif /* CONFIG_PNP */ } module_exit(cmos_exit); diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 079e9ed907e0..52e2743b04ec 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -432,15 +432,9 @@ static int rtc_dev_release(struct inode *inode, struct file *file) { struct rtc_device *rtc = file->private_data; - /* We shut down the repeating IRQs that userspace enabled, - * since nothing is listening to them. - * - Update (UIE) ... currently only managed through ioctls - * - Periodic (PIE) ... also used through rtc_*() interface calls - * - * Leave the alarm alone; it may be set to trigger a system wakeup - * later, or be used by kernel code, and is a one-shot event anyway. - */ - rtc_dev_ioctl(file, RTC_UIE_OFF, 0); +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + clear_uie(rtc); +#endif rtc_irq_set_state(rtc, NULL, 0); if (rtc->ops->release) diff --git a/trunk/drivers/rtc/rtc-ds1286.c b/trunk/drivers/rtc/rtc-ds1286.c deleted file mode 100644 index 4fcb16bbff4a..000000000000 --- a/trunk/drivers/rtc/rtc-ds1286.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * DS1286 Real Time Clock interface for Linux - * - * Copyright (C) 1998, 1999, 2000 Ralf Baechle - * Copyright (C) 2008 Thomas Bogendoerfer - * - * Based on code written by Paul Gortmaker. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include - -#define DRV_VERSION "1.0" - -struct ds1286_priv { - struct rtc_device *rtc; - u32 __iomem *rtcregs; - size_t size; - unsigned long baseaddr; - spinlock_t lock; -}; - -static inline u8 ds1286_rtc_read(struct ds1286_priv *priv, int reg) -{ - return __raw_readl(&priv->rtcregs[reg]) & 0xff; -} - -static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) -{ - __raw_writel(data, &priv->rtcregs[reg]); -} - -#ifdef CONFIG_RTC_INTF_DEV - -static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned long flags; - unsigned char val; - - switch (cmd) { - case RTC_AIE_OFF: - /* Mask alarm int. enab. bit */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val |= RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; - case RTC_AIE_ON: - /* Allow alarm interrupts. */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val &= ~RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; - case RTC_WIE_OFF: - /* Mask watchdog int. enab. bit */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val |= RTC_WAM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; - case RTC_WIE_ON: - /* Allow watchdog interrupts. */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val &= ~RTC_WAM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; - default: - return -ENOIOCTLCMD; - } - return 0; -} - -#else -#define ds1286_ioctl NULL -#endif - -#ifdef CONFIG_PROC_FS - -static int ds1286_proc(struct device *dev, struct seq_file *seq) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned char month, cmd, amode; - const char *s; - - month = ds1286_rtc_read(priv, RTC_MONTH); - seq_printf(seq, - "oscillator\t: %s\n" - "square_wave\t: %s\n", - (month & RTC_EOSC) ? "disabled" : "enabled", - (month & RTC_ESQW) ? "disabled" : "enabled"); - - amode = ((ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x80) >> 5) | - ((ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x80) >> 6) | - ((ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x80) >> 7); - switch (amode) { - case 7: - s = "each minute"; - break; - case 3: - s = "minutes match"; - break; - case 1: - s = "hours and minutes match"; - break; - case 0: - s = "days, hours and minutes match"; - break; - default: - s = "invalid"; - break; - } - seq_printf(seq, "alarm_mode\t: %s\n", s); - - cmd = ds1286_rtc_read(priv, RTC_CMD); - seq_printf(seq, - "alarm_enable\t: %s\n" - "wdog_alarm\t: %s\n" - "alarm_mask\t: %s\n" - "wdog_alarm_mask\t: %s\n" - "interrupt_mode\t: %s\n" - "INTB_mode\t: %s_active\n" - "interrupt_pins\t: %s\n", - (cmd & RTC_TDF) ? "yes" : "no", - (cmd & RTC_WAF) ? "yes" : "no", - (cmd & RTC_TDM) ? "disabled" : "enabled", - (cmd & RTC_WAM) ? "disabled" : "enabled", - (cmd & RTC_PU_LVL) ? "pulse" : "level", - (cmd & RTC_IBH_LO) ? "low" : "high", - (cmd & RTC_IPSW) ? "unswapped" : "swapped"); - return 0; -} - -#else -#define ds1286_proc NULL -#endif - -static int ds1286_read_time(struct device *dev, struct rtc_time *tm) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned char save_control; - unsigned long flags; - unsigned long uip_watchdog = jiffies; - - /* - * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to - * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. - * If you need to know *exactly* when a second has started, enable - * periodic update complete interrupts, (via ioctl) and then - * immediately read /dev/rtc which will block until you get the IRQ. - * Once the read clears, read the RTC time (again via ioctl). Easy. - */ - - if (ds1286_rtc_read(priv, RTC_CMD) & RTC_TE) - while (time_before(jiffies, uip_watchdog + 2*HZ/100)) - barrier(); - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - spin_lock_irqsave(&priv->lock, flags); - save_control = ds1286_rtc_read(priv, RTC_CMD); - ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD); - - tm->tm_sec = ds1286_rtc_read(priv, RTC_SECONDS); - tm->tm_min = ds1286_rtc_read(priv, RTC_MINUTES); - tm->tm_hour = ds1286_rtc_read(priv, RTC_HOURS) & 0x3f; - tm->tm_mday = ds1286_rtc_read(priv, RTC_DATE); - tm->tm_mon = ds1286_rtc_read(priv, RTC_MONTH) & 0x1f; - tm->tm_year = ds1286_rtc_read(priv, RTC_YEAR); - - ds1286_rtc_write(priv, save_control, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - - tm->tm_sec = bcd2bin(tm->tm_sec); - tm->tm_min = bcd2bin(tm->tm_min); - tm->tm_hour = bcd2bin(tm->tm_hour); - tm->tm_mday = bcd2bin(tm->tm_mday); - tm->tm_mon = bcd2bin(tm->tm_mon); - tm->tm_year = bcd2bin(tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if (tm->tm_year < 45) - tm->tm_year += 30; - tm->tm_year += 40; - if (tm->tm_year < 70) - tm->tm_year += 100; - - tm->tm_mon--; - - return rtc_valid_tm(tm); -} - -static int ds1286_set_time(struct device *dev, struct rtc_time *tm) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned char mon, day, hrs, min, sec; - unsigned char save_control; - unsigned int yrs; - unsigned long flags; - - yrs = tm->tm_year + 1900; - mon = tm->tm_mon + 1; /* tm_mon starts at zero */ - day = tm->tm_mday; - hrs = tm->tm_hour; - min = tm->tm_min; - sec = tm->tm_sec; - - if (yrs < 1970) - return -EINVAL; - - yrs -= 1940; - if (yrs > 255) /* They are unsigned */ - return -EINVAL; - - if (yrs >= 100) - yrs -= 100; - - sec = bin2bcd(sec); - min = bin2bcd(min); - hrs = bin2bcd(hrs); - day = bin2bcd(day); - mon = bin2bcd(mon); - yrs = bin2bcd(yrs); - - spin_lock_irqsave(&priv->lock, flags); - save_control = ds1286_rtc_read(priv, RTC_CMD); - ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD); - - ds1286_rtc_write(priv, yrs, RTC_YEAR); - ds1286_rtc_write(priv, mon, RTC_MONTH); - ds1286_rtc_write(priv, day, RTC_DATE); - ds1286_rtc_write(priv, hrs, RTC_HOURS); - ds1286_rtc_write(priv, min, RTC_MINUTES); - ds1286_rtc_write(priv, sec, RTC_SECONDS); - ds1286_rtc_write(priv, 0, RTC_HUNDREDTH_SECOND); - - ds1286_rtc_write(priv, save_control, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - return 0; -} - -static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned char cmd; - unsigned long flags; - - /* - * Only the values that we read from the RTC are set. That - * means only tm_wday, tm_hour, tm_min. - */ - spin_lock_irqsave(&priv->lock, flags); - alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f; - alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x1f; - alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x07; - cmd = ds1286_rtc_read(priv, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - - alm->time.tm_min = bcd2bin(alm->time.tm_min); - alm->time.tm_hour = bcd2bin(alm->time.tm_hour); - alm->time.tm_sec = 0; - return 0; -} - -static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned char hrs, min, sec; - - hrs = alm->time.tm_hour; - min = alm->time.tm_min; - sec = alm->time.tm_sec; - - if (hrs >= 24) - hrs = 0xff; - - if (min >= 60) - min = 0xff; - - if (sec != 0) - return -EINVAL; - - min = bin2bcd(min); - hrs = bin2bcd(hrs); - - spin_lock(&priv->lock); - ds1286_rtc_write(priv, hrs, RTC_HOURS_ALARM); - ds1286_rtc_write(priv, min, RTC_MINUTES_ALARM); - spin_unlock(&priv->lock); - - return 0; -} - -static const struct rtc_class_ops ds1286_ops = { - .ioctl = ds1286_ioctl, - .proc = ds1286_proc, - .read_time = ds1286_read_time, - .set_time = ds1286_set_time, - .read_alarm = ds1286_read_alarm, - .set_alarm = ds1286_set_alarm, -}; - -static int __devinit ds1286_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - struct resource *res; - struct ds1286_priv *priv; - int ret = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - priv = kzalloc(sizeof(struct ds1286_priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->size = res->end - res->start + 1; - if (!request_mem_region(res->start, priv->size, pdev->name)) { - ret = -EBUSY; - goto out; - } - priv->baseaddr = res->start; - priv->rtcregs = ioremap(priv->baseaddr, priv->size); - if (!priv->rtcregs) { - ret = -ENOMEM; - goto out; - } - spin_lock_init(&priv->lock); - rtc = rtc_device_register("ds1286", &pdev->dev, - &ds1286_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto out; - } - priv->rtc = rtc; - platform_set_drvdata(pdev, priv); - return 0; - -out: - if (priv->rtc) - rtc_device_unregister(priv->rtc); - if (priv->rtcregs) - iounmap(priv->rtcregs); - if (priv->baseaddr) - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return ret; -} - -static int __devexit ds1286_remove(struct platform_device *pdev) -{ - struct ds1286_priv *priv = platform_get_drvdata(pdev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->rtcregs); - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return 0; -} - -static struct platform_driver ds1286_platform_driver = { - .driver = { - .name = "rtc-ds1286", - .owner = THIS_MODULE, - }, - .probe = ds1286_probe, - .remove = __devexit_p(ds1286_remove), -}; - -static int __init ds1286_init(void) -{ - return platform_driver_register(&ds1286_platform_driver); -} - -static void __exit ds1286_exit(void) -{ - platform_driver_unregister(&ds1286_platform_driver); -} - -MODULE_AUTHOR("Thomas Bogendoerfer "); -MODULE_DESCRIPTION("DS1286 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); -MODULE_ALIAS("platform:rtc-ds1286"); - -module_init(ds1286_init); -module_exit(ds1286_exit); diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index 4fcf0734a6ef..bbf97e65202a 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -23,6 +23,10 @@ * to have set the chip up as a clock (turning on the oscillator and * setting the date and time), Linux can ignore the non-clock features. * That's a natural job for a factory or repair bench. + * + * This is currently a simple no-alarms driver. If your board has the + * alarm irq wired up on a ds1337 or ds1339, and you want to use that, + * then look at the rtc-rs5c372 driver for code to steal... */ enum ds_type { ds_1307, @@ -63,7 +67,6 @@ enum ds_type { # define DS1307_BIT_RS0 0x01 #define DS1337_REG_CONTROL 0x0e # define DS1337_BIT_nEOSC 0x80 -# define DS1339_BIT_BBSQI 0x20 # define DS1337_BIT_RS2 0x10 # define DS1337_BIT_RS1 0x08 # define DS1337_BIT_INTCN 0x04 @@ -80,22 +83,19 @@ enum ds_type { # define DS1337_BIT_OSF 0x80 # define DS1337_BIT_A2I 0x02 # define DS1337_BIT_A1I 0x01 -#define DS1339_REG_ALARM1_SECS 0x07 #define DS1339_REG_TRICKLE 0x10 struct ds1307 { u8 reg_addr; - u8 regs[11]; + bool has_nvram; + u8 regs[8]; enum ds_type type; - unsigned long flags; -#define HAS_NVRAM 0 /* bit 0 == sysfs file active */ -#define HAS_ALARM 1 /* bit 1 == irq claimed */ struct i2c_msg msg[2]; struct i2c_client *client; + struct i2c_client dev; struct rtc_device *rtc; - struct work_struct work; }; struct chip_desc { @@ -132,79 +132,12 @@ static const struct i2c_device_id ds1307_id[] = { }; MODULE_DEVICE_TABLE(i2c, ds1307_id); -/*----------------------------------------------------------------------*/ - -/* - * The IRQ logic includes a "real" handler running in IRQ context just - * long enough to schedule this workqueue entry. We need a task context - * to talk to the RTC, since I2C I/O calls require that; and disable the - * IRQ until we clear its status on the chip, so that this handler can - * work with any type of triggering (not just falling edge). - * - * The ds1337 and ds1339 both have two alarms, but we only use the first - * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm - * signal; ds1339 chips have only one alarm signal. - */ -static void ds1307_work(struct work_struct *work) -{ - struct ds1307 *ds1307; - struct i2c_client *client; - struct mutex *lock; - int stat, control; - - ds1307 = container_of(work, struct ds1307, work); - client = ds1307->client; - lock = &ds1307->rtc->ops_lock; - - mutex_lock(lock); - stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); - if (stat < 0) - goto out; - - if (stat & DS1337_BIT_A1I) { - stat &= ~DS1337_BIT_A1I; - i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, stat); - - control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); - if (control < 0) - goto out; - - control &= ~DS1337_BIT_A1IE; - i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control); - - /* rtc_update_irq() assumes that it is called - * from IRQ-disabled context. - */ - local_irq_disable(); - rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); - local_irq_enable(); - } - -out: - if (test_bit(HAS_ALARM, &ds1307->flags)) - enable_irq(client->irq); - mutex_unlock(lock); -} - -static irqreturn_t ds1307_irq(int irq, void *dev_id) -{ - struct i2c_client *client = dev_id; - struct ds1307 *ds1307 = i2c_get_clientdata(client); - - disable_irq_nosync(irq); - schedule_work(&ds1307->work); - return IRQ_HANDLED; -} - -/*----------------------------------------------------------------------*/ - static int ds1307_get_time(struct device *dev, struct rtc_time *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); int tmp; /* read the RTC date and time registers all at once */ - ds1307->reg_addr = 0; ds1307->msg[1].flags = I2C_M_RD; ds1307->msg[1].len = 7; @@ -298,186 +231,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) return 0; } -static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ds1307 *ds1307 = i2c_get_clientdata(client); - int ret; - - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -EINVAL; - - /* read all ALARM1, ALARM2, and status registers at once */ - ds1307->reg_addr = DS1339_REG_ALARM1_SECS; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = 9; - - ret = i2c_transfer(to_i2c_adapter(client->dev.parent), - ds1307->msg, 2); - if (ret != 2) { - dev_err(dev, "%s error %d\n", "alarm read", ret); - return -EIO; - } - - dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", - "alarm read", - ds1307->regs[0], ds1307->regs[1], - ds1307->regs[2], ds1307->regs[3], - ds1307->regs[4], ds1307->regs[5], - ds1307->regs[6], ds1307->regs[7], - ds1307->regs[8]); - - /* report alarm time (ALARM1); assume 24 hour and day-of-month modes, - * and that all four fields are checked matches - */ - t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); - t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); - t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); - t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); - t->time.tm_mon = -1; - t->time.tm_year = -1; - t->time.tm_wday = -1; - t->time.tm_yday = -1; - t->time.tm_isdst = -1; - - /* ... and status */ - t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); - t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I); - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, enabled=%d, pending=%d\n", - "alarm read", t->time.tm_sec, t->time.tm_min, - t->time.tm_hour, t->time.tm_mday, - t->enabled, t->pending); - - return 0; -} - -static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ds1307 *ds1307 = i2c_get_clientdata(client); - unsigned char *buf = ds1307->regs; - u8 control, status; - int ret; - - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -EINVAL; - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, enabled=%d, pending=%d\n", - "alarm set", t->time.tm_sec, t->time.tm_min, - t->time.tm_hour, t->time.tm_mday, - t->enabled, t->pending); - - /* read current status of both alarms and the chip */ - ds1307->reg_addr = DS1339_REG_ALARM1_SECS; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = 9; - - ret = i2c_transfer(to_i2c_adapter(client->dev.parent), - ds1307->msg, 2); - if (ret != 2) { - dev_err(dev, "%s error %d\n", "alarm write", ret); - return -EIO; - } - control = ds1307->regs[7]; - status = ds1307->regs[8]; - - dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", - "alarm set (old status)", - ds1307->regs[0], ds1307->regs[1], - ds1307->regs[2], ds1307->regs[3], - ds1307->regs[4], ds1307->regs[5], - ds1307->regs[6], control, status); - - /* set ALARM1, using 24 hour and day-of-month modes */ - *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */ - buf[0] = bin2bcd(t->time.tm_sec); - buf[1] = bin2bcd(t->time.tm_min); - buf[2] = bin2bcd(t->time.tm_hour); - buf[3] = bin2bcd(t->time.tm_mday); - - /* set ALARM2 to non-garbage */ - buf[4] = 0; - buf[5] = 0; - buf[6] = 0; - - /* optionally enable ALARM1 */ - buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE); - if (t->enabled) { - dev_dbg(dev, "alarm IRQ armed\n"); - buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ - } - buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); - - ds1307->msg[1].flags = 0; - ds1307->msg[1].len = 10; - - ret = i2c_transfer(to_i2c_adapter(client->dev.parent), - &ds1307->msg[1], 1); - if (ret != 1) { - dev_err(dev, "can't set alarm time\n"); - return -EIO; - } - - return 0; -} - -static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ds1307 *ds1307 = i2c_get_clientdata(client); - int ret; - - switch (cmd) { - case RTC_AIE_OFF: - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -ENOTTY; - - ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); - if (ret < 0) - return ret; - - ret &= ~DS1337_BIT_A1IE; - - ret = i2c_smbus_write_byte_data(client, - DS1337_REG_CONTROL, ret); - if (ret < 0) - return ret; - - break; - - case RTC_AIE_ON: - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -ENOTTY; - - ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); - if (ret < 0) - return ret; - - ret |= DS1337_BIT_A1IE; - - ret = i2c_smbus_write_byte_data(client, - DS1337_REG_CONTROL, ret); - if (ret < 0) - return ret; - - break; - - default: - return -ENOIOCTLCMD; - } - - return 0; -} - static const struct rtc_class_ops ds13xx_rtc_ops = { .read_time = ds1307_get_time, .set_time = ds1307_set_time, - .read_alarm = ds1307_read_alarm, - .set_alarm = ds1307_set_alarm, - .ioctl = ds1307_ioctl, }; /*----------------------------------------------------------------------*/ @@ -571,7 +327,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, int tmp; const struct chip_desc *chip = &chips[id->driver_data]; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - int want_irq = false; if (!i2c_check_functionality(adapter, I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) @@ -598,12 +353,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, switch (ds1307->type) { case ds_1337: case ds_1339: - /* has IRQ? */ - if (ds1307->client->irq > 0 && chip->alarm) { - INIT_WORK(&ds1307->work, ds1307_work); - want_irq = true; - } - ds1307->reg_addr = DS1337_REG_CONTROL; ds1307->msg[1].len = 2; @@ -620,20 +369,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, /* oscillator off? turn it on, so clock can tick. */ if (ds1307->regs[0] & DS1337_BIT_nEOSC) - ds1307->regs[0] &= ~DS1337_BIT_nEOSC; - - /* Using IRQ? Disable the square wave and both alarms. - * For ds1339, be sure alarms can trigger when we're - * running on Vbackup (BBSQI); we assume ds1337 will - * ignore that bit - */ - if (want_irq) { - ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI; - ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); - } - - i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, - ds1307->regs[0]); + i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, + ds1307->regs[0] & ~DS1337_BIT_nEOSC); /* oscillator fault? clear flag, and warn */ if (ds1307->regs[1] & DS1337_BIT_OSF) { @@ -758,22 +495,10 @@ static int __devinit ds1307_probe(struct i2c_client *client, goto exit_free; } - if (want_irq) { - err = request_irq(client->irq, ds1307_irq, 0, - ds1307->rtc->name, client); - if (err) { - dev_err(&client->dev, - "unable to request IRQ!\n"); - goto exit_irq; - } - set_bit(HAS_ALARM, &ds1307->flags); - dev_dbg(&client->dev, "got IRQ %d\n", client->irq); - } - if (chip->nvram56) { err = sysfs_create_bin_file(&client->dev.kobj, &nvram); if (err == 0) { - set_bit(HAS_NVRAM, &ds1307->flags); + ds1307->has_nvram = true; dev_info(&client->dev, "56 bytes nvram\n"); } } @@ -787,9 +512,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, ds1307->regs[2], ds1307->regs[3], ds1307->regs[4], ds1307->regs[5], ds1307->regs[6]); -exit_irq: - if (ds1307->rtc) - rtc_device_unregister(ds1307->rtc); + exit_free: kfree(ds1307); return err; @@ -797,14 +520,9 @@ static int __devinit ds1307_probe(struct i2c_client *client, static int __devexit ds1307_remove(struct i2c_client *client) { - struct ds1307 *ds1307 = i2c_get_clientdata(client); - - if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { - free_irq(client->irq, client); - cancel_work_sync(&ds1307->work); - } + struct ds1307 *ds1307 = i2c_get_clientdata(client); - if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) + if (ds1307->has_nvram) sysfs_remove_bin_file(&client->dev.kobj, &nvram); rtc_device_unregister(ds1307->rtc); diff --git a/trunk/drivers/rtc/rtc-ds1374.c b/trunk/drivers/rtc/rtc-ds1374.c index a5b0fc09f0c6..a150418fba76 100644 --- a/trunk/drivers/rtc/rtc-ds1374.c +++ b/trunk/drivers/rtc/rtc-ds1374.c @@ -429,33 +429,12 @@ static int __devexit ds1374_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM -static int ds1374_suspend(struct i2c_client *client, pm_message_t state) -{ - if (client->irq >= 0 && device_may_wakeup(&client->dev)) - enable_irq_wake(client->irq); - return 0; -} - -static int ds1374_resume(struct i2c_client *client) -{ - if (client->irq >= 0 && device_may_wakeup(&client->dev)) - disable_irq_wake(client->irq); - return 0; -} -#else -#define ds1374_suspend NULL -#define ds1374_resume NULL -#endif - static struct i2c_driver ds1374_driver = { .driver = { .name = "rtc-ds1374", .owner = THIS_MODULE, }, .probe = ds1374_probe, - .suspend = ds1374_suspend, - .resume = ds1374_resume, .remove = __devexit_p(ds1374_remove), .id_table = ds1374_id, }; diff --git a/trunk/drivers/rtc/rtc-ds1511.c b/trunk/drivers/rtc/rtc-ds1511.c index 86981d34fbb6..0f0d27d1c4ca 100644 --- a/trunk/drivers/rtc/rtc-ds1511.c +++ b/trunk/drivers/rtc/rtc-ds1511.c @@ -379,6 +379,18 @@ ds1511_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } + static void +ds1511_rtc_release(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + + if (pdata->irq >= 0) { + pdata->irqen = 0; + ds1511_rtc_update_alarm(pdata); + } +} + static int ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { @@ -416,6 +428,7 @@ static const struct rtc_class_ops ds1511_rtc_ops = { .set_time = ds1511_rtc_set_time, .read_alarm = ds1511_rtc_read_alarm, .set_alarm = ds1511_rtc_set_alarm, + .release = ds1511_rtc_release, .ioctl = ds1511_rtc_ioctl, }; diff --git a/trunk/drivers/rtc/rtc-ds1553.c b/trunk/drivers/rtc/rtc-ds1553.c index 4ef59285b489..a19f11415540 100644 --- a/trunk/drivers/rtc/rtc-ds1553.c +++ b/trunk/drivers/rtc/rtc-ds1553.c @@ -207,6 +207,17 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static void ds1553_rtc_release(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + + if (pdata->irq >= 0) { + pdata->irqen = 0; + ds1553_rtc_update_alarm(pdata); + } +} + static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { @@ -243,6 +254,7 @@ static const struct rtc_class_ops ds1553_rtc_ops = { .set_time = ds1553_rtc_set_time, .read_alarm = ds1553_rtc_read_alarm, .set_alarm = ds1553_rtc_set_alarm, + .release = ds1553_rtc_release, .ioctl = ds1553_rtc_ioctl, }; diff --git a/trunk/drivers/rtc/rtc-ds1672.c b/trunk/drivers/rtc/rtc-ds1672.c index 341d7a5b45a2..6fa4556f5f5c 100644 --- a/trunk/drivers/rtc/rtc-ds1672.c +++ b/trunk/drivers/rtc/rtc-ds1672.c @@ -9,10 +9,17 @@ * published by the Free Software Foundation. */ +#include #include #include -#define DRV_VERSION "0.4" +#define DRV_VERSION "0.3" + +/* Addresses to scan: none. This chip cannot be detected. */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD; /* Registers */ @@ -22,7 +29,8 @@ #define DS1672_REG_CONTROL_EOSC 0x80 -static struct i2c_driver ds1672_driver; +/* Prototypes */ +static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); /* * In the routines that deal directly with the ds1672 hardware, we use @@ -36,8 +44,8 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) unsigned char buf[4]; struct i2c_msg msgs[] = { - {client->addr, 0, 1, &addr}, /* setup read ptr */ - {client->addr, I2C_M_RD, 4, buf}, /* read date */ + { client->addr, 0, 1, &addr }, /* setup read ptr */ + { client->addr, I2C_M_RD, 4, buf }, /* read date */ }; /* read date registers */ @@ -72,7 +80,7 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) buf[2] = (secs & 0x0000FF00) >> 8; buf[3] = (secs & 0x00FF0000) >> 16; buf[4] = (secs & 0xFF000000) >> 24; - buf[5] = 0; /* set control reg to enable counting */ + buf[5] = 0; /* set control reg to enable counting */ xfer = i2c_master_send(client, buf, 6); if (xfer != 6) { @@ -119,8 +127,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status) unsigned char addr = DS1672_REG_CONTROL; struct i2c_msg msgs[] = { - {client->addr, 0, 1, &addr}, /* setup read ptr */ - {client->addr, I2C_M_RD, 1, status}, /* read control */ + { client->addr, 0, 1, &addr }, /* setup read ptr */ + { client->addr, I2C_M_RD, 1, status }, /* read control */ }; /* read control register */ @@ -133,8 +141,7 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status) } /* following are the sysfs callback functions */ -static ssize_t show_control(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); u8 control; @@ -145,46 +152,85 @@ static ssize_t show_control(struct device *dev, struct device_attribute *attr, return err; return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) - ? "disabled" : "enabled"); + ? "disabled" : "enabled"); } - static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); static const struct rtc_class_ops ds1672_rtc_ops = { - .read_time = ds1672_rtc_read_time, - .set_time = ds1672_rtc_set_time, - .set_mmss = ds1672_rtc_set_mmss, + .read_time = ds1672_rtc_read_time, + .set_time = ds1672_rtc_set_time, + .set_mmss = ds1672_rtc_set_mmss, }; -static int ds1672_remove(struct i2c_client *client) +static int ds1672_attach(struct i2c_adapter *adapter) { + return i2c_probe(adapter, &addr_data, ds1672_probe); +} + +static int ds1672_detach(struct i2c_client *client) +{ + int err; struct rtc_device *rtc = i2c_get_clientdata(client); - if (rtc) + if (rtc) rtc_device_unregister(rtc); + if ((err = i2c_detach_client(client))) + return err; + + kfree(client); + return 0; } -static int ds1672_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static struct i2c_driver ds1672_driver = { + .driver = { + .name = "ds1672", + }, + .id = I2C_DRIVERID_DS1672, + .attach_adapter = &ds1672_attach, + .detach_client = &ds1672_detach, +}; + +static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) { int err = 0; u8 control; + struct i2c_client *client; struct rtc_device *rtc; - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(&adapter->dev, "%s\n", __func__); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + err = -ENODEV; + goto exit; + } + + if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + /* I2C client */ + client->addr = address; + client->driver = &ds1672_driver; + client->adapter = adapter; + + strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE); + + /* Inform the i2c layer */ + if ((err = i2c_attach_client(client))) + goto exit_kfree; dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev, - &ds1672_rtc_ops, THIS_MODULE); + &ds1672_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + if (IS_ERR(rtc)) { + err = PTR_ERR(rtc); + goto exit_detach; + } i2c_set_clientdata(client, rtc); @@ -195,7 +241,7 @@ static int ds1672_probe(struct i2c_client *client, if (control & DS1672_REG_CONTROL_EOSC) dev_warn(&client->dev, "Oscillator not enabled. " - "Set time to enable.\n"); + "Set time to enable.\n"); /* Register sysfs hooks */ err = device_create_file(&client->dev, &dev_attr_control); @@ -204,19 +250,19 @@ static int ds1672_probe(struct i2c_client *client, return 0; - exit_devreg: +exit_devreg: rtc_device_unregister(rtc); + +exit_detach: + i2c_detach_client(client); + +exit_kfree: + kfree(client); + +exit: return err; } -static struct i2c_driver ds1672_driver = { - .driver = { - .name = "rtc-ds1672", - }, - .probe = &ds1672_probe, - .remove = &ds1672_remove, -}; - static int __init ds1672_init(void) { return i2c_add_driver(&ds1672_driver); diff --git a/trunk/drivers/rtc/rtc-ds3234.c b/trunk/drivers/rtc/rtc-ds3234.c deleted file mode 100644 index 37d131d03f33..000000000000 --- a/trunk/drivers/rtc/rtc-ds3234.c +++ /dev/null @@ -1,290 +0,0 @@ -/* drivers/rtc/rtc-ds3234.c - * - * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal - * and SRAM. - * - * Copyright (C) 2008 MIMOMax Wireless Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Changelog: - * - * 07-May-2008: Dennis Aberilla - * - Created based on the max6902 code. Only implements the - * date/time keeping functions; no SRAM yet. - */ - -#include -#include -#include -#include -#include - -#define DS3234_REG_SECONDS 0x00 -#define DS3234_REG_MINUTES 0x01 -#define DS3234_REG_HOURS 0x02 -#define DS3234_REG_DAY 0x03 -#define DS3234_REG_DATE 0x04 -#define DS3234_REG_MONTH 0x05 -#define DS3234_REG_YEAR 0x06 -#define DS3234_REG_CENTURY (1 << 7) /* Bit 7 of the Month register */ - -#define DS3234_REG_CONTROL 0x0E -#define DS3234_REG_CONT_STAT 0x0F - -#undef DS3234_DEBUG - -struct ds3234 { - struct rtc_device *rtc; - u8 buf[8]; /* Burst read: addr + 7 regs */ - u8 tx_buf[2]; - u8 rx_buf[2]; -}; - -static void ds3234_set_reg(struct device *dev, unsigned char address, - unsigned char data) -{ - struct spi_device *spi = to_spi_device(dev); - unsigned char buf[2]; - - /* MSB must be '1' to indicate write */ - buf[0] = address | 0x80; - buf[1] = data; - - spi_write(spi, buf, 2); -} - -static int ds3234_get_reg(struct device *dev, unsigned char address, - unsigned char *data) -{ - struct spi_device *spi = to_spi_device(dev); - struct ds3234 *chip = dev_get_drvdata(dev); - struct spi_message message; - struct spi_transfer xfer; - int status; - - if (!data) - return -EINVAL; - - /* Build our spi message */ - spi_message_init(&message); - memset(&xfer, 0, sizeof(xfer)); - - /* Address + dummy tx byte */ - xfer.len = 2; - xfer.tx_buf = chip->tx_buf; - xfer.rx_buf = chip->rx_buf; - - chip->tx_buf[0] = address; - chip->tx_buf[1] = 0xff; - - spi_message_add_tail(&xfer, &message); - - /* do the i/o */ - status = spi_sync(spi, &message); - if (status == 0) - status = message.status; - else - return status; - - *data = chip->rx_buf[1]; - - return status; -} - -static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt) -{ - struct spi_device *spi = to_spi_device(dev); - struct ds3234 *chip = dev_get_drvdata(dev); - struct spi_message message; - struct spi_transfer xfer; - int status; - - /* build the message */ - spi_message_init(&message); - memset(&xfer, 0, sizeof(xfer)); - xfer.len = 1 + 7; /* Addr + 7 registers */ - xfer.tx_buf = chip->buf; - xfer.rx_buf = chip->buf; - chip->buf[0] = 0x00; /* Start address */ - spi_message_add_tail(&xfer, &message); - - /* do the i/o */ - status = spi_sync(spi, &message); - if (status == 0) - status = message.status; - else - return status; - - /* Seconds, Minutes, Hours, Day, Date, Month, Year */ - dt->tm_sec = bcd2bin(chip->buf[1]); - dt->tm_min = bcd2bin(chip->buf[2]); - dt->tm_hour = bcd2bin(chip->buf[3] & 0x3f); - dt->tm_wday = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */ - dt->tm_mday = bcd2bin(chip->buf[5]); - dt->tm_mon = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */ - dt->tm_year = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */ - -#ifdef DS3234_DEBUG - dev_dbg(dev, "\n%s : Read RTC values\n", __func__); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); -#endif - - return 0; -} - -static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt) -{ -#ifdef DS3234_DEBUG - dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); -#endif - - ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); - ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); - ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); - - /* 0 = Sun */ - ds3234_set_reg(dev, DS3234_REG_DAY, bin2bcd(dt->tm_wday + 1)); - ds3234_set_reg(dev, DS3234_REG_DATE, bin2bcd(dt->tm_mday)); - - /* 0 = Jan */ - ds3234_set_reg(dev, DS3234_REG_MONTH, bin2bcd(dt->tm_mon + 1)); - - /* Assume 20YY although we just want to make sure not to go negative. */ - if (dt->tm_year > 100) - dt->tm_year -= 100; - - ds3234_set_reg(dev, DS3234_REG_YEAR, bin2bcd(dt->tm_year)); - - return 0; -} - -static int ds3234_read_time(struct device *dev, struct rtc_time *tm) -{ - return ds3234_get_datetime(dev, tm); -} - -static int ds3234_set_time(struct device *dev, struct rtc_time *tm) -{ - return ds3234_set_datetime(dev, tm); -} - -static const struct rtc_class_ops ds3234_rtc_ops = { - .read_time = ds3234_read_time, - .set_time = ds3234_set_time, -}; - -static int ds3234_probe(struct spi_device *spi) -{ - struct rtc_device *rtc; - unsigned char tmp; - struct ds3234 *chip; - int res; - - rtc = rtc_device_register("ds3234", - &spi->dev, &ds3234_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - - chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL); - if (!chip) { - rtc_device_unregister(rtc); - return -ENOMEM; - } - chip->rtc = rtc; - dev_set_drvdata(&spi->dev, chip); - - res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); - if (res) { - rtc_device_unregister(rtc); - return res; - } - - /* Control settings - * - * CONTROL_REG - * BIT 7 6 5 4 3 2 1 0 - * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE - * - * 0 0 0 1 1 1 0 0 - * - * CONTROL_STAT_REG - * BIT 7 6 5 4 3 2 1 0 - * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F - * - * 1 0 0 0 1 0 0 0 - */ - ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp); - ds3234_set_reg(&spi->dev, DS3234_REG_CONTROL, tmp & 0x1c); - - ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); - ds3234_set_reg(&spi->dev, DS3234_REG_CONT_STAT, tmp & 0x88); - - /* Print our settings */ - ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp); - dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp); - - ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); - dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); - - return 0; -} - -static int __exit ds3234_remove(struct spi_device *spi) -{ - struct ds3234 *chip = platform_get_drvdata(spi); - struct rtc_device *rtc = chip->rtc; - - if (rtc) - rtc_device_unregister(rtc); - - kfree(chip); - - return 0; -} - -static struct spi_driver ds3234_driver = { - .driver = { - .name = "ds3234", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = ds3234_probe, - .remove = __devexit_p(ds3234_remove), -}; - -static __init int ds3234_init(void) -{ - printk(KERN_INFO "DS3234 SPI RTC Driver\n"); - return spi_register_driver(&ds3234_driver); -} -module_init(ds3234_init); - -static __exit void ds3234_exit(void) -{ - spi_unregister_driver(&ds3234_driver); -} -module_exit(ds3234_exit); - -MODULE_DESCRIPTION("DS3234 SPI RTC driver"); -MODULE_AUTHOR("Dennis Aberilla "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-m41t80.c b/trunk/drivers/rtc/rtc-m41t80.c index 470fb2d29545..24bc1689fc74 100644 --- a/trunk/drivers/rtc/rtc-m41t80.c +++ b/trunk/drivers/rtc/rtc-m41t80.c @@ -56,27 +56,21 @@ #define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */ #define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */ #define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */ -#define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */ -#define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */ -#define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */ -#define M41T80_FEATURE_HT (1 << 0) /* Halt feature */ -#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */ -#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */ -#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */ +#define M41T80_FEATURE_HT (1 << 0) +#define M41T80_FEATURE_BL (1 << 1) #define DRV_VERSION "0.05" static const struct i2c_device_id m41t80_id[] = { - { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, - { "m41t80", M41T80_FEATURE_SQ }, - { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ}, - { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ }, - { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ }, - { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ }, - { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ }, - { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ }, - { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ }, + { "m41t80", 0 }, + { "m41t81", M41T80_FEATURE_HT }, + { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, + { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, + { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, + { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, + { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, + { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, { } }; MODULE_DEVICE_TABLE(i2c, m41t80_id); @@ -392,12 +386,8 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); - struct m41t80_data *clientdata = i2c_get_clientdata(client); int val; - if (!(clientdata->features & M41T80_FEATURE_SQ)) - return -EINVAL; - val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW); if (val < 0) return -EIO; @@ -418,13 +408,9 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); - struct m41t80_data *clientdata = i2c_get_clientdata(client); int almon, sqw; int val = simple_strtoul(buf, NULL, 0); - if (!(clientdata->features & M41T80_FEATURE_SQ)) - return -EINVAL; - if (val) { if (!is_power_of_2(val)) return -EINVAL; @@ -513,8 +499,6 @@ static void wdt_ping(void) .buf = i2c_data, }, }; - struct m41t80_data *clientdata = i2c_get_clientdata(save_client); - i2c_data[0] = 0x09; /* watchdog register */ if (wdt_margin > 31) @@ -525,13 +509,6 @@ static void wdt_ping(void) */ i2c_data[1] = wdt_margin<<2 | 0x82; - /* - * M41T65 has three bits for watchdog resolution. Don't set bit 7, as - * that would be an invalid resolution. - */ - if (clientdata->features & M41T80_FEATURE_WD) - i2c_data[1] &= ~M41T80_WATCHDOG_RB2; - i2c_transfer(save_client->adapter, msgs1, 1); } diff --git a/trunk/drivers/rtc/rtc-m48t35.c b/trunk/drivers/rtc/rtc-m48t35.c deleted file mode 100644 index 0b2197559940..000000000000 --- a/trunk/drivers/rtc/rtc-m48t35.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip - * - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * - * Copyright (C) 2008 Thomas Bogendoerfer - * - * Based on code written by Paul Gortmaker. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include - -#define DRV_VERSION "1.0" - -struct m48t35_rtc { - u8 pad[0x7ff8]; /* starts at 0x7ff8 */ - u8 control; - u8 sec; - u8 min; - u8 hour; - u8 day; - u8 date; - u8 month; - u8 year; -}; - -#define M48T35_RTC_SET 0x80 -#define M48T35_RTC_READ 0x40 - -struct m48t35_priv { - struct rtc_device *rtc; - struct m48t35_rtc __iomem *reg; - size_t size; - unsigned long baseaddr; - spinlock_t lock; -}; - -static int m48t35_read_time(struct device *dev, struct rtc_time *tm) -{ - struct m48t35_priv *priv = dev_get_drvdata(dev); - u8 control; - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - spin_lock_irq(&priv->lock); - control = readb(&priv->reg->control); - writeb(control | M48T35_RTC_READ, &priv->reg->control); - tm->tm_sec = readb(&priv->reg->sec); - tm->tm_min = readb(&priv->reg->min); - tm->tm_hour = readb(&priv->reg->hour); - tm->tm_mday = readb(&priv->reg->date); - tm->tm_mon = readb(&priv->reg->month); - tm->tm_year = readb(&priv->reg->year); - writeb(control, &priv->reg->control); - spin_unlock_irq(&priv->lock); - - tm->tm_sec = bcd2bin(tm->tm_sec); - tm->tm_min = bcd2bin(tm->tm_min); - tm->tm_hour = bcd2bin(tm->tm_hour); - tm->tm_mday = bcd2bin(tm->tm_mday); - tm->tm_mon = bcd2bin(tm->tm_mon); - tm->tm_year = bcd2bin(tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - tm->tm_year += 70; - if (tm->tm_year <= 69) - tm->tm_year += 100; - - tm->tm_mon--; - return rtc_valid_tm(tm); -} - -static int m48t35_set_time(struct device *dev, struct rtc_time *tm) -{ - struct m48t35_priv *priv = dev_get_drvdata(dev); - unsigned char mon, day, hrs, min, sec; - unsigned int yrs; - u8 control; - - yrs = tm->tm_year + 1900; - mon = tm->tm_mon + 1; /* tm_mon starts at zero */ - day = tm->tm_mday; - hrs = tm->tm_hour; - min = tm->tm_min; - sec = tm->tm_sec; - - if (yrs < 1970) - return -EINVAL; - - yrs -= 1970; - if (yrs > 255) /* They are unsigned */ - return -EINVAL; - - if (yrs > 169) - return -EINVAL; - - if (yrs >= 100) - yrs -= 100; - - sec = bin2bcd(sec); - min = bin2bcd(min); - hrs = bin2bcd(hrs); - day = bin2bcd(day); - mon = bin2bcd(mon); - yrs = bin2bcd(yrs); - - spin_lock_irq(&priv->lock); - control = readb(&priv->reg->control); - writeb(control | M48T35_RTC_SET, &priv->reg->control); - writeb(yrs, &priv->reg->year); - writeb(mon, &priv->reg->month); - writeb(day, &priv->reg->date); - writeb(hrs, &priv->reg->hour); - writeb(min, &priv->reg->min); - writeb(sec, &priv->reg->sec); - writeb(control, &priv->reg->control); - spin_unlock_irq(&priv->lock); - return 0; -} - -static const struct rtc_class_ops m48t35_ops = { - .read_time = m48t35_read_time, - .set_time = m48t35_set_time, -}; - -static int __devinit m48t35_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - struct resource *res; - struct m48t35_priv *priv; - int ret = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - priv = kzalloc(sizeof(struct m48t35_priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->size = res->end - res->start + 1; - /* - * kludge: remove the #ifndef after ioc3 resource - * conflicts are resolved - */ -#ifndef CONFIG_SGI_IP27 - if (!request_mem_region(res->start, priv->size, pdev->name)) { - ret = -EBUSY; - goto out; - } -#endif - priv->baseaddr = res->start; - priv->reg = ioremap(priv->baseaddr, priv->size); - if (!priv->reg) { - ret = -ENOMEM; - goto out; - } - spin_lock_init(&priv->lock); - rtc = rtc_device_register("m48t35", &pdev->dev, - &m48t35_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto out; - } - priv->rtc = rtc; - platform_set_drvdata(pdev, priv); - return 0; - -out: - if (priv->rtc) - rtc_device_unregister(priv->rtc); - if (priv->reg) - iounmap(priv->reg); - if (priv->baseaddr) - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return ret; -} - -static int __devexit m48t35_remove(struct platform_device *pdev) -{ - struct m48t35_priv *priv = platform_get_drvdata(pdev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->reg); -#ifndef CONFIG_SGI_IP27 - release_mem_region(priv->baseaddr, priv->size); -#endif - kfree(priv); - return 0; -} - -static struct platform_driver m48t35_platform_driver = { - .driver = { - .name = "rtc-m48t35", - .owner = THIS_MODULE, - }, - .probe = m48t35_probe, - .remove = __devexit_p(m48t35_remove), -}; - -static int __init m48t35_init(void) -{ - return platform_driver_register(&m48t35_platform_driver); -} - -static void __exit m48t35_exit(void) -{ - platform_driver_unregister(&m48t35_platform_driver); -} - -MODULE_AUTHOR("Thomas Bogendoerfer "); -MODULE_DESCRIPTION("M48T35 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); -MODULE_ALIAS("platform:rtc-m48t35"); - -module_init(m48t35_init); -module_exit(m48t35_exit); diff --git a/trunk/drivers/rtc/rtc-max6900.c b/trunk/drivers/rtc/rtc-max6900.c index 12c9cd25cad8..ded3c0abad83 100644 --- a/trunk/drivers/rtc/rtc-max6900.c +++ b/trunk/drivers/rtc/rtc-max6900.c @@ -17,18 +17,19 @@ #include #include -#define DRV_VERSION "0.2" +#define DRV_NAME "max6900" +#define DRV_VERSION "0.1" /* * register indices */ -#define MAX6900_REG_SC 0 /* seconds 00-59 */ -#define MAX6900_REG_MN 1 /* minutes 00-59 */ -#define MAX6900_REG_HR 2 /* hours 00-23 */ -#define MAX6900_REG_DT 3 /* day of month 00-31 */ -#define MAX6900_REG_MO 4 /* month 01-12 */ -#define MAX6900_REG_DW 5 /* day of week 1-7 */ -#define MAX6900_REG_YR 6 /* year 00-99 */ +#define MAX6900_REG_SC 0 /* seconds 00-59 */ +#define MAX6900_REG_MN 1 /* minutes 00-59 */ +#define MAX6900_REG_HR 2 /* hours 00-23 */ +#define MAX6900_REG_DT 3 /* day of month 00-31 */ +#define MAX6900_REG_MO 4 /* month 01-12 */ +#define MAX6900_REG_DW 5 /* day of week 1-7 */ +#define MAX6900_REG_YR 6 /* year 00-99 */ #define MAX6900_REG_CT 7 /* control */ /* register 8 is undocumented */ #define MAX6900_REG_CENTURY 9 /* century */ @@ -38,6 +39,7 @@ #define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */ + /* * register read/write commands */ @@ -50,7 +52,16 @@ #define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ -static struct i2c_driver max6900_driver; +#define MAX6900_I2C_ADDR 0xa0 + +static const unsigned short normal_i2c[] = { + MAX6900_I2C_ADDR >> 1, + I2C_CLIENT_END +}; + +I2C_CLIENT_INSMOD; /* defines addr_data */ + +static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind); static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf) { @@ -58,35 +69,36 @@ static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf) u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ }; struct i2c_msg msgs[4] = { { - .addr = client->addr, - .flags = 0, /* write */ - .len = sizeof(reg_burst_read), - .buf = reg_burst_read} - , + .addr = client->addr, + .flags = 0, /* write */ + .len = sizeof(reg_burst_read), + .buf = reg_burst_read + }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = MAX6900_BURST_LEN, - .buf = buf} - , + .addr = client->addr, + .flags = I2C_M_RD, + .len = MAX6900_BURST_LEN, + .buf = buf + }, { - .addr = client->addr, - .flags = 0, /* write */ - .len = sizeof(reg_century_read), - .buf = reg_century_read} - , + .addr = client->addr, + .flags = 0, /* write */ + .len = sizeof(reg_century_read), + .buf = reg_century_read + }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = sizeof(buf[MAX6900_REG_CENTURY]), - .buf = &buf[MAX6900_REG_CENTURY] - } + .addr = client->addr, + .flags = I2C_M_RD, + .len = sizeof(buf[MAX6900_REG_CENTURY]), + .buf = &buf[MAX6900_REG_CENTURY] + } }; int rc; rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); if (rc != ARRAY_SIZE(msgs)) { - dev_err(&client->dev, "%s: register read failed\n", __func__); + dev_err(&client->dev, "%s: register read failed\n", + __func__); return -EIO; } return 0; @@ -97,18 +109,20 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE }; struct i2c_msg century_msgs[1] = { { - .addr = client->addr, - .flags = 0, /* write */ - .len = sizeof(i2c_century_buf), - .buf = i2c_century_buf} + .addr = client->addr, + .flags = 0, /* write */ + .len = sizeof(i2c_century_buf), + .buf = i2c_century_buf + } }; u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE }; struct i2c_msg burst_msgs[1] = { { - .addr = client->addr, - .flags = 0, /* write */ - .len = sizeof(i2c_burst_buf), - .buf = i2c_burst_buf} + .addr = client->addr, + .flags = 0, /* write */ + .len = sizeof(i2c_burst_buf), + .buf = i2c_burst_buf + } }; int rc; @@ -119,12 +133,10 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) * bit as part of the burst write. */ i2c_century_buf[1] = buf[MAX6900_REG_CENTURY]; - rc = i2c_transfer(client->adapter, century_msgs, ARRAY_SIZE(century_msgs)); if (rc != ARRAY_SIZE(century_msgs)) goto write_failed; - msleep(MAX6900_IDLE_TIME_AFTER_WRITE); memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN); @@ -136,11 +148,45 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) return 0; - write_failed: - dev_err(&client->dev, "%s: register write failed\n", __func__); +write_failed: + dev_err(&client->dev, "%s: register write failed\n", + __func__); return -EIO; } +static int max6900_i2c_validate_client(struct i2c_client *client) +{ + u8 regs[MAX6900_REG_LEN]; + u8 zero_mask[] = { + 0x80, /* seconds */ + 0x80, /* minutes */ + 0x40, /* hours */ + 0xc0, /* day of month */ + 0xe0, /* month */ + 0xf8, /* day of week */ + 0x00, /* year */ + 0x7f, /* control */ + }; + int i; + int rc; + int reserved; + + reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ); + if (reserved != 0x07) + return -ENODEV; + + rc = max6900_i2c_read_regs(client, regs); + if (rc < 0) + return rc; + + for (i = 0; i < ARRAY_SIZE(zero_mask); ++i) { + if (regs[i] & zero_mask[i]) + return -ENODEV; + } + + return 0; +} + static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) { int rc; @@ -156,7 +202,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]); tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1; tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + - BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900; + BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900; tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]); return 0; @@ -165,7 +211,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) static int max6900_i2c_clear_write_protect(struct i2c_client *client) { int rc; - rc = i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0); + rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0); if (rc < 0) { dev_err(&client->dev, "%s: control register write failed\n", __func__); @@ -174,8 +220,8 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client) return 0; } -static int -max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) +static int max6900_i2c_set_time(struct i2c_client *client, + struct rtc_time const *tm) { u8 regs[MAX6900_REG_LEN]; int rc; @@ -212,48 +258,88 @@ static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm) return max6900_i2c_set_time(to_i2c_client(dev), tm); } -static int max6900_remove(struct i2c_client *client) +static int max6900_attach_adapter(struct i2c_adapter *adapter) +{ + return i2c_probe(adapter, &addr_data, max6900_probe); +} + +static int max6900_detach_client(struct i2c_client *client) { - struct rtc_device *rtc = i2c_get_clientdata(client); + struct rtc_device *const rtc = i2c_get_clientdata(client); if (rtc) rtc_device_unregister(rtc); - return 0; + return i2c_detach_client(client); } +static struct i2c_driver max6900_driver = { + .driver = { + .name = DRV_NAME, + }, + .id = I2C_DRIVERID_MAX6900, + .attach_adapter = max6900_attach_adapter, + .detach_client = max6900_detach_client, +}; + static const struct rtc_class_ops max6900_rtc_ops = { - .read_time = max6900_rtc_read_time, - .set_time = max6900_rtc_set_time, + .read_time = max6900_rtc_read_time, + .set_time = max6900_rtc_set_time, }; -static int -max6900_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind) { - struct rtc_device *rtc; + int rc = 0; + struct i2c_client *client = NULL; + struct rtc_device *rtc = NULL; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - return -ENODEV; + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + rc = -ENODEV; + goto failout; + } + + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == NULL) { + rc = -ENOMEM; + goto failout; + } + + client->addr = addr; + client->adapter = adapter; + client->driver = &max6900_driver; + strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE); + + if (kind < 0) { + rc = max6900_i2c_validate_client(client); + if (rc < 0) + goto failout; + } + + rc = i2c_attach_client(client); + if (rc < 0) + goto failout; - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + dev_info(&client->dev, + "chip found, driver version " DRV_VERSION "\n"); rtc = rtc_device_register(max6900_driver.driver.name, - &client->dev, &max6900_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + &client->dev, + &max6900_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) { + rc = PTR_ERR(rtc); + goto failout_detach; + } i2c_set_clientdata(client, rtc); return 0; -} -static struct i2c_driver max6900_driver = { - .driver = { - .name = "rtc-max6900", - }, - .probe = max6900_probe, - .remove = max6900_remove, -}; +failout_detach: + i2c_detach_client(client); +failout: + kfree(client); + return rc; +} static int __init max6900_init(void) { @@ -266,7 +352,6 @@ static void __exit max6900_exit(void) } MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); -MODULE_AUTHOR("Dale Farnsworth "); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/rtc/rtc-pcf8563.c b/trunk/drivers/rtc/rtc-pcf8563.c index a829f20ad6d6..748a502a6355 100644 --- a/trunk/drivers/rtc/rtc-pcf8563.c +++ b/trunk/drivers/rtc/rtc-pcf8563.c @@ -179,6 +179,58 @@ struct pcf8563_limit unsigned char max; }; +static int pcf8563_validate_client(struct i2c_client *client) +{ + int i; + + static const struct pcf8563_limit pattern[] = { + /* register, mask, min, max */ + { PCF8563_REG_SC, 0x7F, 0, 59 }, + { PCF8563_REG_MN, 0x7F, 0, 59 }, + { PCF8563_REG_HR, 0x3F, 0, 23 }, + { PCF8563_REG_DM, 0x3F, 0, 31 }, + { PCF8563_REG_MO, 0x1F, 0, 12 }, + }; + + /* check limits (only registers with bcd values) */ + for (i = 0; i < ARRAY_SIZE(pattern); i++) { + int xfer; + unsigned char value; + unsigned char buf = pattern[i].reg; + + struct i2c_msg msgs[] = { + { client->addr, 0, 1, &buf }, + { client->addr, I2C_M_RD, 1, &buf }, + }; + + xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + + if (xfer != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, + "%s: could not read register 0x%02X\n", + __func__, pattern[i].reg); + + return -EIO; + } + + value = BCD2BIN(buf & pattern[i].mask); + + if (value > pattern[i].max || + value < pattern[i].min) { + dev_dbg(&client->dev, + "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, " + "max=%d, value=%d, raw=0x%02X\n", + __func__, i, pattern[i].reg, pattern[i].mask, + pattern[i].min, pattern[i].max, + value, buf); + + return -ENODEV; + } + } + + return 0; +} + static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) { return pcf8563_get_datetime(to_i2c_client(dev), tm); @@ -210,6 +262,12 @@ static int pcf8563_probe(struct i2c_client *client, if (!pcf8563) return -ENOMEM; + /* Verify the chip is really an PCF8563 */ + if (pcf8563_validate_client(client) < 0) { + err = -ENODEV; + goto exit_kfree; + } + dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name, diff --git a/trunk/drivers/rtc/rtc-pl030.c b/trunk/drivers/rtc/rtc-pl030.c index 826153552157..8448eeb9d675 100644 --- a/trunk/drivers/rtc/rtc-pl030.c +++ b/trunk/drivers/rtc/rtc-pl030.c @@ -34,6 +34,15 @@ static irqreturn_t pl030_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static int pl030_open(struct device *dev) +{ + return 0; +} + +static void pl030_release(struct device *dev) +{ +} + static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; @@ -95,6 +104,8 @@ static int pl030_set_time(struct device *dev, struct rtc_time *tm) } static const struct rtc_class_ops pl030_ops = { + .open = pl030_open, + .release = pl030_release, .ioctl = pl030_ioctl, .read_time = pl030_read_time, .set_time = pl030_set_time, diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index 333eec689d2f..08b4610ec5a6 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -45,6 +45,18 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static int pl031_open(struct device *dev) +{ + /* + * We request IRQ in pl031_probe, so nothing to do here... + */ + return 0; +} + +static void pl031_release(struct device *dev) +{ +} + static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct pl031_local *ldata = dev_get_drvdata(dev); @@ -106,6 +118,8 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) } static const struct rtc_class_ops pl031_ops = { + .open = pl031_open, + .release = pl031_release, .ioctl = pl031_ioctl, .read_time = pl031_read_time, .set_time = pl031_set_time, diff --git a/trunk/drivers/rtc/rtc-rs5c372.c b/trunk/drivers/rtc/rtc-rs5c372.c index 8b561958fb1e..56caf6b2c3e5 100644 --- a/trunk/drivers/rtc/rtc-rs5c372.c +++ b/trunk/drivers/rtc/rtc-rs5c372.c @@ -1,9 +1,8 @@ /* - * An I2C driver for Ricoh RS5C372, R2025S/D and RV5C38[67] RTCs + * An I2C driver for Ricoh RS5C372 and RV5C38[67] RTCs * * Copyright (C) 2005 Pavel Mironchik * Copyright (C) 2006 Tower Technologies - * Copyright (C) 2008 Paul Mundt * * 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 @@ -14,7 +13,7 @@ #include #include -#define DRV_VERSION "0.6" +#define DRV_VERSION "0.5" /* @@ -52,8 +51,7 @@ # define RS5C_CTRL1_CT4 (4 << 0) /* 1 Hz level irq */ #define RS5C_REG_CTRL2 15 # define RS5C372_CTRL2_24 (1 << 5) -# define R2025_CTRL2_XST (1 << 5) -# define RS5C_CTRL2_XSTP (1 << 4) /* only if !R2025S/D */ +# define RS5C_CTRL2_XSTP (1 << 4) # define RS5C_CTRL2_CTFG (1 << 2) # define RS5C_CTRL2_AAFG (1 << 1) /* or WAFG */ # define RS5C_CTRL2_BAFG (1 << 0) /* or DAFG */ @@ -65,7 +63,6 @@ enum rtc_type { rtc_undef = 0, - rtc_r2025sd, rtc_rs5c372a, rtc_rs5c372b, rtc_rv5c386, @@ -73,7 +70,6 @@ enum rtc_type { }; static const struct i2c_device_id rs5c372_id[] = { - { "r2025sd", rtc_r2025sd }, { "rs5c372a", rtc_rs5c372a }, { "rs5c372b", rtc_rs5c372b }, { "rv5c386", rtc_rv5c386 }, @@ -93,7 +89,6 @@ struct rs5c372 { enum rtc_type type; unsigned time24:1; unsigned has_irq:1; - unsigned smbus:1; char buf[17]; char *regs; }; @@ -111,25 +106,10 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) * * The first method doesn't work with the iop3xx adapter driver, on at * least 80219 chips; this works around that bug. - * - * The third method on the other hand doesn't work for the SMBus-only - * configurations, so we use the the first method there, stripping off - * the extra register in the process. */ - if (rs5c->smbus) { - int addr = RS5C_ADDR(RS5C372_REG_SECS); - int size = sizeof(rs5c->buf) - 1; - - if (i2c_smbus_read_i2c_block_data(client, addr, size, - rs5c->buf + 1) != size) { - dev_warn(&client->dev, "can't read registers\n"); - return -EIO; - } - } else { - if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { - dev_warn(&client->dev, "can't read registers\n"); - return -EIO; - } + if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { + dev_warn(&client->dev, "can't read registers\n"); + return -EIO; } dev_dbg(&client->dev, @@ -207,7 +187,6 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) { struct rs5c372 *rs5c = i2c_get_clientdata(client); unsigned char buf[8]; - int addr; dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " "mday=%d, mon=%d, year=%d, wday=%d\n", @@ -215,16 +194,16 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - addr = RS5C_ADDR(RS5C372_REG_SECS); - buf[0] = BIN2BCD(tm->tm_sec); - buf[1] = BIN2BCD(tm->tm_min); - buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour); - buf[3] = BIN2BCD(tm->tm_wday); - buf[4] = BIN2BCD(tm->tm_mday); - buf[5] = BIN2BCD(tm->tm_mon + 1); - buf[6] = BIN2BCD(tm->tm_year - 100); + buf[0] = RS5C_ADDR(RS5C372_REG_SECS); + buf[1] = BIN2BCD(tm->tm_sec); + buf[2] = BIN2BCD(tm->tm_min); + buf[3] = rs5c_hr2reg(rs5c, tm->tm_hour); + buf[4] = BIN2BCD(tm->tm_wday); + buf[5] = BIN2BCD(tm->tm_mday); + buf[6] = BIN2BCD(tm->tm_mon + 1); + buf[7] = BIN2BCD(tm->tm_year - 100); - if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) { + if ((i2c_master_send(client, buf, 8)) != 8) { dev_err(&client->dev, "%s: write error\n", __func__); return -EIO; } @@ -287,16 +266,16 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct i2c_client *client = to_i2c_client(dev); struct rs5c372 *rs5c = i2c_get_clientdata(client); - unsigned char buf; - int status, addr; + unsigned char buf[2]; + int status; - buf = rs5c->regs[RS5C_REG_CTRL1]; + buf[1] = rs5c->regs[RS5C_REG_CTRL1]; switch (cmd) { case RTC_UIE_OFF: case RTC_UIE_ON: /* some 327a modes use a different IRQ pin for 1Hz irqs */ if (rs5c->type == rtc_rs5c372a - && (buf & RS5C372A_CTRL1_SL1)) + && (buf[1] & RS5C372A_CTRL1_SL1)) return -ENOIOCTLCMD; case RTC_AIE_OFF: case RTC_AIE_ON: @@ -314,30 +293,28 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) if (status < 0) return status; - addr = RS5C_ADDR(RS5C_REG_CTRL1); + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); switch (cmd) { case RTC_AIE_OFF: /* alarm off */ - buf &= ~RS5C_CTRL1_AALE; + buf[1] &= ~RS5C_CTRL1_AALE; break; case RTC_AIE_ON: /* alarm on */ - buf |= RS5C_CTRL1_AALE; + buf[1] |= RS5C_CTRL1_AALE; break; case RTC_UIE_OFF: /* update off */ - buf &= ~RS5C_CTRL1_CT_MASK; + buf[1] &= ~RS5C_CTRL1_CT_MASK; break; case RTC_UIE_ON: /* update on */ - buf &= ~RS5C_CTRL1_CT_MASK; - buf |= RS5C_CTRL1_CT4; + buf[1] &= ~RS5C_CTRL1_CT_MASK; + buf[1] |= RS5C_CTRL1_CT4; break; } - - if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { + if ((i2c_master_send(client, buf, 2)) != 2) { printk(KERN_WARNING "%s: can't update alarm\n", rs5c->rtc->name); status = -EIO; } else - rs5c->regs[RS5C_REG_CTRL1] = buf; - + rs5c->regs[RS5C_REG_CTRL1] = buf[1]; return status; } @@ -387,8 +364,8 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) { struct i2c_client *client = to_i2c_client(dev); struct rs5c372 *rs5c = i2c_get_clientdata(client); - int status, addr, i; - unsigned char buf[3]; + int status; + unsigned char buf[4]; /* only handle up to 24 hours in the future, like RTC_ALM_SET */ if (t->time.tm_mday != -1 @@ -403,36 +380,33 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) if (status < 0) return status; if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) { - addr = RS5C_ADDR(RS5C_REG_CTRL1); - buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; - if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) { + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); + buf[1] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; + if (i2c_master_send(client, buf, 2) != 2) { pr_debug("%s: can't disable alarm\n", rs5c->rtc->name); return -EIO; } - rs5c->regs[RS5C_REG_CTRL1] = buf[0]; + rs5c->regs[RS5C_REG_CTRL1] = buf[1]; } /* set alarm */ - buf[0] = BIN2BCD(t->time.tm_min); - buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); - buf[2] = 0x7f; /* any/all days */ - - for (i = 0; i < sizeof(buf); i++) { - addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); - if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) { - pr_debug("%s: can't set alarm time\n", rs5c->rtc->name); - return -EIO; - } + buf[0] = RS5C_ADDR(RS5C_REG_ALARM_A_MIN); + buf[1] = BIN2BCD(t->time.tm_min); + buf[2] = rs5c_hr2reg(rs5c, t->time.tm_hour); + buf[3] = 0x7f; /* any/all days */ + if ((i2c_master_send(client, buf, 4)) != 4) { + pr_debug("%s: can't set alarm time\n", rs5c->rtc->name); + return -EIO; } /* ... and maybe enable its irq */ if (t->enabled) { - addr = RS5C_ADDR(RS5C_REG_CTRL1); - buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; - if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); + buf[1] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; + if ((i2c_master_send(client, buf, 2)) != 2) printk(KERN_WARNING "%s: can't enable alarm\n", rs5c->rtc->name); - rs5c->regs[RS5C_REG_CTRL1] = buf[0]; + rs5c->regs[RS5C_REG_CTRL1] = buf[1]; } return 0; @@ -529,81 +503,18 @@ static void rs5c_sysfs_unregister(struct device *dev) static struct i2c_driver rs5c372_driver; -static int rs5c_oscillator_setup(struct rs5c372 *rs5c372) -{ - unsigned char buf[2]; - int addr, i, ret = 0; - - if (rs5c372->type == rtc_r2025sd) { - if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST)) - return ret; - rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST; - } else { - if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP)) - return ret; - rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP; - } - - addr = RS5C_ADDR(RS5C_REG_CTRL1); - buf[0] = rs5c372->regs[RS5C_REG_CTRL1]; - buf[1] = rs5c372->regs[RS5C_REG_CTRL2]; - - /* use 24hr mode */ - switch (rs5c372->type) { - case rtc_rs5c372a: - case rtc_rs5c372b: - buf[1] |= RS5C372_CTRL2_24; - rs5c372->time24 = 1; - break; - case rtc_r2025sd: - case rtc_rv5c386: - case rtc_rv5c387a: - buf[0] |= RV5C387_CTRL1_24; - rs5c372->time24 = 1; - break; - default: - /* impossible */ - break; - } - - for (i = 0; i < sizeof(buf); i++) { - addr = RS5C_ADDR(RS5C_REG_CTRL1 + i); - ret = i2c_smbus_write_byte_data(rs5c372->client, addr, buf[i]); - if (unlikely(ret < 0)) - return ret; - } - - rs5c372->regs[RS5C_REG_CTRL1] = buf[0]; - rs5c372->regs[RS5C_REG_CTRL2] = buf[1]; - - return 0; -} - static int rs5c372_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; - int smbus_mode = 0; struct rs5c372 *rs5c372; struct rtc_time tm; dev_dbg(&client->dev, "%s\n", __func__); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) { - /* - * If we don't have any master mode adapter, try breaking - * it down in to the barest of capabilities. - */ - if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) - smbus_mode = 1; - else { - /* Still no good, give up */ - err = -ENODEV; - goto exit; - } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; + goto exit; } if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) { @@ -617,7 +528,6 @@ static int rs5c372_probe(struct i2c_client *client, /* we read registers 0x0f then 0x00-0x0f; skip the first one */ rs5c372->regs = &rs5c372->buf[1]; - rs5c372->smbus = smbus_mode; err = rs5c_get_regs(rs5c372); if (err < 0) @@ -633,7 +543,6 @@ static int rs5c372_probe(struct i2c_client *client, if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24) rs5c372->time24 = 1; break; - case rtc_r2025sd: case rtc_rv5c386: case rtc_rv5c387a: if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24) @@ -649,14 +558,39 @@ static int rs5c372_probe(struct i2c_client *client, /* if the oscillator lost power and no other software (like * the bootloader) set it up, do it here. - * - * The R2025S/D does this a little differently than the other - * parts, so we special case that.. */ - err = rs5c_oscillator_setup(rs5c372); - if (unlikely(err < 0)) { - dev_err(&client->dev, "setup error\n"); - goto exit_kfree; + if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP) { + unsigned char buf[3]; + + rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP; + + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); + buf[1] = rs5c372->regs[RS5C_REG_CTRL1]; + buf[2] = rs5c372->regs[RS5C_REG_CTRL2]; + + /* use 24hr mode */ + switch (rs5c372->type) { + case rtc_rs5c372a: + case rtc_rs5c372b: + buf[2] |= RS5C372_CTRL2_24; + rs5c372->time24 = 1; + break; + case rtc_rv5c386: + case rtc_rv5c387a: + buf[1] |= RV5C387_CTRL1_24; + rs5c372->time24 = 1; + break; + default: + /* impossible */ + break; + } + + if ((i2c_master_send(client, buf, 3)) != 3) { + dev_err(&client->dev, "setup error\n"); + goto exit_kfree; + } + rs5c372->regs[RS5C_REG_CTRL1] = buf[1]; + rs5c372->regs[RS5C_REG_CTRL2] = buf[2]; } if (rs5c372_get_datetime(client, &tm) < 0) @@ -664,7 +598,6 @@ static int rs5c372_probe(struct i2c_client *client, dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n", ({ char *s; switch (rs5c372->type) { - case rtc_r2025sd: s = "r2025sd"; break; case rtc_rs5c372a: s = "rs5c372a"; break; case rtc_rs5c372b: s = "rs5c372b"; break; case rtc_rv5c386: s = "rv5c386"; break; @@ -734,8 +667,7 @@ module_exit(rs5c372_exit); MODULE_AUTHOR( "Pavel Mironchik , " - "Alessandro Zummo , " - "Paul Mundt "); + "Alessandro Zummo "); MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/rtc/rtc-sh.c b/trunk/drivers/rtc/rtc-sh.c index fcead4c4cd1f..1f88e9e914ec 100644 --- a/trunk/drivers/rtc/rtc-sh.c +++ b/trunk/drivers/rtc/rtc-sh.c @@ -257,6 +257,12 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) spin_unlock_irq(&rtc->lock); } +static void sh_rtc_release(struct device *dev) +{ + sh_rtc_setpie(dev, 0); + sh_rtc_setaie(dev, 0); +} + static int sh_rtc_proc(struct device *dev, struct seq_file *seq) { struct sh_rtc *rtc = dev_get_drvdata(dev); @@ -553,6 +559,7 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq) } static struct rtc_class_ops sh_rtc_ops = { + .release = sh_rtc_release, .ioctl = sh_rtc_ioctl, .read_time = sh_rtc_read_time, .set_time = sh_rtc_set_time, diff --git a/trunk/drivers/rtc/rtc-stk17ta8.c b/trunk/drivers/rtc/rtc-stk17ta8.c index 9a7e920315fa..31d3c8c28588 100644 --- a/trunk/drivers/rtc/rtc-stk17ta8.c +++ b/trunk/drivers/rtc/rtc-stk17ta8.c @@ -215,6 +215,17 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static void stk17ta8_rtc_release(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + + if (pdata->irq >= 0) { + pdata->irqen = 0; + stk17ta8_rtc_update_alarm(pdata); + } +} + static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { @@ -243,6 +254,7 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = { .set_time = stk17ta8_rtc_set_time, .read_alarm = stk17ta8_rtc_read_alarm, .set_alarm = stk17ta8_rtc_set_alarm, + .release = stk17ta8_rtc_release, .ioctl = stk17ta8_rtc_ioctl, }; diff --git a/trunk/drivers/s390/char/fs3270.c b/trunk/drivers/s390/char/fs3270.c index 40759c33477d..d18e6d2e0b49 100644 --- a/trunk/drivers/s390/char/fs3270.c +++ b/trunk/drivers/s390/char/fs3270.c @@ -418,22 +418,25 @@ fs3270_open(struct inode *inode, struct file *filp) { struct fs3270 *fp; struct idal_buffer *ib; - int minor, rc = 0; + int minor, rc; if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR) return -ENODEV; + lock_kernel(); minor = iminor(filp->f_path.dentry->d_inode); /* Check for minor 0 multiplexer. */ if (minor == 0) { - struct tty_struct *tty = get_current_tty(); + struct tty_struct *tty; + mutex_lock(&tty_mutex); + tty = get_current_tty(); if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { - tty_kref_put(tty); - return -ENODEV; + mutex_unlock(&tty_mutex); + rc = -ENODEV; + goto out; } minor = tty->index + RAW3270_FIRSTMINOR; - tty_kref_put(tty); + mutex_unlock(&tty_mutex); } - lock_kernel(); /* Check if some other program is already using fullscreen mode. */ fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); if (!IS_ERR(fp)) { @@ -475,7 +478,7 @@ fs3270_open(struct inode *inode, struct file *filp) filp->private_data = fp; out: unlock_kernel(); - return rc; + return 0; } /* diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 0b15cf107ec9..1792b2c0130e 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -1168,17 +1168,19 @@ static int raw3270_create_attributes(struct raw3270 *rp) if (rc) goto out; - rp->clttydev = device_create(class3270, &rp->cdev->dev, - MKDEV(IBM_TTY3270_MAJOR, rp->minor), NULL, - "tty%s", dev_name(&rp->cdev->dev)); + rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev, + MKDEV(IBM_TTY3270_MAJOR, rp->minor), + NULL, + "tty%s", dev_name(&rp->cdev->dev)); if (IS_ERR(rp->clttydev)) { rc = PTR_ERR(rp->clttydev); goto out_ttydev; } - rp->cltubdev = device_create(class3270, &rp->cdev->dev, - MKDEV(IBM_FS3270_MAJOR, rp->minor), NULL, - "tub%s", dev_name(&rp->cdev->dev)); + rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev, + MKDEV(IBM_FS3270_MAJOR, rp->minor), + NULL, + "tub%s", dev_name(&rp->cdev->dev)); if (!IS_ERR(rp->cltubdev)) goto out; diff --git a/trunk/drivers/s390/char/tape_class.c b/trunk/drivers/s390/char/tape_class.c index ddc914ccea8f..12c2a5aaf31b 100644 --- a/trunk/drivers/s390/char/tape_class.c +++ b/trunk/drivers/s390/char/tape_class.c @@ -69,9 +69,9 @@ struct tape_class_device *register_tape_dev( if (rc) goto fail_with_cdev; - tcd->class_device = device_create(tape_class, device, - tcd->char_device->dev, NULL, - "%s", tcd->device_name); + tcd->class_device = device_create_drvdata(tape_class, device, + tcd->char_device->dev, + NULL, "%s", tcd->device_name); rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0; if (rc) goto fail_with_cdev; diff --git a/trunk/drivers/s390/char/vmlogrdr.c b/trunk/drivers/s390/char/vmlogrdr.c index 24762727bc27..42173cc34610 100644 --- a/trunk/drivers/s390/char/vmlogrdr.c +++ b/trunk/drivers/s390/char/vmlogrdr.c @@ -747,10 +747,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) device_unregister(dev); return ret; } - priv->class_device = device_create(vmlogrdr_class, dev, - MKDEV(vmlogrdr_major, - priv->minor_num), - priv, "%s", dev_name(dev)); + priv->class_device = device_create_drvdata(vmlogrdr_class, dev, + MKDEV(vmlogrdr_major, + priv->minor_num), + priv, "%s", dev_name(dev)); if (IS_ERR(priv->class_device)) { ret = PTR_ERR(priv->class_device); priv->class_device=NULL; diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index 9020eba620ee..6fdfa5ddeca8 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -896,8 +896,9 @@ static int ur_set_online(struct ccw_device *cdev) goto fail_free_cdev; } - urd->device = device_create(vmur_class, NULL, urd->char_device->dev, - NULL, "%s", node_id); + urd->device = device_create_drvdata(vmur_class, NULL, + urd->char_device->dev, NULL, + "%s", node_id); if (IS_ERR(urd->device)) { rc = PTR_ERR(urd->device); TRACE("ur_set_online: device_create rc=%d\n", rc); diff --git a/trunk/drivers/s390/net/claw.c b/trunk/drivers/s390/net/claw.c index f5e618562c5f..8f83fc994f50 100644 --- a/trunk/drivers/s390/net/claw.c +++ b/trunk/drivers/s390/net/claw.c @@ -2913,7 +2913,7 @@ claw_new_device(struct ccwgroup_device *cgdev) if (ret != 0) { printk(KERN_WARNING "claw: ccw_device_set_online %s WRITE failed " - "with ret = %d\n", dev_name(&cgdev->cdev[WRITE]->dev), + "with ret = %d\n", dev_name(&cgdev->cdev[WRITE]->dev) ret); goto out; } diff --git a/trunk/drivers/s390/net/ctcm_mpc.c b/trunk/drivers/s390/net/ctcm_mpc.c index 19f5d5ed85e0..cbe470493bf0 100644 --- a/trunk/drivers/s390/net/ctcm_mpc.c +++ b/trunk/drivers/s390/net/ctcm_mpc.c @@ -1673,7 +1673,7 @@ static int mpc_validate_xid(struct mpcg_info *mpcginfo) done: if (rc) { - ctcm_pr_info("ctcmpc : %s() failed\n", __func__); + ctcm_pr_info("ctcmpc : %s() failed\n", __FUNCTION__); priv->xid->xid2_flag2 = 0x40; grp->saved_xid2->xid2_flag2 = 0x40; } diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 403ecad48d4b..d3b211af4e1c 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -1640,7 +1640,6 @@ config ATARI_SCSI tristate "Atari native SCSI support" depends on ATARI && SCSI select SCSI_SPI_ATTRS - select NVRAM ---help--- If you have an Atari with built-in NCR5380 SCSI controller (TT, Falcon, ...) say Y to get it supported. Of course also, if you have @@ -1671,6 +1670,14 @@ config ATARI_SCSI_RESET_BOOT boot process fractionally longer but may assist recovery from errors that leave the devices with SCSI operations partway completed. +config TT_DMA_EMUL + bool "Hades SCSI DMA emulator" + depends on ATARI_SCSI && HADES + help + This option enables code which emulates the TT SCSI DMA chip on the + Hades. This increases the SCSI transfer rates at least ten times + compared to PIO transfers. + config MAC_SCSI bool "Macintosh NCR5380 SCSI" depends on MAC && SCSI=y diff --git a/trunk/drivers/scsi/atari_dma_emul.c b/trunk/drivers/scsi/atari_dma_emul.c new file mode 100644 index 000000000000..cdc710ea00fa --- /dev/null +++ b/trunk/drivers/scsi/atari_dma_emul.c @@ -0,0 +1,468 @@ +/* + * atari_dma_emul.c -- TT SCSI DMA emulator for the Hades. + * + * Copyright 1997 Wout Klaren + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * This code was written using the Hades TOS source code as a + * reference. This source code can be found on the home page + * of Medusa Computer Systems. + * + * Version 0.1, 1997-09-24. + * + * This code should be considered experimental. It has only been + * tested on a Hades with a 68060. It might not work on a Hades + * with a 68040. Make backups of your hard drives before using + * this code. + */ + +#include +#include +#include + +#define hades_dma_ctrl (*(unsigned char *) 0xffff8717) +#define hades_psdm_reg (*(unsigned char *) 0xffff8741) + +#define TRANSFER_SIZE 16 + +struct m68040_frame { + unsigned long effaddr; /* effective address */ + unsigned short ssw; /* special status word */ + unsigned short wb3s; /* write back 3 status */ + unsigned short wb2s; /* write back 2 status */ + unsigned short wb1s; /* write back 1 status */ + unsigned long faddr; /* fault address */ + unsigned long wb3a; /* write back 3 address */ + unsigned long wb3d; /* write back 3 data */ + unsigned long wb2a; /* write back 2 address */ + unsigned long wb2d; /* write back 2 data */ + unsigned long wb1a; /* write back 1 address */ + unsigned long wb1dpd0; /* write back 1 data/push data 0*/ + unsigned long pd1; /* push data 1*/ + unsigned long pd2; /* push data 2*/ + unsigned long pd3; /* push data 3*/ +}; + +static void writeback (unsigned short wbs, unsigned long wba, + unsigned long wbd, void *old_buserr) +{ + mm_segment_t fs = get_fs(); + static void *save_buserr; + + __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t" + "move.l %0,8(%%a0)\n\t" + : + : "r" (&&bus_error) + : "a0" ); + + save_buserr = old_buserr; + + set_fs (MAKE_MM_SEG(wbs & WBTM_040)); + + switch (wbs & WBSIZ_040) { + case BA_SIZE_BYTE: + put_user (wbd & 0xff, (char *)wba); + break; + case BA_SIZE_WORD: + put_user (wbd & 0xffff, (short *)wba); + break; + case BA_SIZE_LONG: + put_user (wbd, (int *)wba); + break; + } + + set_fs (fs); + return; + +bus_error: + __asm__ __volatile__ ("cmp.l %0,2(%%sp)\n\t" + "bcs.s .jump_old\n\t" + "cmp.l %1,2(%%sp)\n\t" + "bls.s .restore_old\n" + ".jump_old:\n\t" + "move.l %2,-(%%sp)\n\t" + "rts\n" + ".restore_old:\n\t" + "move.l %%a0,-(%%sp)\n\t" + "movec.l %%vbr,%%a0\n\t" + "move.l %2,8(%%a0)\n\t" + "move.l (%%sp)+,%%a0\n\t" + "rte\n\t" + : + : "i" (writeback), "i" (&&bus_error), + "m" (save_buserr) ); +} + +/* + * static inline void set_restdata_reg(unsigned char *cur_addr) + * + * Set the rest data register if necessary. + */ + +static inline void set_restdata_reg(unsigned char *cur_addr) +{ + if (((long) cur_addr & ~3) != 0) + tt_scsi_dma.dma_restdata = + *((unsigned long *) ((long) cur_addr & ~3)); +} + +/* + * void hades_dma_emulator(int irq, void *dummy) + * + * This code emulates TT SCSI DMA on the Hades. + * + * Note the following: + * + * 1. When there is no byte available to read from the SCSI bus, or + * when a byte cannot yet bet written to the SCSI bus, a bus + * error occurs when reading or writing the pseudo DMA data + * register (hades_psdm_reg). We have to catch this bus error + * and try again to read or write the byte. If after several tries + * we still get a bus error, the interrupt handler is left. When + * the byte can be read or written, the interrupt handler is + * called again. + * + * 2. The SCSI interrupt must be disabled in this interrupt handler. + * + * 3. If we set the EOP signal, the SCSI controller still expects one + * byte to be read or written. Therefore the last byte is transferred + * separately, after setting the EOP signal. + * + * 4. When this function is left, the address pointer (start_addr) is + * converted to a physical address. Because it points one byte + * further than the last transferred byte, it can point outside the + * current page. If virt_to_phys() is called with this address we + * might get an access error. Therefore virt_to_phys() is called with + * start_addr - 1 if the count has reached zero. The result is + * increased with one. + */ + +static irqreturn_t hades_dma_emulator(int irq, void *dummy) +{ + unsigned long dma_base; + register unsigned long dma_cnt asm ("d3"); + static long save_buserr; + register unsigned long save_sp asm ("d4"); + register int tries asm ("d5"); + register unsigned char *start_addr asm ("a3"), *end_addr asm ("a4"); + register unsigned char *eff_addr; + register unsigned char *psdm_reg; + unsigned long rem; + + atari_disable_irq(IRQ_TT_MFP_SCSI); + + /* + * Read the dma address and count registers. + */ + + dma_base = SCSI_DMA_READ_P(dma_addr); + dma_cnt = SCSI_DMA_READ_P(dma_cnt); + + /* + * Check if DMA is still enabled. + */ + + if ((tt_scsi_dma.dma_ctrl & 2) == 0) + { + atari_enable_irq(IRQ_TT_MFP_SCSI); + return IRQ_HANDLED; + } + + if (dma_cnt == 0) + { + printk(KERN_NOTICE "DMA emulation: count is zero.\n"); + tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */ + atari_enable_irq(IRQ_TT_MFP_SCSI); + return IRQ_HANDLED; + } + + /* + * Install new bus error routine. + */ + + __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t" + "move.l 8(%%a0),%0\n\t" + "move.l %1,8(%%a0)\n\t" + : "=&r" (save_buserr) + : "r" (&&scsi_bus_error) + : "a0" ); + + hades_dma_ctrl &= 0xfc; /* Bus error and EOP off. */ + + /* + * Save the stack pointer. + */ + + __asm__ __volatile__ ("move.l %%sp,%0\n\t" + : "=&r" (save_sp) ); + + tries = 100; /* Maximum number of bus errors. */ + start_addr = phys_to_virt(dma_base); + end_addr = start_addr + dma_cnt; + +scsi_loop: + dma_cnt--; + rem = dma_cnt & (TRANSFER_SIZE - 1); + dma_cnt &= ~(TRANSFER_SIZE - 1); + psdm_reg = &hades_psdm_reg; + + if (tt_scsi_dma.dma_ctrl & 1) /* Read or write? */ + { + /* + * SCSI write. Abort when count is zero. + */ + + switch (rem) + { + case 0: + while (dma_cnt > 0) + { + dma_cnt -= TRANSFER_SIZE; + + *psdm_reg = *start_addr++; + case 15: + *psdm_reg = *start_addr++; + case 14: + *psdm_reg = *start_addr++; + case 13: + *psdm_reg = *start_addr++; + case 12: + *psdm_reg = *start_addr++; + case 11: + *psdm_reg = *start_addr++; + case 10: + *psdm_reg = *start_addr++; + case 9: + *psdm_reg = *start_addr++; + case 8: + *psdm_reg = *start_addr++; + case 7: + *psdm_reg = *start_addr++; + case 6: + *psdm_reg = *start_addr++; + case 5: + *psdm_reg = *start_addr++; + case 4: + *psdm_reg = *start_addr++; + case 3: + *psdm_reg = *start_addr++; + case 2: + *psdm_reg = *start_addr++; + case 1: + *psdm_reg = *start_addr++; + } + } + + hades_dma_ctrl |= 1; /* Set EOP. */ + udelay(10); + *psdm_reg = *start_addr++; /* Dummy byte. */ + tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */ + } + else + { + /* + * SCSI read. Abort when count is zero. + */ + + switch (rem) + { + case 0: + while (dma_cnt > 0) + { + dma_cnt -= TRANSFER_SIZE; + + *start_addr++ = *psdm_reg; + case 15: + *start_addr++ = *psdm_reg; + case 14: + *start_addr++ = *psdm_reg; + case 13: + *start_addr++ = *psdm_reg; + case 12: + *start_addr++ = *psdm_reg; + case 11: + *start_addr++ = *psdm_reg; + case 10: + *start_addr++ = *psdm_reg; + case 9: + *start_addr++ = *psdm_reg; + case 8: + *start_addr++ = *psdm_reg; + case 7: + *start_addr++ = *psdm_reg; + case 6: + *start_addr++ = *psdm_reg; + case 5: + *start_addr++ = *psdm_reg; + case 4: + *start_addr++ = *psdm_reg; + case 3: + *start_addr++ = *psdm_reg; + case 2: + *start_addr++ = *psdm_reg; + case 1: + *start_addr++ = *psdm_reg; + } + } + + hades_dma_ctrl |= 1; /* Set EOP. */ + udelay(10); + *start_addr++ = *psdm_reg; + tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */ + + set_restdata_reg(start_addr); + } + + if (start_addr != end_addr) + printk(KERN_CRIT "DMA emulation: FATAL: Count is not zero at end of transfer.\n"); + + dma_cnt = end_addr - start_addr; + +scsi_end: + dma_base = (dma_cnt == 0) ? virt_to_phys(start_addr - 1) + 1 : + virt_to_phys(start_addr); + + SCSI_DMA_WRITE_P(dma_addr, dma_base); + SCSI_DMA_WRITE_P(dma_cnt, dma_cnt); + + /* + * Restore old bus error routine. + */ + + __asm__ __volatile__ ("movec.l %%vbr,%%a0\n\t" + "move.l %0,8(%%a0)\n\t" + : + : "r" (save_buserr) + : "a0" ); + + atari_enable_irq(IRQ_TT_MFP_SCSI); + + return IRQ_HANDLED; + +scsi_bus_error: + /* + * First check if the bus error is caused by our code. + * If not, call the original handler. + */ + + __asm__ __volatile__ ("cmp.l %0,2(%%sp)\n\t" + "bcs.s .old_vector\n\t" + "cmp.l %1,2(%%sp)\n\t" + "bls.s .scsi_buserr\n" + ".old_vector:\n\t" + "move.l %2,-(%%sp)\n\t" + "rts\n" + ".scsi_buserr:\n\t" + : + : "i" (&&scsi_loop), "i" (&&scsi_end), + "m" (save_buserr) ); + + if (CPU_IS_060) + { + /* + * Get effective address and restore the stack. + */ + + __asm__ __volatile__ ("move.l 8(%%sp),%0\n\t" + "move.l %1,%%sp\n\t" + : "=a&" (eff_addr) + : "r" (save_sp) ); + } + else + { + register struct m68040_frame *frame; + + __asm__ __volatile__ ("lea 8(%%sp),%0\n\t" + : "=a&" (frame) ); + + if (tt_scsi_dma.dma_ctrl & 1) + { + /* + * Bus error while writing. + */ + + if (frame->wb3s & WBV_040) + { + if (frame->wb3a == (long) &hades_psdm_reg) + start_addr--; + else + writeback(frame->wb3s, frame->wb3a, + frame->wb3d, &&scsi_bus_error); + } + + if (frame->wb2s & WBV_040) + { + if (frame->wb2a == (long) &hades_psdm_reg) + start_addr--; + else + writeback(frame->wb2s, frame->wb2a, + frame->wb2d, &&scsi_bus_error); + } + + if (frame->wb1s & WBV_040) + { + if (frame->wb1a == (long) &hades_psdm_reg) + start_addr--; + } + } + else + { + /* + * Bus error while reading. + */ + + if (frame->wb3s & WBV_040) + writeback(frame->wb3s, frame->wb3a, + frame->wb3d, &&scsi_bus_error); + } + + eff_addr = (unsigned char *) frame->faddr; + + __asm__ __volatile__ ("move.l %0,%%sp\n\t" + : + : "r" (save_sp) ); + } + + dma_cnt = end_addr - start_addr; + + if (eff_addr == &hades_psdm_reg) + { + /* + * Bus error occurred while reading the pseudo + * DMA register. Time out. + */ + + tries--; + + if (tries <= 0) + { + if ((tt_scsi_dma.dma_ctrl & 1) == 0) /* Read or write? */ + set_restdata_reg(start_addr); + + if (dma_cnt <= 1) + printk(KERN_CRIT "DMA emulation: Fatal " + "error while %s the last byte.\n", + (tt_scsi_dma.dma_ctrl & 1) + ? "writing" : "reading"); + + goto scsi_end; + } + else + goto scsi_loop; + } + else + { + /* + * Bus error during pseudo DMA transfer. + * Terminate the DMA transfer. + */ + + hades_dma_ctrl |= 3; /* Set EOP and bus error. */ + if ((tt_scsi_dma.dma_ctrl & 1) == 0) /* Read or write? */ + set_restdata_reg(start_addr); + goto scsi_end; + } +} diff --git a/trunk/drivers/scsi/atari_scsi.c b/trunk/drivers/scsi/atari_scsi.c index 21fe07f9df87..f5732d8f67fe 100644 --- a/trunk/drivers/scsi/atari_scsi.c +++ b/trunk/drivers/scsi/atari_scsi.c @@ -249,6 +249,10 @@ static int setup_hostid = -1; module_param(setup_hostid, int, 0); +#if defined(CONFIG_TT_DMA_EMUL) +#include "atari_dma_emul.c" +#endif + #if defined(REAL_DMA) static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) @@ -691,8 +695,21 @@ int atari_scsi_detect(struct scsi_host_template *host) #ifdef REAL_DMA tt_scsi_dma.dma_ctrl = 0; atari_dma_residual = 0; - - if (MACH_IS_MEDUSA) { +#ifdef CONFIG_TT_DMA_EMUL + if (MACH_IS_HADES) { + if (request_irq(IRQ_AUTO_2, hades_dma_emulator, + IRQ_TYPE_PRIO, "Hades DMA emulator", + hades_dma_emulator)) { + printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting (MACH_IS_HADES)",IRQ_AUTO_2); + free_irq(IRQ_TT_MFP_SCSI, instance); + scsi_unregister(atari_scsi_host); + atari_stram_free(atari_dma_buffer); + atari_dma_buffer = 0; + return 0; + } + } +#endif + if (MACH_IS_MEDUSA || MACH_IS_HADES) { /* While the read overruns (described by Drew Eckhardt in * NCR5380.c) never happened on TTs, they do in fact on the Medusa * (This was the cause why SCSI didn't work right for so long @@ -990,7 +1007,11 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, Scsi_Cmnd *cmd, int write_flag) { unsigned long possible_len, limit; - +#ifndef CONFIG_TT_DMA_EMUL + if (MACH_IS_HADES) + /* Hades has no SCSI DMA at all :-( Always force use of PIO */ + return 0; +#endif if (IS_A_TT()) /* TT SCSI DMA can transfer arbitrary #bytes */ return wanted_len; diff --git a/trunk/drivers/scsi/ch.c b/trunk/drivers/scsi/ch.c index 88ecf94ad979..3c257fe0893e 100644 --- a/trunk/drivers/scsi/ch.c +++ b/trunk/drivers/scsi/ch.c @@ -914,9 +914,9 @@ static int ch_probe(struct device *dev) ch->minor = minor; sprintf(ch->name,"ch%d",ch->minor); - class_dev = device_create(ch_sysfs_class, dev, - MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch, - "s%s", ch->name); + class_dev = device_create_drvdata(ch_sysfs_class, dev, + MKDEV(SCSI_CHANGER_MAJOR, ch->minor), + ch, "s%s", ch->name); if (IS_ERR(class_dev)) { printk(KERN_WARNING "ch%d: device_create failed\n", ch->minor); diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index 8aba4fdfb522..1fe0901e8119 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -271,7 +271,7 @@ static int adpt_detect(struct scsi_host_template* sht) pHba->initialized = TRUE; pHba->state &= ~DPTI_STATE_RESET; if (adpt_sysfs_class) { - struct device *dev = device_create(adpt_sysfs_class, + struct device *dev = device_create_drvdata(adpt_sysfs_class, NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL, "dpti%d", pHba->unit); if (IS_ERR(dev)) { diff --git a/trunk/drivers/scsi/ide-scsi.c b/trunk/drivers/scsi/ide-scsi.c index 740bad435995..90212ac33be3 100644 --- a/trunk/drivers/scsi/ide-scsi.c +++ b/trunk/drivers/scsi/ide-scsi.c @@ -82,6 +82,7 @@ typedef struct ide_scsi_obj { struct gendisk *disk; struct Scsi_Host *host; + struct ide_atapi_pc *pc; /* Current packet command */ unsigned long transform; /* SCSI cmd translation layer */ unsigned long log; /* log flags */ } idescsi_scsi_t; @@ -136,10 +137,10 @@ static void ide_scsi_hex_dump(u8 *data, int len) static int idescsi_end_request(ide_drive_t *, int, int); -static void ide_scsi_callback(ide_drive_t *drive, int dsc) +static void ide_scsi_callback(ide_drive_t *drive) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = drive->pc; + struct ide_atapi_pc *pc = scsi->pc; if (pc->flags & PC_FLAG_TIMEDOUT) debug_log("%s: got timed out packet %lu at %lu\n", __func__, @@ -266,10 +267,49 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) spin_unlock_irqrestore(host->host_lock, flags); kfree(pc); blk_put_request(rq); - drive->pc = NULL; + scsi->pc = NULL; return 0; } +static inline unsigned long get_timeout(struct ide_atapi_pc *pc) +{ + return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies); +} + +static int idescsi_expiry(ide_drive_t *drive) +{ + idescsi_scsi_t *scsi = drive_to_idescsi(drive); + struct ide_atapi_pc *pc = scsi->pc; + + debug_log("%s called for %lu at %lu\n", __func__, + pc->scsi_cmd->serial_number, jiffies); + + pc->flags |= PC_FLAG_TIMEDOUT; + + return 0; /* we do not want the ide subsystem to retry */ +} + +/* + * Our interrupt handler. + */ +static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) +{ + idescsi_scsi_t *scsi = drive_to_idescsi(drive); + struct ide_atapi_pc *pc = scsi->pc; + + return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), + idescsi_expiry, NULL, NULL, NULL, + ide_io_buffers); +} + +static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) +{ + idescsi_scsi_t *scsi = drive_to_idescsi(drive); + + return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr, + get_timeout(scsi->pc), idescsi_expiry); +} + static inline int idescsi_set_direction(struct ide_atapi_pc *pc) { switch (pc->c[0]) { @@ -312,10 +352,13 @@ static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc) static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { + idescsi_scsi_t *scsi = drive_to_idescsi(drive); + /* Set the current packet command */ - drive->pc = pc; + scsi->pc = pc; - return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry); + return ide_issue_pc(drive, pc, idescsi_transfer_pc, + get_timeout(pc), idescsi_expiry); } /* @@ -331,8 +374,7 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r if (blk_sense_request(rq) || blk_special_request(rq)) { struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; - if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && - idescsi_map_sg(drive, pc) == 0) + if (drive->using_dma && !idescsi_map_sg(drive, pc)) pc->flags |= PC_FLAG_DMA_OK; return idescsi_issue_pc(drive, pc); @@ -385,14 +427,14 @@ static const struct ide_proc_devset idescsi_settings[] = { */ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) { + if ((drive->id[ATA_ID_CONFIG] & 0x0060) == 0x20) + set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); #if IDESCSI_DEBUG_LOG set_bit(IDESCSI_LOG_CMD, &scsi->log); #endif /* IDESCSI_DEBUG_LOG */ - drive->pc_callback = ide_scsi_callback; - drive->pc_update_buffers = NULL; - drive->pc_io_buffers = ide_io_buffers; + drive->pc_callback = ide_scsi_callback; ide_proc_register_driver(drive, scsi->driver); } @@ -414,7 +456,7 @@ static void ide_scsi_remove(ide_drive_t *drive) ide_scsi_put(scsi); - drive->dev_flags &= ~IDE_DFLAG_SCSI; + drive->scsi = 0; } static int ide_scsi_probe(ide_drive_t *); @@ -435,6 +477,7 @@ static ide_driver_t idescsi_driver = { .probe = ide_scsi_probe, .remove = ide_scsi_remove, .version = IDESCSI_VERSION, + .media = ide_scsi, .do_request = idescsi_do_request, .end_request = idescsi_end_request, .error = idescsi_atapi_error, @@ -579,8 +622,6 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) int busy; int ret = FAILED; - struct ide_atapi_pc *pc; - /* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) @@ -601,27 +642,26 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) spin_lock_irq(&ide_lock); /* If there is no pc running we're done (our interrupt took care of it) */ - pc = drive->pc; - if (pc == NULL) { + if (!scsi->pc) { ret = SUCCESS; goto ide_unlock; } /* It's somewhere in flight. Does ide subsystem agree? */ - if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy && - elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) { + if (scsi->pc->scsi_cmd->serial_number == cmd->serial_number && !busy && + elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != scsi->pc->rq) { /* * FIXME - not sure this condition can ever occur */ printk (KERN_ERR "ide-scsi: cmd aborted!\n"); - if (blk_sense_request(pc->rq)) - kfree(pc->buf); + if (blk_sense_request(scsi->pc->rq)) + kfree(scsi->pc->buf); /* we need to call blk_put_request twice. */ - blk_put_request(pc->rq); - blk_put_request(pc->rq); - kfree(pc); - drive->pc = NULL; + blk_put_request(scsi->pc->rq); + blk_put_request(scsi->pc->rq); + kfree(scsi->pc); + scsi->pc = NULL; ret = SUCCESS; } @@ -643,8 +683,6 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) int ready = 0; int ret = SUCCESS; - struct ide_atapi_pc *pc; - /* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) @@ -659,9 +697,7 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) spin_lock_irq(cmd->device->host->host_lock); spin_lock(&ide_lock); - pc = drive->pc; - - if (pc == NULL || (req = pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { + if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); spin_unlock(&ide_lock); spin_unlock_irq(cmd->device->host->host_lock); @@ -672,9 +708,9 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) if (__blk_end_request(req, -EIO, 0)) BUG(); if (blk_sense_request(req)) - kfree(pc->buf); - kfree(pc); - drive->pc = NULL; + kfree(scsi->pc->buf); + kfree(scsi->pc); + scsi->pc = NULL; blk_put_request(req); /* now nuke the drive queue */ @@ -765,7 +801,7 @@ static int ide_scsi_probe(ide_drive_t *drive) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) return -ENODEV; - drive->dev_flags |= IDE_DFLAG_SCSI; + drive->scsi = 1; g = alloc_disk(1 << PARTN_BITS); if (!g) @@ -806,7 +842,7 @@ static int ide_scsi_probe(ide_drive_t *drive) put_disk(g); out_host_put: - drive->dev_flags &= ~IDE_DFLAG_SCSI; + drive->scsi = 0; scsi_host_put(host); return err; } diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index 0ea78d9a37db..1c79f9794f4e 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -5708,8 +5708,7 @@ static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * S struct device *osst_member; int err; - osst_member = device_create(osst_sysfs_class, device, dev, STp, - "%s", name); + osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name); if (IS_ERR(osst_member)) { printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); return PTR_ERR(osst_member); diff --git a/trunk/drivers/scsi/pcmcia/aha152x_stub.c b/trunk/drivers/scsi/pcmcia/aha152x_stub.c index 165ff884f48e..2dd0dc9a9aed 100644 --- a/trunk/drivers/scsi/pcmcia/aha152x_stub.c +++ b/trunk/drivers/scsi/pcmcia/aha152x_stub.c @@ -140,41 +140,44 @@ static void aha152x_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int aha152x_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - /* For New Media T&J, look for a SCSI window */ - if (cfg->io.win[0].len >= 0x20) - p_dev->io.BasePort1 = cfg->io.win[0].base; - else if ((cfg->io.nwin > 1) && - (cfg->io.win[1].len >= 0x20)) - p_dev->io.BasePort1 = cfg->io.win[1].base; - if ((cfg->io.nwin > 0) && - (p_dev->io.BasePort1 < 0xffff)) { - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -EINVAL; -} - static int aha152x_config_cs(struct pcmcia_device *link) { scsi_info_t *info = link->priv; struct aha152x_setup s; - int last_ret, last_fn; + tuple_t tuple; + cisparse_t parse; + int i, last_ret, last_fn; + u_char tuple_data[64]; struct Scsi_Host *host; - + DEBUG(0, "aha152x_config(0x%p)\n", link); - last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL); - if (last_ret) { - cs_error(link, RequestIO, last_ret); - goto failed; + tuple.TupleData = tuple_data; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + /* For New Media T&J, look for a SCSI window */ + if (parse.cftable_entry.io.win[0].len >= 0x20) + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + else if ((parse.cftable_entry.io.nwin > 1) && + (parse.cftable_entry.io.win[1].len >= 0x20)) + link->io.BasePort1 = parse.cftable_entry.io.win[1].base; + if ((parse.cftable_entry.io.nwin > 0) && + (link->io.BasePort1 < 0xffff)) { + link->conf.ConfigIndex = parse.cftable_entry.index; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + } + next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } - + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -205,7 +208,6 @@ static int aha152x_config_cs(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); -failed: aha152x_release_cs(link); return -ENODEV; } diff --git a/trunk/drivers/scsi/pcmcia/fdomain_stub.c b/trunk/drivers/scsi/pcmcia/fdomain_stub.c index 06254f46a0dd..d8b99351b053 100644 --- a/trunk/drivers/scsi/pcmcia/fdomain_stub.c +++ b/trunk/drivers/scsi/pcmcia/fdomain_stub.c @@ -123,30 +123,34 @@ static void fdomain_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int fdomain_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - p_dev->io.BasePort1 = cfg->io.win[0].base; - return pcmcia_request_io(p_dev, &p_dev->io); -} - - static int fdomain_config(struct pcmcia_device *link) { scsi_info_t *info = link->priv; - int last_ret, last_fn; + tuple_t tuple; + cisparse_t parse; + int i, last_ret, last_fn; + u_char tuple_data[64]; char str[22]; struct Scsi_Host *host; DEBUG(0, "fdomain_config(0x%p)\n", link); - last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL); - if (last_ret) { - cs_error(link, RequestIO, last_ret); - goto failed; + tuple.TupleData = tuple_data; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + link->conf.ConfigIndex = parse.cftable_entry.index; + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) break; + next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -177,7 +181,6 @@ static int fdomain_config(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); -failed: fdomain_release(link); return -ENODEV; } /* fdomain_config */ diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.c b/trunk/drivers/scsi/pcmcia/nsp_cs.c index 11a61ea8d5d9..24e6cb8396e3 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.c +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.c @@ -1606,129 +1606,133 @@ static void nsp_cs_detach(struct pcmcia_device *link) is received, to configure the PCMCIA socket, and to make the ethernet device available to the system. ======================================================================*/ +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +/*====================================================================*/ +static int nsp_cs_config(struct pcmcia_device *link) +{ + int ret; + scsi_info_t *info = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_ret, last_fn; + unsigned char tuple_data[64]; + config_info_t conf; + win_req_t req; + memreq_t map; + cistpl_cftable_entry_t dflt = { 0 }; + struct Scsi_Host *host; + nsp_hw_data *data = &nsp_data_base; -struct nsp_cs_configdata { - nsp_hw_data *data; - win_req_t req; -}; + nsp_dbg(NSP_DEBUG_INIT, "in"); -static int nsp_cs_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - struct nsp_cs_configdata *cfg_mem = priv_data; + tuple.Attributes = 0; + tuple.TupleData = tuple_data; + tuple.TupleDataMax = sizeof(tuple_data); + tuple.TupleOffset = 0; - if (cfg->index == 0) - return -ENODEV; + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - p_dev->conf.Attributes |= CONF_ENABLE_SPKR; - p_dev->conf.Status = CCSR_AUDIO_ENA; - } + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) - return -ENODEV; - else if (dflt->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) - return -ENODEV; + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } + if (cfg->index == 0) { goto next_entry; } + link->conf.ConfigIndex = cfg->index; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) { + goto next_entry; + } + } else if (dflt.vcc.present & (1<vpp1.present & (1 << CISTPL_POWER_VNOM)) { - p_dev->conf.Vpp = + link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - } else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) { - p_dev->conf.Vpp = - dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; + } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { + link->conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { + link->conf.Attributes |= CONF_ENABLE_IRQ; + } /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; + link->io.Attributes2 = link->io.Attributes1; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; } - if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { - memreq_t map; - cistpl_mem_t *mem = - (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; - cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; - cfg_mem->req.Attributes |= WIN_ENABLE; - cfg_mem->req.Base = mem->win[0].host_addr; - cfg_mem->req.Size = mem->win[0].len; - if (cfg_mem->req.Size < 0x1000) - cfg_mem->req.Size = 0x1000; - cfg_mem->req.AccessSpeed = 0; - if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0) + if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; + req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; + req.Attributes |= WIN_ENABLE; + req.Base = mem->win[0].host_addr; + req.Size = mem->win[0].len; + if (req.Size < 0x1000) { + req.Size = 0x1000; + } + req.AccessSpeed = 0; + if (pcmcia_request_window(&link, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(p_dev->win, &map) != 0) + if (pcmcia_map_mem_page(link->win, &map) != 0) goto next_entry; - cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size); - cfg_mem->data->MmioLength = cfg_mem->req.Size; + data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); + data->MmioLength = req.Size; } /* If we got this far, we're cool! */ - return 0; - } - -next_entry: - nsp_dbg(NSP_DEBUG_INIT, "next"); - pcmcia_disable_device(p_dev); - return -ENODEV; -} - -static int nsp_cs_config(struct pcmcia_device *link) -{ - int ret; - scsi_info_t *info = link->priv; - struct nsp_cs_configdata *cfg_mem; - struct Scsi_Host *host; - nsp_hw_data *data = &nsp_data_base; - - nsp_dbg(NSP_DEBUG_INIT, "in"); - - cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL); - if (!cfg_mem) - return -ENOMEM; - cfg_mem->data = data; + break; - ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); - goto cs_failed; + next_entry: + nsp_dbg(NSP_DEBUG_INIT, "next"); + pcmcia_disable_device(link); + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } if (link->conf.Attributes & CONF_ENABLE_IRQ) { - if (pcmcia_request_irq(link, &link->irq)) - goto cs_failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); } - - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto cs_failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (free_ports) { if (link->io.BasePort1) { @@ -1786,20 +1790,20 @@ static int nsp_cs_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) - printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, - cfg_mem->req.Base+cfg_mem->req.Size-1); + printk(", mem 0x%06lx-0x%06lx", req.Base, + req.Base+req.Size-1); printk("\n"); - kfree(cfg_mem); return 0; cs_failed: nsp_dbg(NSP_DEBUG_INIT, "config fail"); + cs_error(link, last_fn, last_ret); nsp_cs_release(link); - kfree(cfg_mem); return -ENODEV; } /* nsp_cs_config */ +#undef CS_CHECK /*====================================================================== diff --git a/trunk/drivers/scsi/pcmcia/qlogic_stub.c b/trunk/drivers/scsi/pcmcia/qlogic_stub.c index 20c3e5e6d88a..67c5a58d17df 100644 --- a/trunk/drivers/scsi/pcmcia/qlogic_stub.c +++ b/trunk/drivers/scsi/pcmcia/qlogic_stub.c @@ -195,33 +195,39 @@ static void qlogic_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int qlogic_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - - if (p_dev->io.BasePort1 == 0) - return -ENODEV; - - return pcmcia_request_io(p_dev, &p_dev->io); -} - static int qlogic_config(struct pcmcia_device * link) { scsi_info_t *info = link->priv; - int last_ret, last_fn; + tuple_t tuple; + cisparse_t parse; + int i, last_ret, last_fn; + unsigned short tuple_data[32]; struct Scsi_Host *host; DEBUG(0, "qlogic_config(0x%p)\n", link); - last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL); - if (last_ret) { - cs_error(link, RequestIO, last_ret); - goto failed; + info->manf_id = link->manf_id; + + tuple.TupleData = (cisdata_t *) tuple_data; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + link->conf.ConfigIndex = parse.cftable_entry.index; + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; + if (link->io.BasePort1 != 0) { + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + break; + } + next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -256,7 +262,6 @@ static int qlogic_config(struct pcmcia_device * link) cs_failed: cs_error(link, last_fn, last_ret); pcmcia_disable_device(link); -failed: return -ENODEV; } /* qlogic_config */ diff --git a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c index b330c11a1752..0be232b58ffb 100644 --- a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c @@ -700,27 +700,15 @@ static struct scsi_host_template sym53c500_driver_template = { #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int SYM53C500_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - p_dev->io.BasePort1 = cfg->io.win[0].base; - p_dev->io.NumPorts1 = cfg->io.win[0].len; - - if (p_dev->io.BasePort1 == 0) - return -ENODEV; - - return pcmcia_request_io(p_dev, &p_dev->io); -} - static int SYM53C500_config(struct pcmcia_device *link) { struct scsi_info_t *info = link->priv; - int last_ret, last_fn; + tuple_t tuple; + cisparse_t parse; + int i, last_ret, last_fn; int irq_level, port_base; + unsigned short tuple_data[32]; struct Scsi_Host *host; struct scsi_host_template *tpnt = &sym53c500_driver_template; struct sym53c500_data *data; @@ -729,10 +717,27 @@ SYM53C500_config(struct pcmcia_device *link) info->manf_id = link->manf_id; - last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL); - if (last_ret) { - cs_error(link, RequestIO, last_ret); - goto failed; + tuple.TupleData = (cisdata_t *)tuple_data; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + link->conf.ConfigIndex = parse.cftable_entry.index; + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; + + if (link->io.BasePort1 != 0) { + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + break; + } +next_entry: + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); } CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); @@ -826,7 +831,6 @@ SYM53C500_config(struct pcmcia_device *link) cs_failed: cs_error(link, last_fn, last_ret); -failed: SYM53C500_release(link); return -ENODEV; } /* SYM53C500_config */ diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 93bd59a1ed79..ba9b9bbd4e73 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -1450,10 +1450,12 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf) if (sg_sysfs_valid) { struct device *sg_class_member; - sg_class_member = device_create(sg_sysfs_class, cl_dev->parent, - MKDEV(SCSI_GENERIC_MAJOR, - sdp->index), - sdp, "%s", disk->disk_name); + sg_class_member = device_create_drvdata(sg_sysfs_class, + cl_dev->parent, + MKDEV(SCSI_GENERIC_MAJOR, + sdp->index), + sdp, + "%s", disk->disk_name); if (IS_ERR(sg_class_member)) { printk(KERN_ERR "sg_add: " "device_create failed\n"); diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 5c28d08f18f4..c2bb53e3d941 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -4428,10 +4428,13 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) snprintf(name, 10, "%s%s%s", rew ? "n" : "", STp->disk->disk_name, st_formats[i]); st_class_member = - device_create(st_sysfs_class, &STp->device->sdev_gendev, - MKDEV(SCSI_TAPE_MAJOR, - TAPE_MINOR(dev_num, mode, rew)), - &STp->modes[mode], "%s", name); + device_create_drvdata(st_sysfs_class, + &STp->device->sdev_gendev, + MKDEV(SCSI_TAPE_MAJOR, + TAPE_MINOR(dev_num, + mode, rew)), + &STp->modes[mode], + "%s", name); if (IS_ERR(st_class_member)) { printk(KERN_WARNING "st%d: device_create failed\n", dev_num); diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index 1528de23a650..9ccc563d8730 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -44,10 +44,6 @@ #include "8250.h" -#ifdef CONFIG_SPARC -#include "suncore.h" -#endif - /* * Configuration: * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option @@ -57,13 +53,6 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; -static struct uart_driver serial8250_reg; - -static int serial_index(struct uart_port *port) -{ - return (serial8250_reg.minor - 64) + port->line; -} - /* * Debugging. */ @@ -547,7 +536,7 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) /* * FIFO support. */ -static void serial8250_clear_fifos(struct uart_8250_port *p) +static inline void serial8250_clear_fifos(struct uart_8250_port *p) { if (p->capabilities & UART_CAP_FIFO) { serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); @@ -562,7 +551,7 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) * capability" bit enabled. Note that on XR16C850s, we need to * reset LCR to write to IER. */ -static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) +static inline void serial8250_set_sleep(struct uart_8250_port *p, int sleep) { if (p->capabilities & UART_CAP_SLEEP) { if (p->capabilities & UART_CAP_EFR) { @@ -1004,7 +993,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) return; DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", - serial_index(&up->port), up->port.iobase, up->port.membase); + up->port.line, up->port.iobase, up->port.membase); /* * We really do need global IRQs disabled here - we're going to @@ -1139,8 +1128,8 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) if (up->capabilities != uart_config[up->port.type].flags) { printk(KERN_WARNING "ttyS%d: detected caps %08x should be %08x\n", - serial_index(&up->port), up->capabilities, - uart_config[up->port.type].flags); + up->port.line, up->capabilities, + uart_config[up->port.type].flags); } up->port.fifosize = uart_config[up->port.type].fifo_size; @@ -1435,7 +1424,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) /* * This handles the interrupt from one port. */ -static void serial8250_handle_port(struct uart_8250_port *up) +static inline void +serial8250_handle_port(struct uart_8250_port *up) { unsigned int status; unsigned long flags; @@ -1729,7 +1719,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) /* * Wait for transmitter & holding register to empty */ -static void wait_for_xmitr(struct uart_8250_port *up, int bits) +static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) { unsigned int status, tmout = 10000; @@ -1864,8 +1854,7 @@ static int serial8250_startup(struct uart_port *port) */ if (!(up->port.flags & UPF_BUGGY_UART) && (serial_inp(up, UART_LSR) == 0xff)) { - printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n", - serial_index(&up->port)); + printk("ttyS%d: LSR safety check engaged!\n", up->port.line); return -ENODEV; } @@ -1920,8 +1909,7 @@ static int serial8250_startup(struct uart_port *port) */ if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { up->bugs |= UART_BUG_THRE; - pr_debug("ttyS%d - using backup timer\n", - serial_index(port)); + pr_debug("ttyS%d - using backup timer\n", port->line); } } @@ -1981,7 +1969,7 @@ static int serial8250_startup(struct uart_port *port) if (!(up->bugs & UART_BUG_TXEN)) { up->bugs |= UART_BUG_TXEN; pr_debug("ttyS%d - enabling bad tx status workarounds\n", - serial_index(port)); + port->line); } } else { up->bugs &= ~UART_BUG_TXEN; @@ -2223,9 +2211,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, serial_outp(up, UART_EFR, efr); } -#ifdef CONFIG_ARCH_OMAP +#ifdef CONFIG_ARCH_OMAP15XX /* Workaround to enable 115200 baud on OMAP1510 internal ports */ - if (cpu_is_omap1510() && is_omap_port(up)) { + if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) { if (baud == 115200) { quot = 1; serial_out(up, UART_OMAP_OSC_12M_SEL, 1); @@ -2278,27 +2266,18 @@ serial8250_pm(struct uart_port *port, unsigned int state, p->pm(port, state, oldstate); } -static unsigned int serial8250_port_size(struct uart_8250_port *pt) -{ - if (pt->port.iotype == UPIO_AU) - return 0x100000; -#ifdef CONFIG_ARCH_OMAP - if (is_omap_port(pt)) - return 0x16 << pt->port.regshift; -#endif - return 8 << pt->port.regshift; -} - /* * Resource handling. */ static int serial8250_request_std_resource(struct uart_8250_port *up) { - unsigned int size = serial8250_port_size(up); + unsigned int size = 8 << up->port.regshift; int ret = 0; switch (up->port.iotype) { case UPIO_AU: + size = 0x100000; + /* fall thru */ case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM: @@ -2332,10 +2311,12 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) static void serial8250_release_std_resource(struct uart_8250_port *up) { - unsigned int size = serial8250_port_size(up); + unsigned int size = 8 << up->port.regshift; switch (up->port.iotype) { case UPIO_AU: + size = 0x100000; + /* fall thru */ case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM: @@ -2649,6 +2630,7 @@ static int serial8250_console_early_setup(void) return serial8250_find_port_for_earlycon(); } +static struct uart_driver serial8250_reg; static struct console serial8250_console = { .name = "ttyS", .write = serial8250_console_write, @@ -2695,6 +2677,7 @@ static struct uart_driver serial8250_reg = { .dev_name = "ttyS", .major = TTY_MAJOR, .minor = 64, + .nr = UART_NR, .cons = SERIAL8250_CONSOLE, }; @@ -2979,12 +2962,7 @@ static int __init serial8250_init(void) for (i = 0; i < NR_IRQS; i++) spin_lock_init(&irq_lists[i].lock); -#ifdef CONFIG_SPARC - ret = sunserial_register_minors(&serial8250_reg, UART_NR); -#else - serial8250_reg.nr = UART_NR; ret = uart_register_driver(&serial8250_reg); -#endif if (ret) goto out; @@ -3009,11 +2987,7 @@ static int __init serial8250_init(void) put_dev: platform_device_put(serial8250_isa_devs); unreg_uart_drv: -#ifdef CONFIG_SPARC - sunserial_unregister_minors(&serial8250_reg, UART_NR); -#else uart_unregister_driver(&serial8250_reg); -#endif out: return ret; } @@ -3032,11 +3006,7 @@ static void __exit serial8250_exit(void) platform_driver_unregister(&serial8250_isa_driver); platform_device_unregister(isa_dev); -#ifdef CONFIG_SPARC - sunserial_unregister_minors(&serial8250_reg, UART_NR); -#else uart_unregister_driver(&serial8250_reg); -#endif } module_init(serial8250_init); diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index c014ffb110e9..c2f23933155b 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -2041,9 +2041,9 @@ static int pciserial_resume_one(struct pci_dev *dev) * The device may have been disabled. Re-enable it. */ err = pci_enable_device(dev); - /* FIXME: We cannot simply error out here */ if (err) - printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n"); + return err; + pciserial_resume_ports(priv); } return 0; diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index db783b77a881..77cb34270fc1 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -9,6 +9,7 @@ menu "Serial drivers" # The new 8250/16550 serial drivers config SERIAL_8250 tristate "8250/16550 and compatible serial support" + depends on (BROKEN || !SPARC) select SERIAL_CORE ---help--- This selects whether you want to include the driver for the standard @@ -993,12 +994,24 @@ config SERIAL_68328_RTS_CTS bool "Support RTS/CTS on 68328 serial port" depends on SERIAL_68328 +config SERIAL_COLDFIRE + bool "ColdFire serial support (DEPRECATED)" + depends on COLDFIRE + help + This driver supports the built-in serial ports of the Motorola ColdFire + family of CPUs. + This driver is deprecated because it supports only the old interface + for serial drivers and features like magic keys are not working. + Please switch to the new style driver because this driver will be + removed soon. + config SERIAL_MCF - bool "Coldfire serial support" + bool "Coldfire serial support (new style driver)" depends on COLDFIRE select SERIAL_CORE help - This serial driver supports the Freescale Coldfire serial ports. + This new serial driver supports the Freescale Coldfire serial ports + using the new serial driver subsystem. config SERIAL_MCF_BAUDRATE int "Default baudrate for Coldfire serial ports" @@ -1123,6 +1136,42 @@ config SERIAL_CPM_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_CPM_SCC1 + bool "Support for SCC1 serial port" + depends on SERIAL_CPM=y + help + Select this option to use SCC1 as a serial port + +config SERIAL_CPM_SCC2 + bool "Support for SCC2 serial port" + depends on SERIAL_CPM=y + help + Select this option to use SCC2 as a serial port + +config SERIAL_CPM_SCC3 + bool "Support for SCC3 serial port" + depends on SERIAL_CPM=y + help + Select this option to use SCC3 as a serial port + +config SERIAL_CPM_SCC4 + bool "Support for SCC4 serial port" + depends on SERIAL_CPM=y + help + Select this option to use SCC4 as a serial port + +config SERIAL_CPM_SMC1 + bool "Support for SMC1 serial port" + depends on SERIAL_CPM=y + help + Select this option to use SMC1 as a serial port + +config SERIAL_CPM_SMC2 + bool "Support for SMC2 serial port" + depends on SERIAL_CPM=y + help + Select this option to use SMC2 as a serial port + config SERIAL_SGI_L1_CONSOLE bool "SGI Altix L1 serial console support" depends on IA64_GENERIC || IA64_SGI_SN2 diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index 0c17c8ddb19d..7e7383e890d8 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -4,16 +4,6 @@ obj-$(CONFIG_SERIAL_CORE) += serial_core.o obj-$(CONFIG_SERIAL_21285) += 21285.o - -# These Sparc drivers have to appear before others such as 8250 -# which share ttySx minor node space. Otherwise console device -# names change and other unplesantries. -obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o -obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o -obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o -obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o -obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o - obj-$(CONFIG_SERIAL_8250) += 8250.o obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o @@ -41,10 +31,16 @@ obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o +obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o +obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o +obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o +obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o +obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o obj-$(CONFIG_SERIAL_MUX) += mux.o obj-$(CONFIG_SERIAL_68328) += 68328serial.o obj-$(CONFIG_SERIAL_68360) += 68360serial.o +obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o obj-$(CONFIG_SERIAL_MCF) += mcf.o obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o diff --git a/trunk/drivers/serial/bfin_5xx.c b/trunk/drivers/serial/bfin_5xx.c index 569f0e2476c6..4a0d30bed9f1 100644 --- a/trunk/drivers/serial/bfin_5xx.c +++ b/trunk/drivers/serial/bfin_5xx.c @@ -1,7 +1,7 @@ /* * Blackfin On-Chip Serial Driver * - * Copyright 2006-2008 Analog Devices Inc. + * Copyright 2006-2007 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * @@ -42,9 +42,6 @@ #define BFIN_SERIAL_MAJOR 204 #define BFIN_SERIAL_MINOR 64 -static struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; -static int nr_active_ports = ARRAY_SIZE(bfin_serial_resource); - /* * Setup for console. Argument comes from the menuconfig */ @@ -129,13 +126,13 @@ static int kgdb_entry_state; void kgdb_put_debug_char(int chr) { struct bfin_serial_port *uart; - + if (CONFIG_KGDB_UART_PORT < 0 || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS) uart = &bfin_serial_ports[0]; else uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; - + while (!(UART_GET_LSR(uart) & THRE)) { SSYNC(); } @@ -155,7 +152,7 @@ int kgdb_get_debug_char(void) uart = &bfin_serial_ports[0]; else uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; - + while(!(UART_GET_LSR(uart) & DR)) { SSYNC(); } @@ -301,11 +298,7 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) bfin_serial_mctrl_check(uart); if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { -#ifdef CONFIG_BF54x - /* Clear TFI bit */ - UART_PUT_LSR(uart, TFI); -#endif - UART_CLEAR_IER(uart, ETBEI); + bfin_serial_stop_tx(&uart->port); return; } @@ -324,6 +317,9 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); + + if (uart_circ_empty(xmit)) + bfin_serial_stop_tx(&uart->port); } static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) @@ -649,42 +645,6 @@ static int bfin_serial_startup(struct uart_port *port) free_irq(uart->port.irq, uart); return -EBUSY; } - -# ifdef CONFIG_BF54x - { - unsigned uart_dma_ch_rx, uart_dma_ch_tx; - - switch (uart->port.irq) { - case IRQ_UART3_RX: - uart_dma_ch_rx = CH_UART3_RX; - uart_dma_ch_tx = CH_UART3_TX; - break; - case IRQ_UART2_RX: - uart_dma_ch_rx = CH_UART2_RX; - uart_dma_ch_tx = CH_UART2_TX; - break; - default: - uart_dma_ch_rx = uart_dma_ch_tx = 0; - break; - }; - - if (uart_dma_ch_rx && - request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) { - printk(KERN_NOTICE"Fail to attach UART interrupt\n"); - free_irq(uart->port.irq, uart); - free_irq(uart->port.irq + 1, uart); - return -EBUSY; - } - if (uart_dma_ch_tx && - request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) { - printk(KERN_NOTICE "Fail to attach UART interrupt\n"); - free_dma(uart_dma_ch_rx); - free_irq(uart->port.irq, uart); - free_irq(uart->port.irq + 1, uart); - return -EBUSY; - } - } -# endif #endif UART_SET_IER(uart, ERBFI); return 0; @@ -702,20 +662,6 @@ static void bfin_serial_shutdown(struct uart_port *port) del_timer(&(uart->rx_dma_timer)); dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); #else -#ifdef CONFIG_BF54x - switch (uart->port.irq) { - case IRQ_UART3_RX: - free_dma(CH_UART3_RX); - free_dma(CH_UART3_TX); - break; - case IRQ_UART2_RX: - free_dma(CH_UART2_RX); - free_dma(CH_UART2_TX); - break; - default: - break; - }; -#endif #ifdef CONFIG_KGDB_UART if (uart->port.line != CONFIG_KGDB_UART_PORT) #endif @@ -811,9 +757,6 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, val |= UCEN; UART_PUT_GCTL(uart, val); - /* Port speed changed, update the per-port timeout. */ - uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&uart->port.lock, flags); } @@ -916,9 +859,8 @@ static void __init bfin_serial_init_ports(void) return; first = 0; - for (i = 0; i < nr_active_ports; i++) { + for (i = 0; i < nr_ports; i++) { bfin_serial_ports[i].port.uartclk = get_sclk(); - bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE; bfin_serial_ports[i].port.ops = &bfin_serial_pops; bfin_serial_ports[i].port.line = i; bfin_serial_ports[i].port.iotype = UPIO_MEM; @@ -1019,7 +961,7 @@ bfin_serial_console_setup(struct console *co, char *options) * if so, search for the first available port that does have * console support. */ - if (co->index == -1 || co->index >= nr_active_ports) + if (co->index == -1 || co->index >= nr_ports) co->index = 0; uart = &bfin_serial_ports[co->index]; @@ -1114,7 +1056,7 @@ static __init void early_serial_write(struct console *con, const char *s, } } -static struct __initdata console bfin_early_serial_console = { +static struct __init console bfin_early_serial_console = { .name = "early_BFuart", .write = early_serial_write, .device = uart_console_device, @@ -1130,7 +1072,7 @@ struct console __init *bfin_earlyserial_init(unsigned int port, struct bfin_serial_port *uart; struct ktermios t; - if (port == -1 || port >= nr_active_ports) + if (port == -1 || port >= nr_ports) port = 0; bfin_serial_init_ports(); bfin_early_serial_console.index = port; @@ -1158,26 +1100,20 @@ static struct uart_driver bfin_serial_reg = { static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) { - int i; + struct bfin_serial_port *uart = platform_get_drvdata(dev); - for (i = 0; i < nr_active_ports; i++) { - if (bfin_serial_ports[i].port.dev != &dev->dev) - continue; - uart_suspend_port(&bfin_serial_reg, &bfin_serial_ports[i].port); - } + if (uart) + uart_suspend_port(&bfin_serial_reg, &uart->port); return 0; } static int bfin_serial_resume(struct platform_device *dev) { - int i; + struct bfin_serial_port *uart = platform_get_drvdata(dev); - for (i = 0; i < nr_active_ports; i++) { - if (bfin_serial_ports[i].port.dev != &dev->dev) - continue; - uart_resume_port(&bfin_serial_reg, &bfin_serial_ports[i].port); - } + if (uart) + uart_resume_port(&bfin_serial_reg, &uart->port); return 0; } @@ -1192,31 +1128,32 @@ static int bfin_serial_probe(struct platform_device *dev) break; if (i < dev->num_resources) { - for (i = 0; i < nr_active_ports; i++, res++) { + for (i = 0; i < nr_ports; i++, res++) { if (bfin_serial_ports[i].port.mapbase != res->start) continue; bfin_serial_ports[i].port.dev = &dev->dev; uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); + platform_set_drvdata(dev, &bfin_serial_ports[i]); } } return 0; } -static int bfin_serial_remove(struct platform_device *dev) +static int bfin_serial_remove(struct platform_device *pdev) { - int i; + struct bfin_serial_port *uart = platform_get_drvdata(pdev); + - for (i = 0; i < nr_active_ports; i++) { - if (bfin_serial_ports[i].port.dev != &dev->dev) - continue; - uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); - bfin_serial_ports[i].port.dev = NULL; #ifdef CONFIG_SERIAL_BFIN_CTSRTS - gpio_free(bfin_serial_ports[i].cts_pin); - gpio_free(bfin_serial_ports[i].rts_pin); + gpio_free(uart->cts_pin); + gpio_free(uart->rts_pin); #endif - } + + platform_set_drvdata(pdev, NULL); + + if (uart) + uart_remove_one_port(&bfin_serial_reg, &uart->port); return 0; } diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c index a6c4d744495e..25efca5a7a1f 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1333,9 +1333,6 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev, if (ret) return ret; - /* initialize the device pointer for the port */ - pinfo->port.dev = &ofdev->dev; - return uart_add_one_port(&cpm_reg, &pinfo->port); } diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 1b94c56ec239..0f0aff06c596 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -100,7 +100,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); dma_addr = (u32)cpm_dpram_phys(mem_addr); } else - mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, + mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); if (mem_addr == NULL) { @@ -127,8 +127,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) void cpm_uart_freebuf(struct uart_cpm_port *pinfo) { - dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * - pinfo->rx_fifosize) + + dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * + pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize), pinfo->mem_addr, pinfo->dma_addr); diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 141c0a3333ad..b8db4d3eed36 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -136,7 +136,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) dma_addr = virt_to_bus(mem_addr); } else - mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, + mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, GFP_KERNEL); if (mem_addr == NULL) { @@ -163,8 +163,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) void cpm_uart_freebuf(struct uart_cpm_port *pinfo) { - dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * - pinfo->rx_fifosize) + + dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * + pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, pinfo->dma_addr); diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index 211c21797ce0..bf94a770bb44 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -457,6 +457,7 @@ static struct e100_serial rs_table[] = { #define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) static struct ktermios *serial_termios[NR_PORTS]; +static struct ktermios *serial_termios_locked[NR_PORTS]; #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER static struct fast_timer fast_timers[NR_PORTS]; #endif @@ -4418,7 +4419,6 @@ rs_init(void) rs485_pa_bit)) { printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " "RS485 pin\n"); - put_tty_driver(driver); return -EBUSY; } #endif @@ -4427,7 +4427,6 @@ rs_init(void) rs485_port_g_bit)) { printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " "RS485 pin\n"); - put_tty_driver(driver); return -EBUSY; } #endif @@ -4447,6 +4446,8 @@ rs_init(void) driver->init_termios.c_ispeed = 115200; driver->init_termios.c_ospeed = 115200; driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + driver->termios = serial_termios; + driver->termios_locked = serial_termios_locked; tty_set_operations(driver, &rs_ops); serial_driver = driver; diff --git a/trunk/drivers/serial/mcfserial.c b/trunk/drivers/serial/mcfserial.c new file mode 100644 index 000000000000..fbe3835f6b77 --- /dev/null +++ b/trunk/drivers/serial/mcfserial.c @@ -0,0 +1,1965 @@ +#warning This driver is deprecated. Check Kconfig for details. +/* + * mcfserial.c -- serial driver for ColdFire internal UARTS. + * + * Copyright (C) 1999-2003 Greg Ungerer + * Copyright (c) 2000-2001 Lineo, Inc. + * Copyright (C) 2001-2002 SnapGear Inc. + * + * Based on code from 68332serial.c which was: + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 TSHG + * Copyright (c) 1999 Rt-Control Inc. + * + * Changes: + * 08/07/2003 Daniele Bellucci + * some cleanups in mcfrs_write. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mcfserial.h" + +struct timer_list mcfrs_timer_struct; + +/* + * Default console baud rate, we use this as the default + * for all ports so init can just open /dev/console and + * keep going. Perhaps one day the cflag settings for the + * console can be used instead. + */ +#if defined(CONFIG_HW_FEITH) +#define CONSOLE_BAUD_RATE 38400 +#define DEFAULT_CBAUD B38400 +#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \ + defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO) +#define CONSOLE_BAUD_RATE 115200 +#define DEFAULT_CBAUD B115200 +#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ + defined(CONFIG_senTec) || defined(CONFIG_SNEHA) || defined(CONFIG_AVNET) +#define CONSOLE_BAUD_RATE 19200 +#define DEFAULT_CBAUD B19200 +#endif + +#ifndef CONSOLE_BAUD_RATE +#define CONSOLE_BAUD_RATE 9600 +#define DEFAULT_CBAUD B9600 +#endif + +int mcfrs_console_inited = 0; +int mcfrs_console_port = -1; +int mcfrs_console_baud = CONSOLE_BAUD_RATE; +int mcfrs_console_cbaud = DEFAULT_CBAUD; + +/* + * Driver data structures. + */ +static struct tty_driver *mcfrs_serial_driver; + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* Debugging... + */ +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW + +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) || defined(CONFIG_M532x) +#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0) +#else +#define IRQBASE 73 +#endif + +/* + * Configuration table, UARTs to look for at startup. + */ +static struct mcf_serial mcfrs_table[] = { + { /* ttyS0 */ + .magic = 0, + .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE1), + .irq = IRQBASE, + .flags = ASYNC_BOOT_AUTOCONF, + }, +#ifdef MCFUART_BASE2 + { /* ttyS1 */ + .magic = 0, + .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2), + .irq = IRQBASE+1, + .flags = ASYNC_BOOT_AUTOCONF, + }, +#endif +#ifdef MCFUART_BASE3 + { /* ttyS2 */ + .magic = 0, + .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3), + .irq = IRQBASE+2, + .flags = ASYNC_BOOT_AUTOCONF, + }, +#endif +#ifdef MCFUART_BASE4 + { /* ttyS3 */ + .magic = 0, + .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4), + .irq = IRQBASE+3, + .flags = ASYNC_BOOT_AUTOCONF, + }, +#endif +}; + + +#define NR_PORTS (sizeof(mcfrs_table) / sizeof(struct mcf_serial)) + +/* + * This is used to figure out the divisor speeds and the timeouts. + */ +static int mcfrs_baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 +}; +#define MCFRS_BAUD_TABLE_SIZE \ + (sizeof(mcfrs_baud_table)/sizeof(mcfrs_baud_table[0])) + + +#ifdef CONFIG_MAGIC_SYSRQ +/* + * Magic system request keys. Used for debugging... + */ +extern int magic_sysrq_key(int ch); +#endif + + +/* + * Forware declarations... + */ +static void mcfrs_change_speed(struct mcf_serial *info); +static void mcfrs_wait_until_sent(struct tty_struct *tty, int timeout); + + +static inline int serial_paranoia_check(struct mcf_serial *info, + char *name, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char badmagic[] = + "MCFRS(warning): bad magic number for serial struct %s in %s\n"; + static const char badinfo[] = + "MCFRS(warning): null mcf_serial for %s in %s\n"; + + if (!info) { + printk(badinfo, name, routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, name, routine); + return 1; + } +#endif + return 0; +} + +/* + * Sets or clears DTR and RTS on the requested line. + */ +static void mcfrs_setsignals(struct mcf_serial *info, int dtr, int rts) +{ + volatile unsigned char *uartp; + unsigned long flags; + +#if 0 + printk("%s(%d): mcfrs_setsignals(info=%x,dtr=%d,rts=%d)\n", + __FILE__, __LINE__, info, dtr, rts); +#endif + + local_irq_save(flags); + if (dtr >= 0) { +#ifdef MCFPP_DTR0 + if (info->line) + mcf_setppdata(MCFPP_DTR1, (dtr ? 0 : MCFPP_DTR1)); + else + mcf_setppdata(MCFPP_DTR0, (dtr ? 0 : MCFPP_DTR0)); +#endif + } + if (rts >= 0) { + uartp = info->addr; + if (rts) { + info->sigs |= TIOCM_RTS; + uartp[MCFUART_UOP1] = MCFUART_UOP_RTS; + } else { + info->sigs &= ~TIOCM_RTS; + uartp[MCFUART_UOP0] = MCFUART_UOP_RTS; + } + } + local_irq_restore(flags); + return; +} + +/* + * Gets values of serial signals. + */ +static int mcfrs_getsignals(struct mcf_serial *info) +{ + volatile unsigned char *uartp; + unsigned long flags; + int sigs; +#if defined(CONFIG_NETtel) && defined(CONFIG_M5307) + unsigned short ppdata; +#endif + +#if 0 + printk("%s(%d): mcfrs_getsignals(info=%x)\n", __FILE__, __LINE__); +#endif + + local_irq_save(flags); + uartp = info->addr; + sigs = (uartp[MCFUART_UIPR] & MCFUART_UIPR_CTS) ? 0 : TIOCM_CTS; + sigs |= (info->sigs & TIOCM_RTS); + +#ifdef MCFPP_DCD0 +{ + unsigned int ppdata; + ppdata = mcf_getppdata(); + if (info->line == 0) { + sigs |= (ppdata & MCFPP_DCD0) ? 0 : TIOCM_CD; + sigs |= (ppdata & MCFPP_DTR0) ? 0 : TIOCM_DTR; + } else if (info->line == 1) { + sigs |= (ppdata & MCFPP_DCD1) ? 0 : TIOCM_CD; + sigs |= (ppdata & MCFPP_DTR1) ? 0 : TIOCM_DTR; + } +} +#endif + + local_irq_restore(flags); + return(sigs); +} + +/* + * ------------------------------------------------------------ + * mcfrs_stop() and mcfrs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void mcfrs_stop(struct tty_struct *tty) +{ + volatile unsigned char *uartp; + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "mcfrs_stop")) + return; + + local_irq_save(flags); + uartp = info->addr; + info->imr &= ~MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + local_irq_restore(flags); +} + +static void mcfrs_start(struct tty_struct *tty) +{ + volatile unsigned char *uartp; + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "mcfrs_start")) + return; + + local_irq_save(flags); + if (info->xmit_cnt && info->xmit_buf) { + uartp = info->addr; + info->imr |= MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + } + local_irq_restore(flags); +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * mcfrs_interrupt(). They were separated out for readability's sake. + * + * Note: mcfrs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * mcfrs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +static inline void receive_chars(struct mcf_serial *info) +{ + volatile unsigned char *uartp; + struct tty_struct *tty = info->port.tty; + unsigned char status, ch, flag; + + if (!tty) + return; + + uartp = info->addr; + + while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { + ch = uartp[MCFUART_URB]; + info->stats.rx++; + +#ifdef CONFIG_MAGIC_SYSRQ + if (mcfrs_console_inited && (info->line == mcfrs_console_port)) { + if (magic_sysrq_key(ch)) + continue; + } +#endif + + flag = TTY_NORMAL; + if (status & MCFUART_USR_RXERR) { + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; + if (status & MCFUART_USR_RXBREAK) { + info->stats.rxbreak++; + flag = TTY_BREAK; + } else if (status & MCFUART_USR_RXPARITY) { + info->stats.rxparity++; + flag = TTY_PARITY; + } else if (status & MCFUART_USR_RXOVERRUN) { + info->stats.rxoverrun++; + flag = TTY_OVERRUN; + } else if (status & MCFUART_USR_RXFRAMING) { + info->stats.rxframing++; + flag = TTY_FRAME; + } + } + tty_insert_flip_char(tty, ch, flag); + } + tty_schedule_flip(tty); + return; +} + +static inline void transmit_chars(struct mcf_serial *info) +{ + volatile unsigned char *uartp; + + uartp = info->addr; + + if (info->x_char) { + /* Send special char - probably flow control */ + uartp[MCFUART_UTB] = info->x_char; + info->x_char = 0; + info->stats.tx++; + } + + if ((info->xmit_cnt <= 0) || info->port.tty->stopped) { + info->imr &= ~MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + return; + } + + while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) { + uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++]; + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->stats.tx++; + if (--info->xmit_cnt <= 0) + break; + } + + if (info->xmit_cnt < WAKEUP_CHARS) + schedule_work(&info->tqueue); + return; +} + +/* + * This is the serial driver's generic interrupt routine + */ +irqreturn_t mcfrs_interrupt(int irq, void *dev_id) +{ + struct mcf_serial *info; + unsigned char isr; + + info = &mcfrs_table[(irq - IRQBASE)]; + isr = info->addr[MCFUART_UISR] & info->imr; + + if (isr & MCFUART_UIR_RXREADY) + receive_chars(info); + if (isr & MCFUART_UIR_TXREADY) + transmit_chars(info); + return IRQ_HANDLED; +} + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +static void mcfrs_offintr(struct work_struct *work) +{ + struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue); + struct tty_struct *tty = info->port.tty; + + if (tty) + tty_wakeup(tty); +} + + +/* + * Change of state on a DCD line. + */ +void mcfrs_modem_change(struct mcf_serial *info, int dcd) +{ + if (info->count == 0) + return; + + if (info->flags & ASYNC_CHECK_CD) { + if (dcd) + wake_up_interruptible(&info->open_wait); + else + schedule_work(&info->tqueue_hangup); + } +} + + +#ifdef MCFPP_DCD0 + +unsigned short mcfrs_ppstatus; + +/* + * This subroutine is called when the RS_TIMER goes off. It is used + * to monitor the state of the DCD lines - since they have no edge + * sensors and interrupt generators. + */ +static void mcfrs_timer(void) +{ + unsigned int ppstatus, dcdval, i; + + ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1); + + if (ppstatus != mcfrs_ppstatus) { + for (i = 0; (i < 2); i++) { + dcdval = (i ? MCFPP_DCD1 : MCFPP_DCD0); + if ((ppstatus & dcdval) != (mcfrs_ppstatus & dcdval)) { + mcfrs_modem_change(&mcfrs_table[i], + ((ppstatus & dcdval) ? 0 : 1)); + } + } + } + mcfrs_ppstatus = ppstatus; + + /* Re-arm timer */ + mcfrs_timer_struct.expires = jiffies + HZ/25; + add_timer(&mcfrs_timer_struct); +} + +#endif /* MCFPP_DCD0 */ + + +/* + * This routine is called from the scheduler tqueue when the interrupt + * routine has signalled that a hangup has occurred. The path of + * hangup processing is: + * + * serial interrupt routine -> (scheduler tqueue) -> + * do_serial_hangup() -> tty->hangup() -> mcfrs_hangup() + * + */ +static void do_serial_hangup(struct work_struct *work) +{ + struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup); + struct tty_struct *tty = info->port.tty; + + if (tty) + tty_hangup(tty); +} + +static int startup(struct mcf_serial * info) +{ + volatile unsigned char *uartp; + unsigned long flags; + + if (info->flags & ASYNC_INITIALIZED) + return 0; + + if (!info->xmit_buf) { + info->xmit_buf = (unsigned char *) __get_free_page(GFP_KERNEL); + if (!info->xmit_buf) + return -ENOMEM; + } + + local_irq_save(flags); + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq); +#endif + + /* + * Reset UART, get it into known state... + */ + uartp = info->addr; + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ + mcfrs_setsignals(info, 1, 1); + + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * and set the speed of the serial port + */ + mcfrs_change_speed(info); + + /* + * Lastly enable the UART transmitter and receiver, and + * interrupt enables. + */ + info->imr = MCFUART_UIR_RXREADY; + uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; + uartp[MCFUART_UIMR] = info->imr; + + info->flags |= ASYNC_INITIALIZED; + local_irq_restore(flags); + return 0; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct mcf_serial * info) +{ + volatile unsigned char *uartp; + unsigned long flags; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....\n", info->line, + info->irq); +#endif + + local_irq_save(flags); + + uartp = info->addr; + uartp[MCFUART_UIMR] = 0; /* mask all interrupts */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ + + if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) + mcfrs_setsignals(info, 0, 0); + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = 0; + } + + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; + local_irq_restore(flags); +} + + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void mcfrs_change_speed(struct mcf_serial *info) +{ + volatile unsigned char *uartp; + unsigned int baudclk, cflag; + unsigned long flags; + unsigned char mr1, mr2; + int i; +#ifdef CONFIG_M5272 + unsigned int fraction; +#endif + + if (!info->port.tty || !info->port.tty->termios) + return; + cflag = info->port.tty->termios->c_cflag; + if (info->addr == 0) + return; + +#if 0 + printk("%s(%d): mcfrs_change_speed()\n", __FILE__, __LINE__); +#endif + + i = cflag & CBAUD; + if (i & CBAUDEX) { + i &= ~CBAUDEX; + if (i < 1 || i > 4) + info->port.tty->termios->c_cflag &= ~CBAUDEX; + else + i += 15; + } + if (i == 0) { + mcfrs_setsignals(info, 0, -1); + return; + } + + /* compute the baudrate clock */ +#ifdef CONFIG_M5272 + /* + * For the MCF5272, also compute the baudrate fraction. + */ + baudclk = (MCF_BUSCLK / mcfrs_baud_table[i]) / 32; + fraction = MCF_BUSCLK - (baudclk * 32 * mcfrs_baud_table[i]); + fraction *= 16; + fraction /= (32 * mcfrs_baud_table[i]); +#else + baudclk = ((MCF_BUSCLK / mcfrs_baud_table[i]) + 16) / 32; +#endif + + info->baud = mcfrs_baud_table[i]; + + mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; + mr2 = 0; + + switch (cflag & CSIZE) { + case CS5: mr1 |= MCFUART_MR1_CS5; break; + case CS6: mr1 |= MCFUART_MR1_CS6; break; + case CS7: mr1 |= MCFUART_MR1_CS7; break; + case CS8: + default: mr1 |= MCFUART_MR1_CS8; break; + } + + if (cflag & PARENB) { + if (cflag & CMSPAR) { + if (cflag & PARODD) + mr1 |= MCFUART_MR1_PARITYMARK; + else + mr1 |= MCFUART_MR1_PARITYSPACE; + } else { + if (cflag & PARODD) + mr1 |= MCFUART_MR1_PARITYODD; + else + mr1 |= MCFUART_MR1_PARITYEVEN; + } + } else { + mr1 |= MCFUART_MR1_PARITYNONE; + } + + if (cflag & CSTOPB) + mr2 |= MCFUART_MR2_STOP2; + else + mr2 |= MCFUART_MR2_STOP1; + + if (cflag & CRTSCTS) { + mr1 |= MCFUART_MR1_RXRTS; + mr2 |= MCFUART_MR2_TXCTS; + } + + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else + info->flags |= ASYNC_CHECK_CD; + + uartp = info->addr; + + local_irq_save(flags); +#if 0 + printk("%s(%d): mr1=%x mr2=%x baudclk=%x\n", __FILE__, __LINE__, + mr1, mr2, baudclk); +#endif + /* + Note: pg 12-16 of MCF5206e User's Manual states that a + software reset should be performed prior to changing + UMR1,2, UCSR, UACR, bit 7 + */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */ + uartp[MCFUART_UMR] = mr1; + uartp[MCFUART_UMR] = mr2; + uartp[MCFUART_UBG1] = (baudclk & 0xff00) >> 8; /* set msb byte */ + uartp[MCFUART_UBG2] = (baudclk & 0xff); /* set lsb byte */ +#ifdef CONFIG_M5272 + uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */ +#endif + uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; + uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; + mcfrs_setsignals(info, 1, -1); + local_irq_restore(flags); + return; +} + +static void mcfrs_flush_chars(struct tty_struct *tty) +{ + volatile unsigned char *uartp; + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "mcfrs_flush_chars")) + return; + + uartp = (volatile unsigned char *) info->addr; + + /* + * re-enable receiver interrupt + */ + local_irq_save(flags); + if ((!(info->imr & MCFUART_UIR_RXREADY)) && + (info->flags & ASYNC_INITIALIZED) ) { + info->imr |= MCFUART_UIR_RXREADY; + uartp[MCFUART_UIMR] = info->imr; + } + local_irq_restore(flags); + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->xmit_buf) + return; + + /* Enable transmitter */ + local_irq_save(flags); + info->imr |= MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + local_irq_restore(flags); +} + +static int mcfrs_write(struct tty_struct * tty, + const unsigned char *buf, int count) +{ + volatile unsigned char *uartp; + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + unsigned long flags; + int c, total = 0; + +#if 0 + printk("%s(%d): mcfrs_write(tty=%x,buf=%x,count=%d)\n", + __FILE__, __LINE__, (int)tty, (int)buf, count); +#endif + + if (serial_paranoia_check(info, tty->name, "mcfrs_write")) + return 0; + + if (!tty || !info->xmit_buf) + return 0; + + local_save_flags(flags); + while (1) { + local_irq_disable(); + c = min(count, (int) min(((int)SERIAL_XMIT_SIZE) - info->xmit_cnt - 1, + ((int)SERIAL_XMIT_SIZE) - info->xmit_head)); + local_irq_restore(flags); + + if (c <= 0) + break; + + memcpy(info->xmit_buf + info->xmit_head, buf, c); + + local_irq_disable(); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + local_irq_restore(flags); + + buf += c; + count -= c; + total += c; + } + + local_irq_disable(); + uartp = info->addr; + info->imr |= MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + local_irq_restore(flags); + + return total; +} + +static int mcfrs_write_room(struct tty_struct *tty) +{ + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + int ret; + + if (serial_paranoia_check(info, tty->name, "mcfrs_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int mcfrs_chars_in_buffer(struct tty_struct *tty) +{ + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "mcfrs_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} + +static void mcfrs_flush_buffer(struct tty_struct *tty) +{ + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "mcfrs_flush_buffer")) + return; + + local_irq_save(flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + local_irq_restore(flags); + + tty_wakeup(tty); +} + +/* + * ------------------------------------------------------------ + * mcfrs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void mcfrs_throttle(struct tty_struct * tty) +{ + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->name, "mcfrs_throttle")) + return; + + if (I_IXOFF(tty)) + info->x_char = STOP_CHAR(tty); + + /* Turn off RTS line (do this atomic) */ +} + +static void mcfrs_unthrottle(struct tty_struct * tty) +{ + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->name, "mcfrs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + info->x_char = START_CHAR(tty); + } + + /* Assert RTS line (do this atomic) */ +} + +/* + * ------------------------------------------------------------ + * mcfrs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct mcf_serial * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = info->type; + tmp.line = info->line; + tmp.port = (unsigned int) info->addr; + tmp.irq = info->irq; + tmp.flags = info->flags; + tmp.baud_base = info->baud_base; + tmp.close_delay = info->close_delay; + tmp.closing_wait = info->closing_wait; + tmp.custom_divisor = info->custom_divisor; + return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0; +} + +static int set_serial_info(struct mcf_serial * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct mcf_serial old_info; + int retval = 0; + + if (!new_info) + return -EFAULT; + if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) + return -EFAULT; + old_info = *info; + + if (!capable(CAP_SYS_ADMIN)) { + if ((new_serial.baud_base != info->baud_base) || + (new_serial.type != info->type) || + (new_serial.close_delay != info->close_delay) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (info->flags & ~ASYNC_USR_MASK))) + return -EPERM; + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if (info->count > 1) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + info->baud_base = new_serial.baud_base; + info->flags = ((info->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->type = new_serial.type; + info->close_delay = new_serial.close_delay; + info->closing_wait = new_serial.closing_wait; + +check_and_exit: + retval = startup(info); + return retval; +} + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct mcf_serial * info, unsigned int *value) +{ + volatile unsigned char *uartp; + unsigned long flags; + unsigned char status; + + local_irq_save(flags); + uartp = info->addr; + status = (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY) ? TIOCSER_TEMT : 0; + local_irq_restore(flags); + + return put_user(status,value); +} + +/* + * This routine sends a break character out the serial port. + */ +static void send_break( struct mcf_serial * info, int duration) +{ + volatile unsigned char *uartp; + unsigned long flags; + + if (!info->addr) + return; + set_current_state(TASK_INTERRUPTIBLE); + uartp = info->addr; + + local_irq_save(flags); + uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTART; + schedule_timeout(duration); + uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTOP; + local_irq_restore(flags); +} + +static int mcfrs_tiocmget(struct tty_struct *tty, struct file *file) +{ + struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + return mcfrs_getsignals(info); +} + +static int mcfrs_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear) +{ + struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; + int rts = -1, dtr = -1; + + if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + if (set & TIOCM_RTS) + rts = 1; + if (set & TIOCM_DTR) + dtr = 1; + if (clear & TIOCM_RTS) + rts = 0; + if (clear & TIOCM_DTR) + dtr = 0; + + mcfrs_setsignals(info, dtr, rts); + + return 0; +} + +static int mcfrs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; + int retval, error; + + if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && + (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TCSBRK: /* SVID version: non-zero arg --> no break */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + if (!arg) + send_break(info, HZ/4); /* 1/4 second */ + return 0; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + send_break(info, arg ? arg*(HZ/10) : HZ/4); + return 0; + case TIOCGSERIAL: + if (access_ok(VERIFY_WRITE, (void *) arg, + sizeof(struct serial_struct))) + return get_serial_info(info, + (struct serial_struct *) arg); + return -EFAULT; + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERGETLSR: /* Get line status register */ + if (access_ok(VERIFY_WRITE, (void *) arg, + sizeof(unsigned int))) + return get_lsr_info(info, (unsigned int *) arg); + return -EFAULT; + case TIOCSERGSTRUCT: + error = copy_to_user((struct mcf_serial *) arg, + info, sizeof(struct mcf_serial)); + if (error) + return -EFAULT; + return 0; + +#ifdef TIOCSET422 + case TIOCSET422: { + unsigned int val; + get_user(val, (unsigned int *) arg); + mcf_setpa(MCFPP_PA11, (val ? 0 : MCFPP_PA11)); + break; + } + case TIOCGET422: { + unsigned int val; + val = (mcf_getpa() & MCFPP_PA11) ? 0 : 1; + put_user(val, (unsigned int *) arg); + break; + } +#endif + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + + mcfrs_change_speed(info); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + mcfrs_setsignals(info, -1, 1); +#if 0 + mcfrs_start(tty); +#endif + } +} + +/* + * ------------------------------------------------------------ + * mcfrs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * S structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void mcfrs_close(struct tty_struct *tty, struct file * filp) +{ + volatile unsigned char *uartp; + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->name, "mcfrs_close")) + return; + + local_irq_save(flags); + + if (tty_hung_up_p(filp)) { + local_irq_restore(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("mcfrs_close ttyS%d, count = %d\n", info->line, info->count); +#endif + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("MCFRS: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } + if (--info->count < 0) { + printk("MCFRS: bad serial port count for ttyS%d: %d\n", + info->line, info->count); + info->count = 0; + } + if (info->count) { + local_irq_restore(flags); + return; + } + info->flags |= ASYNC_CLOSING; + + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->imr &= ~MCFUART_UIR_RXREADY; + uartp = info->addr; + uartp[MCFUART_UIMR] = info->imr; + +#if 0 + /* FIXME: do we need to keep this enabled for console?? */ + if (mcfrs_console_inited && (mcfrs_console_port == info->line)) { + /* Do not disable the UART */ ; + } else +#endif + shutdown(info); + mcfrs_flush_buffer(tty); + tty_ldisc_flush(tty); + + tty->closing = 0; + info->event = 0; + info->port.tty = NULL; +#if 0 + if (tty->ldisc.num != ldiscs[N_TTY].num) { + if (tty->ldisc.close) + (tty->ldisc.close)(tty); + tty->ldisc = ldiscs[N_TTY]; + tty->termios->c_line = N_TTY; + if (tty->ldisc.open) + (tty->ldisc.open)(tty); + } +#endif + if (info->blocked_open) { + if (info->close_delay) { + msleep_interruptible(jiffies_to_msecs(info->close_delay)); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + local_irq_restore(flags); +} + +/* + * mcfrs_wait_until_sent() --- wait until the transmitter is empty + */ +static void +mcfrs_wait_until_sent(struct tty_struct *tty, int timeout) +{ +#ifdef CONFIG_M5272 +#define MCF5272_FIFO_SIZE 25 /* fifo size + shift reg */ + + struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; + volatile unsigned char *uartp; + unsigned long orig_jiffies, fifo_time, char_time, fifo_cnt; + + if (serial_paranoia_check(info, tty->name, "mcfrs_wait_until_sent")) + return; + + orig_jiffies = jiffies; + + /* + * Set the check interval to be 1/5 of the approximate time + * to send the entire fifo, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + lock_kernel(); + + fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud; + char_time = fifo_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout && timeout < char_time) + char_time = timeout; + + /* + * Clamp the timeout period at 2 * the time to empty the + * fifo. Just to be safe, set the minimum at .5 seconds. + */ + fifo_time *= 2; + if (fifo_time < (HZ/2)) + fifo_time = HZ/2; + if (!timeout || timeout > fifo_time) + timeout = fifo_time; + + /* + * Account for the number of bytes in the UART + * transmitter FIFO plus any byte being shifted out. + */ + uartp = (volatile unsigned char *) info->addr; + for (;;) { + fifo_cnt = (uartp[MCFUART_UTF] & MCFUART_UTF_TXB); + if ((uartp[MCFUART_USR] & (MCFUART_USR_TXREADY| + MCFUART_USR_TXEMPTY)) == + MCFUART_USR_TXREADY) + fifo_cnt++; + if (fifo_cnt == 0) + break; + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + unlock_kernel(); +#else + /* + * For the other coldfire models, assume all data has been sent + */ +#endif +} + +/* + * mcfrs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +void mcfrs_hangup(struct tty_struct *tty) +{ + struct mcf_serial * info = (struct mcf_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "mcfrs_hangup")) + return; + + mcfrs_flush_buffer(tty); + shutdown(info); + info->event = 0; + info->count = 0; + info->flags &= ~ASYNC_NORMAL_ACTIVE; + info->port.tty = NULL; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * mcfrs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct mcf_serial *info) +{ + DECLARE_WAITQUEUE(wait, current); + int retval; + int do_clocal = 0; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (info->flags & ASYNC_CLOSING) { + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + return -EAGAIN; + else + return -ERESTARTSYS; +#else + return -EAGAIN; +#endif + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * mcfrs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttyS%d, count = %d\n", + info->line, info->count); +#endif + info->count--; + info->blocked_open++; + while (1) { + local_irq_disable(); + mcfrs_setsignals(info, 1, 1); + local_irq_enable(); + current->state = TASK_INTERRUPTIBLE; + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ASYNC_CLOSING) && + (do_clocal || (mcfrs_getsignals(info) & TIOCM_CD))) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttyS%d, count = %d\n", + info->line, info->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) + info->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttyS%d, count = %d\n", + info->line, info->count); +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +int mcfrs_open(struct tty_struct *tty, struct file * filp) +{ + struct mcf_serial *info; + int retval, line; + + line = tty->index; + if ((line < 0) || (line >= NR_PORTS)) + return -ENODEV; + info = mcfrs_table + line; + if (serial_paranoia_check(info, tty->name, "mcfrs_open")) + return -ENODEV; +#ifdef SERIAL_DEBUG_OPEN + printk("mcfrs_open %s, count = %d\n", tty->name, info->count); +#endif + info->count++; + tty->driver_data = info; + info->port.tty = tty; + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) + return retval; + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("mcfrs_open returning after block_til_ready with %d\n", + retval); +#endif + return retval; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("mcfrs_open %s successful...\n", tty->name); +#endif + return 0; +} + +/* + * Based on the line number set up the internal interrupt stuff. + */ +static void mcfrs_irqinit(struct mcf_serial *info) +{ +#if defined(CONFIG_M5272) + volatile unsigned long *icrp; + volatile unsigned long *portp; + volatile unsigned char *uartp; + + uartp = info->addr; + icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR2); + + switch (info->line) { + case 0: + *icrp = 0xe0000000; + break; + case 1: + *icrp = 0x0e000000; + break; + default: + printk("MCFRS: don't know how to handle UART %d interrupt?\n", + info->line); + return; + } + + /* Enable the output lines for the serial ports */ + portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PBCNT); + *portp = (*portp & ~0x000000ff) | 0x00000055; + portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT); + *portp = (*portp & ~0x000003fc) | 0x000002a8; +#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) + volatile unsigned char *icrp, *uartp; + volatile unsigned long *imrp; + + uartp = info->addr; + + icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + + MCFINTC_ICR0 + MCFINT_UART0 + info->line); + *icrp = 0x30 + info->line; /* level 6, line based priority */ + + imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + + MCFINTC_IMRL); + *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); +#if defined(CONFIG_M527x) + { + /* + * External Pin Mask Setting & Enable External Pin for Interface + * mrcbis@aliceposta.it + */ + u16 *serpin_enable_mask; + serpin_enable_mask = (u16 *) (MCF_IPSBAR + MCF_GPIO_PAR_UART); + if (info->line == 0) + *serpin_enable_mask |= UART0_ENABLE_MASK; + else if (info->line == 1) + *serpin_enable_mask |= UART1_ENABLE_MASK; + else if (info->line == 2) + *serpin_enable_mask |= UART2_ENABLE_MASK; + } +#endif +#if defined(CONFIG_M528x) + /* make sure PUAPAR is set for UART0 and UART1 */ + if (info->line < 2) { + volatile unsigned char *portp = (volatile unsigned char *) (MCF_MBAR + MCF5282_GPIO_PUAPAR); + *portp |= (0x03 << (info->line * 2)); + } +#endif +#elif defined(CONFIG_M520x) + volatile unsigned char *icrp, *uartp; + volatile unsigned long *imrp; + + uartp = info->addr; + + icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + + MCFINTC_ICR0 + MCFINT_UART0 + info->line); + *icrp = 0x03; + + imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + + MCFINTC_IMRL); + *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); + if (info->line < 2) { + unsigned short *uart_par; + uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART); + if (info->line == 0) + *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0 + | MCF_GPIO_PAR_UART_PAR_URXD0; + else if (info->line == 1) + *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1 + | MCF_GPIO_PAR_UART_PAR_URXD1; + } else if (info->line == 2) { + unsigned char *feci2c_par; + feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); + *feci2c_par &= ~0x0F; + *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 + | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; + } +#elif defined(CONFIG_M532x) + volatile unsigned char *uartp; + uartp = info->addr; + switch (info->line) { + case 0: + MCF_INTC0_ICR26 = 0x3; + MCF_INTC0_CIMR = 26; + /* GPIO initialization */ + MCF_GPIO_PAR_UART |= 0x000F; + break; + case 1: + MCF_INTC0_ICR27 = 0x3; + MCF_INTC0_CIMR = 27; + /* GPIO initialization */ + MCF_GPIO_PAR_UART |= 0x0FF0; + break; + case 2: + MCF_INTC0_ICR28 = 0x3; + MCF_INTC0_CIMR = 28; + /* GPIOs also must be initalized, depends on board */ + break; + } +#else + volatile unsigned char *icrp, *uartp; + + switch (info->line) { + case 0: + icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART1ICR); + *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | + MCFSIM_ICR_PRI1; + mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); + break; + case 1: + icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART2ICR); + *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | + MCFSIM_ICR_PRI2; + mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); + break; + default: + printk("MCFRS: don't know how to handle UART %d interrupt?\n", + info->line); + return; + } + + uartp = info->addr; + uartp[MCFUART_UIVR] = info->irq; +#endif + + /* Clear mask, so no surprise interrupts. */ + uartp[MCFUART_UIMR] = 0; + + if (request_irq(info->irq, mcfrs_interrupt, IRQF_DISABLED, + "ColdFire UART", NULL)) { + printk("MCFRS: Unable to attach ColdFire UART %d interrupt " + "vector=%d\n", info->line, info->irq); + } + + return; +} + + +char *mcfrs_drivername = "ColdFire internal UART serial driver version 1.00\n"; + + +/* + * Serial stats reporting... + */ +int mcfrs_readproc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct mcf_serial *info; + char str[20]; + int len, sigs, i; + + len = sprintf(page, mcfrs_drivername); + for (i = 0; (i < NR_PORTS); i++) { + info = &mcfrs_table[i]; + len += sprintf((page + len), "%d: port:%x irq=%d baud:%d ", + i, (unsigned int) info->addr, info->irq, info->baud); + if (info->stats.rx || info->stats.tx) + len += sprintf((page + len), "tx:%d rx:%d ", + info->stats.tx, info->stats.rx); + if (info->stats.rxframing) + len += sprintf((page + len), "fe:%d ", + info->stats.rxframing); + if (info->stats.rxparity) + len += sprintf((page + len), "pe:%d ", + info->stats.rxparity); + if (info->stats.rxbreak) + len += sprintf((page + len), "brk:%d ", + info->stats.rxbreak); + if (info->stats.rxoverrun) + len += sprintf((page + len), "oe:%d ", + info->stats.rxoverrun); + + str[0] = str[1] = 0; + if ((sigs = mcfrs_getsignals(info))) { + if (sigs & TIOCM_RTS) + strcat(str, "|RTS"); + if (sigs & TIOCM_CTS) + strcat(str, "|CTS"); + if (sigs & TIOCM_DTR) + strcat(str, "|DTR"); + if (sigs & TIOCM_CD) + strcat(str, "|CD"); + } + + len += sprintf((page + len), "%s\n", &str[1]); + } + + return(len); +} + + +/* Finally, routines used to initialize the serial driver. */ + +static void show_serial_version(void) +{ + printk(mcfrs_drivername); +} + +static const struct tty_operations mcfrs_ops = { + .open = mcfrs_open, + .close = mcfrs_close, + .write = mcfrs_write, + .flush_chars = mcfrs_flush_chars, + .write_room = mcfrs_write_room, + .chars_in_buffer = mcfrs_chars_in_buffer, + .flush_buffer = mcfrs_flush_buffer, + .ioctl = mcfrs_ioctl, + .throttle = mcfrs_throttle, + .unthrottle = mcfrs_unthrottle, + .set_termios = mcfrs_set_termios, + .stop = mcfrs_stop, + .start = mcfrs_start, + .hangup = mcfrs_hangup, + .read_proc = mcfrs_readproc, + .wait_until_sent = mcfrs_wait_until_sent, + .tiocmget = mcfrs_tiocmget, + .tiocmset = mcfrs_tiocmset, +}; + +/* mcfrs_init inits the driver */ +static int __init +mcfrs_init(void) +{ + struct mcf_serial *info; + unsigned long flags; + int i; + + /* Setup base handler, and timer table. */ +#ifdef MCFPP_DCD0 + init_timer(&mcfrs_timer_struct); + mcfrs_timer_struct.function = mcfrs_timer; + mcfrs_timer_struct.data = 0; + mcfrs_timer_struct.expires = jiffies + HZ/25; + add_timer(&mcfrs_timer_struct); + mcfrs_ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1); +#endif + mcfrs_serial_driver = alloc_tty_driver(NR_PORTS); + if (!mcfrs_serial_driver) + return -ENOMEM; + + show_serial_version(); + + /* Initialize the tty_driver structure */ + mcfrs_serial_driver->owner = THIS_MODULE; + mcfrs_serial_driver->name = "ttyS"; + mcfrs_serial_driver->driver_name = "mcfserial"; + mcfrs_serial_driver->major = TTY_MAJOR; + mcfrs_serial_driver->minor_start = 64; + mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + mcfrs_serial_driver->subtype = SERIAL_TYPE_NORMAL; + mcfrs_serial_driver->init_termios = tty_std_termios; + + mcfrs_serial_driver->init_termios.c_cflag = + mcfrs_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL; + mcfrs_serial_driver->flags = TTY_DRIVER_REAL_RAW; + + tty_set_operations(mcfrs_serial_driver, &mcfrs_ops); + + if (tty_register_driver(mcfrs_serial_driver)) { + printk("MCFRS: Couldn't register serial driver\n"); + put_tty_driver(mcfrs_serial_driver); + return(-EBUSY); + } + + local_irq_save(flags); + + /* + * Configure all the attached serial ports. + */ + for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) { + info->magic = SERIAL_MAGIC; + info->line = i; + info->port.tty = NULL; + info->custom_divisor = 16; + info->close_delay = 50; + info->closing_wait = 3000; + info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; + INIT_WORK(&info->tqueue, mcfrs_offintr); + INIT_WORK(&info->tqueue_hangup, do_serial_hangup); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + + info->imr = 0; + mcfrs_setsignals(info, 0, 0); + mcfrs_irqinit(info); + + printk("ttyS%d at 0x%04x (irq = %d)", info->line, + (unsigned int) info->addr, info->irq); + printk(" is a builtin ColdFire UART\n"); + } + + local_irq_restore(flags); + return 0; +} + +module_init(mcfrs_init); + +/****************************************************************************/ +/* Serial Console */ +/****************************************************************************/ + +/* + * Quick and dirty UART initialization, for console output. + */ + +void mcfrs_init_console(void) +{ + volatile unsigned char *uartp; + unsigned int clk; + + /* + * Reset UART, get it into known state... + */ + uartp = (volatile unsigned char *) (MCF_MBAR + + (mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1)); + + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */ + + /* + * Set port for defined baud , 8 data bits, 1 stop bit, no parity. + */ + uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; + uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; + +#ifdef CONFIG_M5272 +{ + /* + * For the MCF5272, also compute the baudrate fraction. + */ + int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud); + fraction *= 16; + fraction /= (32 * mcfrs_console_baud); + uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */ + clk = (MCF_BUSCLK / mcfrs_console_baud) / 32; +} +#else + clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */ +#endif + + uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */ + uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */ + uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; + uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; + + mcfrs_console_inited++; + return; +} + + +/* + * Setup for console. Argument comes from the boot command line. + */ + +int mcfrs_console_setup(struct console *cp, char *arg) +{ + int i, n = CONSOLE_BAUD_RATE; + + if (!cp) + return(-1); + + if (!strncmp(cp->name, "ttyS", 4)) + mcfrs_console_port = cp->index; + else if (!strncmp(cp->name, "cua", 3)) + mcfrs_console_port = cp->index; + else + return(-1); + + if (arg) + n = simple_strtoul(arg,NULL,0); + for (i = 0; i < MCFRS_BAUD_TABLE_SIZE; i++) + if (mcfrs_baud_table[i] == n) + break; + if (i < MCFRS_BAUD_TABLE_SIZE) { + mcfrs_console_baud = n; + mcfrs_console_cbaud = 0; + if (i > 15) { + mcfrs_console_cbaud |= CBAUDEX; + i -= 15; + } + mcfrs_console_cbaud |= i; + } + mcfrs_init_console(); /* make sure baud rate changes */ + return(0); +} + + +static struct tty_driver *mcfrs_console_device(struct console *c, int *index) +{ + *index = c->index; + return mcfrs_serial_driver; +} + + +/* + * Output a single character, using UART polled mode. + * This is used for console output. + */ + +int mcfrs_put_char(char ch) +{ + volatile unsigned char *uartp; + unsigned long flags; + int i; + + uartp = (volatile unsigned char *) (MCF_MBAR + + (mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1)); + + local_irq_save(flags); + for (i = 0; (i < 0x10000); i++) { + if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) + break; + } + if (i < 0x10000) { + uartp[MCFUART_UTB] = ch; + for (i = 0; (i < 0x10000); i++) + if (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY) + break; + } + if (i >= 0x10000) + mcfrs_init_console(); /* try and get it back */ + local_irq_restore(flags); + + return 1; +} + + +/* + * rs_console_write is registered for printk output. + */ + +void mcfrs_console_write(struct console *cp, const char *p, unsigned len) +{ + if (!mcfrs_console_inited) + mcfrs_init_console(); + while (len-- > 0) { + if (*p == '\n') + mcfrs_put_char('\r'); + mcfrs_put_char(*p++); + } +} + +/* + * declare our consoles + */ + +struct console mcfrs_console = { + .name = "ttyS", + .write = mcfrs_console_write, + .device = mcfrs_console_device, + .setup = mcfrs_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static int __init mcfrs_console_init(void) +{ + register_console(&mcfrs_console); + return 0; +} + +console_initcall(mcfrs_console_init); + +/****************************************************************************/ diff --git a/trunk/drivers/serial/mcfserial.h b/trunk/drivers/serial/mcfserial.h new file mode 100644 index 000000000000..56420e2cb110 --- /dev/null +++ b/trunk/drivers/serial/mcfserial.h @@ -0,0 +1,74 @@ +/* + * mcfserial.c -- serial driver for ColdFire internal UARTS. + * + * Copyright (c) 1999 Greg Ungerer + * Copyright (c) 2000-2001 Lineo, Inc. + * Copyright (c) 2002 SnapGear Inc., + * + * Based on code from 68332serial.c which was: + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 TSHG + * Copyright (c) 1999 Rt-Control Inc. + */ +#ifndef _MCF_SERIAL_H +#define _MCF_SERIAL_H + +#include + +#ifdef __KERNEL__ + +/* + * Define a local serial stats structure. + */ + +struct mcf_stats { + unsigned int rx; + unsigned int tx; + unsigned int rxbreak; + unsigned int rxframing; + unsigned int rxparity; + unsigned int rxoverrun; +}; + + +/* + * This is our internal structure for each serial port's state. + * Each serial port has one of these structures associated with it. + */ + +struct mcf_serial { + int magic; + volatile unsigned char *addr; /* UART memory address */ + int irq; + int flags; /* defined in tty.h */ + int type; /* UART type */ + struct tty_struct *tty; + unsigned char imr; /* Software imr register */ + unsigned int baud; + int sigs; + int custom_divisor; + int x_char; /* xon/xoff character */ + int baud_base; + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + unsigned long event; + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct mcf_stats stats; + struct work_struct tqueue; + struct work_struct tqueue_hangup; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + +}; + +#endif /* __KERNEL__ */ + +#endif /* _MCF_SERIAL_H */ diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index 6117d3db0b66..36126070d9af 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -72,8 +72,13 @@ #include #include #include + +#if defined(CONFIG_PPC_MERGE) #include #include +#else +#include +#endif #include #include @@ -102,11 +107,12 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM]; * it's cleared, then a memset(...,0,...) should be added to * the console_init */ - +#if defined(CONFIG_PPC_MERGE) /* lookup table for matching device nodes to index numbers */ static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM]; static void mpc52xx_uart_of_enumerate(void); +#endif #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) @@ -249,12 +255,17 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) /* Search for bus-frequency property in this node or a parent */ static unsigned long mpc52xx_getuartclk(void *p) { +#if defined(CONFIG_PPC_MERGE) /* * 5200 UARTs have a / 32 prescaler * but the generic serial code assumes 16 * so return ipb freq / 2 */ return mpc52xx_find_ipb_freq(p) / 2; +#else + pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n"); + return NULL; +#endif } static struct psc_ops mpc52xx_psc_ops = { @@ -875,6 +886,10 @@ mpc52xx_console_get_options(struct uart_port *port, /* CT{U,L}R are write-only ! */ *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; +#if !defined(CONFIG_PPC_MERGE) + if (__res.bi_baudrate) + *baud = __res.bi_baudrate; +#endif /* Parse them */ switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { @@ -931,6 +946,42 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) psc_ops->cw_restore_ints(port); } +#if !defined(CONFIG_PPC_MERGE) +static int __init +mpc52xx_console_setup(struct console *co, char *options) +{ + struct uart_port *port = &mpc52xx_uart_ports[co->index]; + + int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM) + return -EINVAL; + + /* Basic port init. Needed since we use some uart_??? func before + * real init for early access */ + spin_lock_init(&port->lock); + port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ + port->ops = &mpc52xx_uart_ops; + port->mapbase = MPC52xx_PA(MPC52xx_PSCx_OFFSET(co->index+1)); + + /* We ioremap ourself */ + port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE); + if (port->membase == NULL) + return -EINVAL; + + /* Setup the port parameters accoding to options */ + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else + mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +#else static int __init mpc52xx_console_setup(struct console *co, char *options) @@ -1002,6 +1053,7 @@ mpc52xx_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } +#endif /* defined(CONFIG_PPC_MERGE) */ static struct uart_driver mpc52xx_uart_driver; @@ -1020,7 +1072,9 @@ static struct console mpc52xx_console = { static int __init mpc52xx_console_init(void) { +#if defined(CONFIG_PPC_MERGE) mpc52xx_uart_of_enumerate(); +#endif register_console(&mpc52xx_console); return 0; } @@ -1046,6 +1100,115 @@ static struct uart_driver mpc52xx_uart_driver = { .cons = MPC52xx_PSC_CONSOLE, }; + +#if !defined(CONFIG_PPC_MERGE) +/* ======================================================================== */ +/* Platform Driver */ +/* ======================================================================== */ + +static int __devinit +mpc52xx_uart_probe(struct platform_device *dev) +{ + struct resource *res = dev->resource; + + struct uart_port *port = NULL; + int i, idx, ret; + + /* Check validity & presence */ + idx = dev->id; + if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) + return -EINVAL; + + if (!mpc52xx_match_psc_function(idx, "uart")) + return -ENODEV; + + /* Init the port structure */ + port = &mpc52xx_uart_ports[idx]; + + spin_lock_init(&port->lock); + port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ + port->fifosize = 512; + port->iotype = UPIO_MEM; + port->flags = UPF_BOOT_AUTOCONF | + (uart_console(port) ? 0 : UPF_IOREMAP); + port->line = idx; + port->ops = &mpc52xx_uart_ops; + port->dev = &dev->dev; + + /* Search for IRQ and mapbase */ + for (i = 0 ; i < dev->num_resources ; i++, res++) { + if (res->flags & IORESOURCE_MEM) + port->mapbase = res->start; + else if (res->flags & IORESOURCE_IRQ) + port->irq = res->start; + } + if (!port->irq || !port->mapbase) + return -EINVAL; + + /* Add the port to the uart sub-system */ + ret = uart_add_one_port(&mpc52xx_uart_driver, port); + if (!ret) + platform_set_drvdata(dev, (void *)port); + + return ret; +} + +static int +mpc52xx_uart_remove(struct platform_device *dev) +{ + struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev); + + platform_set_drvdata(dev, NULL); + + if (port) + uart_remove_one_port(&mpc52xx_uart_driver, port); + + return 0; +} + +#ifdef CONFIG_PM +static int +mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state) +{ + struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev); + + if (port) + uart_suspend_port(&mpc52xx_uart_driver, port); + + return 0; +} + +static int +mpc52xx_uart_resume(struct platform_device *dev) +{ + struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev); + + if (port) + uart_resume_port(&mpc52xx_uart_driver, port); + + return 0; +} +#endif + +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:mpc52xx-psc"); + +static struct platform_driver mpc52xx_uart_platform_driver = { + .probe = mpc52xx_uart_probe, + .remove = mpc52xx_uart_remove, +#ifdef CONFIG_PM + .suspend = mpc52xx_uart_suspend, + .resume = mpc52xx_uart_resume, +#endif + .driver = { + .owner = THIS_MODULE, + .name = "mpc52xx-psc", + }, +}; +#endif /* !defined(CONFIG_PPC_MERGE) */ + + +#if defined(CONFIG_PPC_MERGE) /* ======================================================================== */ /* OF Platform Driver */ /* ======================================================================== */ @@ -1239,6 +1402,7 @@ static struct of_platform_driver mpc52xx_uart_of_driver = { .name = "mpc52xx-psc-uart", }, }; +#endif /* defined(CONFIG_PPC_MERGE) */ /* ======================================================================== */ @@ -1259,6 +1423,7 @@ mpc52xx_uart_init(void) return ret; } +#if defined(CONFIG_PPC_MERGE) mpc52xx_uart_of_enumerate(); ret = of_register_platform_driver(&mpc52xx_uart_of_driver); @@ -1268,6 +1433,16 @@ mpc52xx_uart_init(void) uart_unregister_driver(&mpc52xx_uart_driver); return ret; } +#else + psc_ops = &mpc52xx_psc_ops; + ret = platform_driver_register(&mpc52xx_uart_platform_driver); + if (ret) { + printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", + __FILE__, ret); + uart_unregister_driver(&mpc52xx_uart_driver); + return ret; + } +#endif return 0; } @@ -1275,7 +1450,11 @@ mpc52xx_uart_init(void) static void __exit mpc52xx_uart_exit(void) { +#if defined(CONFIG_PPC_MERGE) of_unregister_platform_driver(&mpc52xx_uart_of_driver); +#else + platform_driver_unregister(&mpc52xx_uart_platform_driver); +#endif uart_unregister_driver(&mpc52xx_uart_driver); } diff --git a/trunk/drivers/serial/s3c2400.c b/trunk/drivers/serial/s3c2400.c index 4873f2978bd2..c8b4266ac35f 100644 --- a/trunk/drivers/serial/s3c2400.c +++ b/trunk/drivers/serial/s3c2400.c @@ -19,7 +19,7 @@ #include -#include +#include #include #include "samsung.h" diff --git a/trunk/drivers/serial/s3c2410.c b/trunk/drivers/serial/s3c2410.c index 87c182ef71b8..40a2531b5541 100644 --- a/trunk/drivers/serial/s3c2410.c +++ b/trunk/drivers/serial/s3c2410.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "samsung.h" diff --git a/trunk/drivers/serial/s3c2412.c b/trunk/drivers/serial/s3c2412.c index fd017b375568..d0170319c729 100644 --- a/trunk/drivers/serial/s3c2412.c +++ b/trunk/drivers/serial/s3c2412.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "samsung.h" diff --git a/trunk/drivers/serial/s3c2440.c b/trunk/drivers/serial/s3c2440.c index 317d239ab740..d4a2b17b2498 100644 --- a/trunk/drivers/serial/s3c2440.c +++ b/trunk/drivers/serial/s3c2440.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "samsung.h" diff --git a/trunk/drivers/serial/samsung.c b/trunk/drivers/serial/samsung.c index 1e219d3d0352..5a88b3f9fe9b 100644 --- a/trunk/drivers/serial/samsung.c +++ b/trunk/drivers/serial/samsung.c @@ -47,7 +47,7 @@ #include -#include +#include #include #include "samsung.h" diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 6bdf3362e3b1..f977c98cfa95 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -2051,8 +2051,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) "transmitter\n", port->dev ? port->dev->bus_id : "", port->dev ? ": " : "", - drv->dev_name, - drv->tty_driver->name_base + port->line); + drv->dev_name, port->line); ops->shutdown(port); } @@ -2155,11 +2154,12 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) switch (port->iotype) { case UPIO_PORT: - snprintf(address, sizeof(address), "I/O 0x%lx", port->iobase); + snprintf(address, sizeof(address), + "I/O 0x%x", port->iobase); break; case UPIO_HUB6: snprintf(address, sizeof(address), - "I/O 0x%lx offset 0x%x", port->iobase, port->hub6); + "I/O 0x%x offset 0x%x", port->iobase, port->hub6); break; case UPIO_MEM: case UPIO_MEM32: @@ -2177,9 +2177,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n", port->dev ? port->dev->bus_id : "", port->dev ? ": " : "", - drv->dev_name, - drv->tty_driver->name_base + port->line, - address, port->irq, uart_type(port)); + drv->dev_name, port->line, address, port->irq, uart_type(port)); } static void diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index 7546aa887fa7..164d2a42eb59 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -431,103 +431,131 @@ first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) { int i; i = pcmcia_get_first_tuple(handle, tuple); - if (i != 0) - return i; + if (i != CS_SUCCESS) + return CS_NO_MORE_ITEMS; i = pcmcia_get_tuple_data(handle, tuple); - if (i != 0) + if (i != CS_SUCCESS) return i; - return pcmcia_parse_tuple(tuple, parse); + return pcmcia_parse_tuple(handle, tuple, parse); } -/*====================================================================*/ - -static int simple_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int +next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) { - static const int size_table[2] = { 8, 16 }; - int *try = priv_data; - - if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - p_dev->conf.Vpp = - cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; - - if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)]) - && (cf->io.win[0].base != 0)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ? - 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -EINVAL; + int i; + i = pcmcia_get_next_tuple(handle, tuple); + if (i != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) + return i; + return pcmcia_parse_tuple(handle, tuple, parse); } -static int simple_config_check_notpicky(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; - int j; - - if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { - for (j = 0; j < 5; j++) { - p_dev->io.BasePort1 = base[j]; - p_dev->io.IOAddrLines = base[j] ? 16 : 3; - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - } - return -ENODEV; -} +/*====================================================================*/ static int simple_config(struct pcmcia_device *link) { + static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; + static const int size_table[2] = { 8, 16 }; struct serial_info *info = link->priv; - int i = -ENODEV, try; + struct serial_cfg_mem *cfg_mem; + tuple_t *tuple; + u_char *buf; + cisparse_t *parse; + cistpl_cftable_entry_t *cf; + config_info_t config; + int i, j, try; + int s; + + cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); + if (!cfg_mem) + return -1; + + tuple = &cfg_mem->tuple; + parse = &cfg_mem->parse; + cf = &parse->cftable_entry; + buf = cfg_mem->buf; /* If the card is already configured, look up the port and irq */ - if (link->function_config) { + i = pcmcia_get_configuration_info(link, &config); + if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { unsigned int port = 0; - if ((link->io.BasePort2 != 0) && - (link->io.NumPorts2 == 8)) { - port = link->io.BasePort2; + if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { + port = config.BasePort2; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && - (link->io.NumPorts1 == 0x40)) { - port = link->io.BasePort1 + 0x28; + (config.NumPorts1 == 0x40)) { + port = config.BasePort1 + 0x28; info->slave = 1; } if (info->slave) { - return setup_serial(link, info, port, - link->irq.AssignedIRQ); + kfree(cfg_mem); + return setup_serial(link, info, port, config.AssignedIRQ); } } - /* First pass: look for a config entry that looks normal. - * Two tries: without IO aliases, then with aliases */ - for (try = 0; try < 4; try++) - if (!pcmcia_loop_config(link, simple_config_check, &try)) - goto found_port; - + /* First pass: look for a config entry that looks normal. */ + tuple->TupleData = (cisdata_t *) buf; + tuple->TupleOffset = 0; + tuple->TupleDataMax = 255; + tuple->Attributes = 0; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + /* Two tries: without IO aliases, then with aliases */ + for (s = 0; s < 2; s++) { + for (try = 0; try < 2; try++) { + i = first_tuple(link, tuple, parse); + while (i != CS_NO_MORE_ITEMS) { + if (i != CS_SUCCESS) + goto next_entry; + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp = + cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && + (cf->io.win[0].base != 0)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = (try == 0) ? + 16 : cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + goto found_port; + } +next_entry: + i = next_tuple(link, tuple, parse); + } + } + } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) - goto found_port; + i = first_tuple(link, tuple, parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && + ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { + link->conf.ConfigIndex = cf->index; + for (j = 0; j < 5; j++) { + link->io.BasePort1 = base[j]; + link->io.IOAddrLines = base[j] ? 16 : 3; + i = pcmcia_request_io(link, &link->io); + if (i == CS_SUCCESS) + goto found_port; + } + } + i = next_tuple(link, tuple, parse); + } - printk(KERN_NOTICE - "serial_cs: no usable port range found, giving up\n"); - cs_error(link, RequestIO, i); - return -1; + found_port: + if (i != CS_SUCCESS) { + printk(KERN_NOTICE + "serial_cs: no usable port range found, giving up\n"); + cs_error(link, RequestIO, i); + kfree(cfg_mem); + return -1; + } -found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } @@ -541,76 +569,88 @@ static int simple_config(struct pcmcia_device *link) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); + kfree(cfg_mem); return -1; } + kfree(cfg_mem); return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); } -static int multi_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int multi_config(struct pcmcia_device * link) { - int *base2 = priv_data; - - /* The quad port cards have bad CIS's, so just look for a - window larger than 8 ports and assume it will be right */ - if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) { - *base2 = p_dev->io.BasePort1 + 8; - return 0; - } - } - return -ENODEV; -} + struct serial_info *info = link->priv; + struct serial_cfg_mem *cfg_mem; + tuple_t *tuple; + u_char *buf; + cisparse_t *parse; + cistpl_cftable_entry_t *cf; + int i, rc, base2 = 0; -static int multi_config_check_notpicky(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cf, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - int *base2 = priv_data; - - if (cf->io.nwin == 2) { - p_dev->io.BasePort1 = cf->io.win[0].base; - p_dev->io.BasePort2 = cf->io.win[1].base; - p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - if (!pcmcia_request_io(p_dev, &p_dev->io)) { - *base2 = p_dev->io.BasePort2; - return 0; - } - } - return -ENODEV; -} + cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); + if (!cfg_mem) + return -1; + tuple = &cfg_mem->tuple; + parse = &cfg_mem->parse; + cf = &parse->cftable_entry; + buf = cfg_mem->buf; -static int multi_config(struct pcmcia_device *link) -{ - struct serial_info *info = link->priv; - int i, base2 = 0; + tuple->TupleData = (cisdata_t *) buf; + tuple->TupleOffset = 0; + tuple->TupleDataMax = 255; + tuple->Attributes = 0; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; - if (pcmcia_loop_config(link, multi_config_check, &base2)) { - /* If that didn't work, look for two windows */ + i = first_tuple(link, tuple, parse); + while (i != CS_NO_MORE_ITEMS) { + /* The quad port cards have bad CIS's, so just look for a + window larger than 8 ports and assume it will be right */ + if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && + (cf->io.win[0].len > 8)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = + cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + base2 = link->io.BasePort1 + 8; + if (i == CS_SUCCESS) + break; + } + i = next_tuple(link, tuple, parse); + } + + /* If that didn't work, look for two windows */ + if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; - if (pcmcia_loop_config(link, multi_config_check_notpicky, - &base2)) { - printk(KERN_NOTICE "serial_cs: no usable port range" - "found, giving up\n"); - return -ENODEV; + i = first_tuple(link, tuple, parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.BasePort2 = cf->io.win[1].base; + link->io.IOAddrLines = + cf->io.flags & CISTPL_IO_LINES_MASK; + i = pcmcia_request_io(link, &link->io); + base2 = link->io.BasePort2; + if (i == CS_SUCCESS) + break; + } + i = next_tuple(link, tuple, parse); } } + if (i != CS_SUCCESS) { + cs_error(link, RequestIO, i); + rc = -1; + goto free_cfg_mem; + } + i = pcmcia_request_irq(link, &link->irq); - if (i != 0) { - /* FIXME: comment does not fit, error handling does not fit */ + if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link, RequestIRQ, i); @@ -624,9 +664,10 @@ static int multi_config(struct pcmcia_device *link) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) { + if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); - return -ENODEV; + rc = -1; + goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: @@ -637,8 +678,7 @@ static int multi_config(struct pcmcia_device *link) info->prodid == PRODID_POSSIO_GCC)) { int err; - if (link->conf.ConfigIndex == 1 || - link->conf.ConfigIndex == 3) { + if (cf->index == 1 || cf->index == 3) { err = setup_serial(link, info, base2, link->irq.AssignedIRQ); base2 = link->io.BasePort1; @@ -655,14 +695,18 @@ static int multi_config(struct pcmcia_device *link) if (info->quirk && info->quirk->wakeup) info->quirk->wakeup(link); - return 0; + rc = 0; + goto free_cfg_mem; } setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); for (i = 0; i < info->multi - 1; i++) setup_serial(link, info, base2 + (8 * i), link->irq.AssignedIRQ); - return 0; + rc = 0; +free_cfg_mem: + kfree(cfg_mem); + return rc; } /*====================================================================== @@ -702,7 +746,7 @@ static int serial_config(struct pcmcia_device * link) /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; - info->multi = (first_tuple(link, tuple, parse) == 0); + info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS); /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; @@ -726,7 +770,7 @@ static int serial_config(struct pcmcia_device * link) ((link->func_id == CISTPL_FUNCID_MULTI) || (link->func_id == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - if (first_tuple(link, tuple, parse) == 0) { + if (first_tuple(link, tuple, parse) == CS_SUCCESS) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) info->multi = cf->io.win[0].len >> 3; if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && diff --git a/trunk/drivers/serial/ucc_uart.c b/trunk/drivers/serial/ucc_uart.c index 539c933b335f..5c5d18dcb6ac 100644 --- a/trunk/drivers/serial/ucc_uart.c +++ b/trunk/drivers/serial/ucc_uart.c @@ -1009,7 +1009,7 @@ static int qe_uart_request_port(struct uart_port *port) rx_size = L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize); tx_size = L1_CACHE_ALIGN(qe_port->tx_nrfifos * qe_port->tx_fifosize); - bd_virt = dma_alloc_coherent(port->dev, rx_size + tx_size, &bd_dma_addr, + bd_virt = dma_alloc_coherent(NULL, rx_size + tx_size, &bd_dma_addr, GFP_KERNEL); if (!bd_virt) { dev_err(port->dev, "could not allocate buffer descriptors\n"); @@ -1051,7 +1051,7 @@ static void qe_uart_release_port(struct uart_port *port) container_of(port, struct uart_qe_port, port); struct ucc_slow_private *uccs = qe_port->us_private; - dma_free_coherent(port->dev, qe_port->bd_size, qe_port->bd_virt, + dma_free_coherent(NULL, qe_port->bd_size, qe_port->bd_virt, qe_port->bd_dma_addr); ucc_slow_free(uccs); diff --git a/trunk/drivers/spi/mpc52xx_psc_spi.c b/trunk/drivers/spi/mpc52xx_psc_spi.c index 0debe11b67b4..25eda71f4bf4 100644 --- a/trunk/drivers/spi/mpc52xx_psc_spi.c +++ b/trunk/drivers/spi/mpc52xx_psc_spi.c @@ -15,7 +15,13 @@ #include #include #include + +#if defined(CONFIG_PPC_MERGE) #include +#else +#include +#endif + #include #include #include @@ -102,13 +108,13 @@ static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi) * Because psc->ccr is defined as 16bit register instead of 32bit * just set the lower byte of BitClkDiv */ - ccr = in_be16((u16 __iomem *)&psc->ccr); + ccr = in_be16(&psc->ccr); ccr &= 0xFF00; if (cs->speed_hz) ccr |= (MCLK / cs->speed_hz - 1) & 0xFF; else /* by default SPI Clk 1MHz */ ccr |= (MCLK / 1000000 - 1) & 0xFF; - out_be16((u16 __iomem *)&psc->ccr, ccr); + out_be16(&psc->ccr, ccr); mps->bits_per_word = cs->bits_per_word; if (mps->activate_cs) @@ -341,7 +347,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) /* Configure 8bit codec mode as a SPI master and use EOF flags */ /* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */ out_be32(&psc->sicr, 0x0180C800); - out_be16((u16 __iomem *)&psc->ccr, 0x070F); /* default SPI Clk 1MHz */ + out_be16(&psc->ccr, 0x070F); /* by default SPI Clk 1MHz */ /* Set 2ms DTL delay */ out_8(&psc->ctur, 0x00); @@ -465,6 +471,53 @@ static int __exit mpc52xx_psc_spi_do_remove(struct device *dev) return 0; } +#if !defined(CONFIG_PPC_MERGE) +static int __init mpc52xx_psc_spi_probe(struct platform_device *dev) +{ + switch(dev->id) { + case 1: + case 2: + case 3: + case 6: + return mpc52xx_psc_spi_do_probe(&dev->dev, + MPC52xx_PA(MPC52xx_PSCx_OFFSET(dev->id)), + MPC52xx_PSC_SIZE, platform_get_irq(dev, 0), dev->id); + default: + return -EINVAL; + } +} + +static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev) +{ + return mpc52xx_psc_spi_do_remove(&dev->dev); +} + +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:mpc52xx-psc-spi"); + +static struct platform_driver mpc52xx_psc_spi_platform_driver = { + .remove = __exit_p(mpc52xx_psc_spi_remove), + .driver = { + .name = "mpc52xx-psc-spi", + .owner = THIS_MODULE, + }, +}; + +static int __init mpc52xx_psc_spi_init(void) +{ + return platform_driver_probe(&mpc52xx_psc_spi_platform_driver, + mpc52xx_psc_spi_probe); +} +module_init(mpc52xx_psc_spi_init); + +static void __exit mpc52xx_psc_spi_exit(void) +{ + platform_driver_unregister(&mpc52xx_psc_spi_platform_driver); +} +module_exit(mpc52xx_psc_spi_exit); + +#else /* defined(CONFIG_PPC_MERGE) */ + static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, const struct of_device_id *match) { @@ -533,6 +586,8 @@ static void __exit mpc52xx_psc_spi_exit(void) } module_exit(mpc52xx_psc_spi_exit); +#endif /* defined(CONFIG_PPC_MERGE) */ + MODULE_AUTHOR("Dragos Carp"); MODULE_DESCRIPTION("MPC52xx PSC SPI Driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/omap2_mcspi.c b/trunk/drivers/spi/omap2_mcspi.c index 454a2712e629..9d2186fd74aa 100644 --- a/trunk/drivers/spi/omap2_mcspi.c +++ b/trunk/drivers/spi/omap2_mcspi.c @@ -119,14 +119,12 @@ struct omap2_mcspi { struct clk *fck; /* Virtual base address of the controller */ void __iomem *base; - unsigned long phys; /* SPI1 has 4 channels, while SPI2 has 2 */ struct omap2_mcspi_dma *dma_channels; }; struct omap2_mcspi_cs { void __iomem *base; - unsigned long phys; int word_len; }; @@ -235,7 +233,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) c = count; word_len = cs->word_len; - base = cs->phys; + base = (unsigned long) io_v2p(cs->base); tx_reg = base + OMAP2_MCSPI_TX0; rx_reg = base + OMAP2_MCSPI_RX0; rx = xfer->rx_buf; @@ -635,7 +633,6 @@ static int omap2_mcspi_setup(struct spi_device *spi) if (!cs) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; - cs->phys = mcspi->phys + spi->chip_select * 0x14; spi->controller_state = cs; } @@ -1008,13 +1005,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) goto err1; } - mcspi->phys = r->start; - mcspi->base = ioremap(r->start, r->end - r->start + 1); - if (!mcspi->base) { - dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); - status = -ENOMEM; - goto err1aa; - } + mcspi->base = (void __iomem *) io_p2v(r->start); INIT_WORK(&mcspi->work, omap2_mcspi_work); @@ -1064,8 +1055,6 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) err2: clk_put(mcspi->ick); err1a: - iounmap(mcspi->base); -err1aa: release_mem_region(r->start, (r->end - r->start) + 1); err1: spi_master_put(master); @@ -1078,7 +1067,6 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *dma_channels; struct resource *r; - void __iomem *base; master = dev_get_drvdata(&pdev->dev); mcspi = spi_master_get_devdata(master); @@ -1090,9 +1078,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(r->start, (r->end - r->start) + 1); - base = mcspi->base; spi_unregister_master(master); - iounmap(base); kfree(dma_channels); return 0; diff --git a/trunk/drivers/spi/omap_uwire.c b/trunk/drivers/spi/omap_uwire.c index bab6ff061e91..5515eb97d7c5 100644 --- a/trunk/drivers/spi/omap_uwire.c +++ b/trunk/drivers/spi/omap_uwire.c @@ -59,6 +59,7 @@ * and irqs should show there too... */ #define UWIRE_BASE_PHYS 0xFFFB3000 +#define UWIRE_BASE ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS)) /* uWire Registers: */ #define UWIRE_IO_SIZE 0x20 @@ -102,21 +103,16 @@ struct uwire_state { }; /* REVISIT compile time constant for idx_shift? */ -/* - * Or, put it in a structure which is used throughout the driver; - * that avoids having to issue two loads for each bit of static data. - */ static unsigned int uwire_idx_shift; -static void __iomem *uwire_base; static inline void uwire_write_reg(int idx, u16 val) { - __raw_writew(val, uwire_base + (idx << uwire_idx_shift)); + __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift)); } static inline u16 uwire_read_reg(int idx) { - return __raw_readw(uwire_base + (idx << uwire_idx_shift)); + return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift)); } static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags) @@ -496,14 +492,6 @@ static int __init uwire_probe(struct platform_device *pdev) return -ENODEV; uwire = spi_master_get_devdata(master); - - uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE); - if (!uwire_base) { - dev_dbg(&pdev->dev, "can't ioremap UWIRE\n"); - spi_master_put(master); - return -ENOMEM; - } - dev_set_drvdata(&pdev->dev, uwire); uwire->ck = clk_get(&pdev->dev, "armxor_ck"); @@ -532,10 +520,8 @@ static int __init uwire_probe(struct platform_device *pdev) uwire->bitbang.txrx_bufs = uwire_txrx; status = spi_bitbang_start(&uwire->bitbang); - if (status < 0) { + if (status < 0) uwire_off(uwire); - iounmap(uwire_base); - } return status; } @@ -548,7 +534,6 @@ static int __exit uwire_remove(struct platform_device *pdev) status = spi_bitbang_stop(&uwire->bitbang); uwire_off(uwire); - iounmap(uwire_base); return status; } diff --git a/trunk/drivers/spi/orion_spi.c b/trunk/drivers/spi/orion_spi.c index 014becb7d530..b872bfaf4bd2 100644 --- a/trunk/drivers/spi/orion_spi.c +++ b/trunk/drivers/spi/orion_spi.c @@ -364,11 +364,6 @@ static int orion_spi_setup(struct spi_device *spi) return -EINVAL; } - /* Fix ac timing if required. */ - if (orion_spi->spi_info->enable_clock_fix) - orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, - (1 << 14)); - if (spi->bits_per_word == 0) spi->bits_per_word = 8; diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c index dae87b1a4c6e..d47d3636227f 100644 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ b/trunk/drivers/spi/pxa2xx_spi.c @@ -47,10 +47,6 @@ MODULE_ALIAS("platform:pxa2xx-spi"); #define MAX_BUSES 3 -#define RX_THRESH_DFLT 8 -#define TX_THRESH_DFLT 8 -#define TIMOUT_DFLT 1000 - #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) #define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0) @@ -1175,8 +1171,6 @@ static int setup(struct spi_device *spi) struct driver_data *drv_data = spi_master_get_devdata(spi->master); struct ssp_device *ssp = drv_data->ssp; unsigned int clk_div; - uint tx_thres = TX_THRESH_DFLT; - uint rx_thres = RX_THRESH_DFLT; if (!spi->bits_per_word) spi->bits_per_word = 8; @@ -1215,7 +1209,8 @@ static int setup(struct spi_device *spi) chip->cs_control = null_cs_control; chip->enable_dma = 0; - chip->timeout = TIMOUT_DFLT; + chip->timeout = 1000; + chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1); chip->dma_burst_size = drv_data->master_info->enable_dma ? DCMD_BURST8 : 0; } @@ -1229,21 +1224,22 @@ static int setup(struct spi_device *spi) if (chip_info) { if (chip_info->cs_control) chip->cs_control = chip_info->cs_control; - if (chip_info->timeout) - chip->timeout = chip_info->timeout; - if (chip_info->tx_threshold) - tx_thres = chip_info->tx_threshold; - if (chip_info->rx_threshold) - rx_thres = chip_info->rx_threshold; - chip->enable_dma = drv_data->master_info->enable_dma; + + chip->timeout = chip_info->timeout; + + chip->threshold = (SSCR1_RxTresh(chip_info->rx_threshold) & + SSCR1_RFT) | + (SSCR1_TxTresh(chip_info->tx_threshold) & + SSCR1_TFT); + + chip->enable_dma = chip_info->dma_burst_size != 0 + && drv_data->master_info->enable_dma; chip->dma_threshold = 0; + if (chip_info->enable_loopback) chip->cr1 = SSCR1_LBM; } - chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | - (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); - /* set dma burst and threshold outside of chip_info path so that if * chip_info goes away after setting chip->enable_dma, the * burst and threshold can still respond to changes in bits_per_word */ @@ -1272,19 +1268,17 @@ static int setup(struct spi_device *spi) /* NOTE: PXA25x_SSP _could_ use external clocking ... */ if (drv_data->ssp_type != PXA25x_SSP) - dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n", + dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n", spi->bits_per_word, clk_get_rate(ssp->clk) / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3, - chip->enable_dma ? "DMA" : "PIO"); + spi->mode & 0x3); else - dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n", + dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n", spi->bits_per_word, - clk_get_rate(ssp->clk) / 2 + clk_get_rate(ssp->clk) / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3, - chip->enable_dma ? "DMA" : "PIO"); + spi->mode & 0x3); if (spi->bits_per_word <= 8) { chip->n_bytes = 1; @@ -1413,9 +1407,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct pxa2xx_spi_master *platform_info; struct spi_master *master; - struct driver_data *drv_data; + struct driver_data *drv_data = NULL; struct ssp_device *ssp; - int status; + int status = 0; platform_info = dev->platform_data; @@ -1428,7 +1422,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) /* Allocate master with space for drv_data and null dma buffer */ master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); if (!master) { - dev_err(&pdev->dev, "cannot alloc spi_master\n"); + dev_err(&pdev->dev, "can not alloc spi_master\n"); ssp_free(ssp); return -ENOMEM; } @@ -1464,7 +1458,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data); if (status < 0) { - dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq); + dev_err(&pdev->dev, "can not get IRQ\n"); goto out_error_master_alloc; } @@ -1504,9 +1498,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) /* Load default SSP configuration */ write_SSCR0(0, drv_data->ioaddr); - write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) | - SSCR1_TxTresh(TX_THRESH_DFLT), - drv_data->ioaddr); + write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr); write_SSCR0(SSCR0_SerClkDiv(2) | SSCR0_Motorola | SSCR0_DataSize(8), diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 3734dc9708e1..75e86865234c 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_device *spi, int status; struct spi_message message; - struct spi_transfer x; + struct spi_transfer x[2]; u8 *local_buf; /* Use preallocated DMA-safe buffer. We can't avoid copying here, @@ -671,9 +671,15 @@ int spi_write_then_read(struct spi_device *spi, return -EINVAL; spi_message_init(&message); - memset(&x, 0, sizeof x); - x.len = n_tx + n_rx; - spi_message_add_tail(&x, &message); + memset(x, 0, sizeof x); + if (n_tx) { + x[0].len = n_tx; + spi_message_add_tail(&x[0], &message); + } + if (n_rx) { + x[1].len = n_rx; + spi_message_add_tail(&x[1], &message); + } /* ... unless someone else is using the pre-allocated buffer */ if (!mutex_trylock(&lock)) { @@ -684,15 +690,15 @@ int spi_write_then_read(struct spi_device *spi, local_buf = buf; memcpy(local_buf, txbuf, n_tx); - x.tx_buf = local_buf; - x.rx_buf = local_buf; + x[0].tx_buf = local_buf; + x[1].rx_buf = local_buf + n_tx; /* do the i/o */ status = spi_sync(spi, &message); if (status == 0) - memcpy(rxbuf, x.rx_buf + n_tx, n_rx); + memcpy(rxbuf, x[1].rx_buf, n_rx); - if (x.tx_buf == buf) + if (x[0].tx_buf == buf) mutex_unlock(&lock); else kfree(local_buf); @@ -738,5 +744,5 @@ static int __init spi_init(void) * driver registration) _could_ be dynamically linked (modular) ... costs * include needing to have boardinfo data structures be much more public. */ -postcore_initcall(spi_init); +subsys_initcall(spi_init); diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index c252cbac00f1..3eb414b84a9d 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -247,9 +247,6 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw) writeb(0xff, hw->regs + S3C2410_SPPRE); writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); - - if (hw->pdata && hw->pdata->gpio_setup) - hw->pdata->gpio_setup(hw->pdata, 1); } static int __init s3c24xx_spi_probe(struct platform_device *pdev) @@ -415,9 +412,6 @@ static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg) { struct s3c24xx_spi *hw = platform_get_drvdata(pdev); - if (hw->pdata && hw->pdata->gpio_setup) - hw->pdata->gpio_setup(hw->pdata, 0); - clk_disable(hw->clk); return 0; } diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index 89a43755a453..e5e0cfed5e3b 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -583,9 +583,10 @@ static int spidev_probe(struct spi_device *spi) struct device *dev; spidev->devt = MKDEV(SPIDEV_MAJOR, minor); - dev = device_create(spidev_class, &spi->dev, spidev->devt, - spidev, "spidev%d.%d", - spi->master->bus_num, spi->chip_select); + dev = device_create_drvdata(spidev_class, &spi->dev, + spidev->devt, spidev, + "spidev%d.%d", + spi->master->bus_num, spi->chip_select); status = IS_ERR(dev) ? PTR_ERR(dev) : 0; } else { dev_dbg(&spi->dev, "no minor number available!\n"); diff --git a/trunk/drivers/ssb/pcmcia.c b/trunk/drivers/ssb/pcmcia.c index fbfadbac67e8..24c2a46c1476 100644 --- a/trunk/drivers/ssb/pcmcia.c +++ b/trunk/drivers/ssb/pcmcia.c @@ -80,7 +80,7 @@ static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value) reg.Action = CS_WRITE; reg.Value = value; res = pcmcia_access_configuration_register(bus->host_pcmcia, ®); - if (unlikely(res != 0)) + if (unlikely(res != CS_SUCCESS)) return -EBUSY; return 0; @@ -96,7 +96,7 @@ static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value) reg.Offset = offset; reg.Action = CS_READ; res = pcmcia_access_configuration_register(bus->host_pcmcia, ®); - if (unlikely(res != 0)) + if (unlikely(res != CS_SUCCESS)) return -EBUSY; *value = reg.Value; @@ -638,17 +638,17 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "MAC first tpl"); + GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "MAC first tpl data"); + GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data"); while (1) { GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1"); if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID) break; res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "MAC next tpl"); + GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "MAC next tpl data"); + GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data"); } GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size"); memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN); @@ -659,9 +659,9 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "VEN first tpl"); + GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "VEN first tpl data"); + GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data"); while (1) { GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1"); switch (tuple.TupleData[0]) { @@ -733,11 +733,11 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, break; } res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple); - if (res == -ENOSPC) + if (res == CS_NO_MORE_ITEMS) break; - GOTO_ERROR_ON(res != 0, "VEN next tpl"); + GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != 0, "VEN next tpl data"); + GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data"); } return 0; diff --git a/trunk/drivers/telephony/ixj.c b/trunk/drivers/telephony/ixj.c index 41b6530b8f25..ec7aeb502d15 100644 --- a/trunk/drivers/telephony/ixj.c +++ b/trunk/drivers/telephony/ixj.c @@ -42,6 +42,8 @@ ***************************************************************************/ /* + * $Log: ixj.c,v $ + * * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci * Audit some copy_*_user and minor cleanup. * diff --git a/trunk/drivers/telephony/ixj_pcmcia.c b/trunk/drivers/telephony/ixj_pcmcia.c index 347c3ed1d9f1..ff9a29b76336 100644 --- a/trunk/drivers/telephony/ixj_pcmcia.c +++ b/trunk/drivers/telephony/ixj_pcmcia.c @@ -124,53 +124,65 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) return; } -static int ixj_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin == 2) { - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - if (!pcmcia_request_io(p_dev, &p_dev->io)) - return 0; - } - return -ENODEV; -} - static int ixj_config(struct pcmcia_device * link) { IXJ *j; ixj_info_t *info; - cistpl_cftable_entry_t dflt = { 0 }; - + tuple_t tuple; + u_short buf[128]; + cisparse_t parse; + cistpl_cftable_entry_t *cfg = &parse.cftable_entry; + cistpl_cftable_entry_t dflt = + { + 0 + }; + int last_ret, last_fn; info = link->priv; DEBUG(0, "ixj_config(0x%p)\n", link); + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + if (pcmcia_get_tuple_data(link, &tuple) != 0 || + pcmcia_parse_tuple(link, &tuple, &parse) != 0) + goto next_entry; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->conf.ConfigIndex = cfg->index; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + if (io->nwin == 2) { + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = io->win[1].len; + } + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + /* If we've got this far, we're done */ + break; + } + next_entry: + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + dflt = *cfg; + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + } - if (pcmcia_loop_config(link, ixj_config_check, &dflt)) - goto cs_failed; - - if (pcmcia_request_configuration(link, &link->conf)) - goto cs_failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* * Register the card with the core. - */ - j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10); + */ + j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10); info->ndev = 1; info->node.major = PHONE_MAJOR; link->dev_node = &info->node; ixj_get_serial(link, j); return 0; - cs_failed: + cs_error(link, last_fn, last_ret); ixj_cs_release(link); return -ENODEV; } diff --git a/trunk/drivers/uio/Kconfig b/trunk/drivers/uio/Kconfig index 04b954cfce76..4190be64917f 100644 --- a/trunk/drivers/uio/Kconfig +++ b/trunk/drivers/uio/Kconfig @@ -58,17 +58,4 @@ config UIO_SMX If you compile this as a module, it will be called uio_smx. -config UIO_SERCOS3 - tristate "Automata Sercos III PCI card driver" - default n - help - Userspace I/O interface for the Sercos III PCI card from - Automata GmbH. The userspace part of this driver will be - available for download from the Automata GmbH web site. - - Automata GmbH: http://www.automataweb.com - Sercos III interface: http://www.sercos.com - - If you compile this as a module, it will be called uio_sercos3. - endif diff --git a/trunk/drivers/uio/Makefile b/trunk/drivers/uio/Makefile index e69558149859..8667bbdef904 100644 --- a/trunk/drivers/uio/Makefile +++ b/trunk/drivers/uio/Makefile @@ -3,4 +3,3 @@ obj-$(CONFIG_UIO_CIF) += uio_cif.o obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o obj-$(CONFIG_UIO_SMX) += uio_smx.o -obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o diff --git a/trunk/drivers/uio/uio.c b/trunk/drivers/uio/uio.c index 5dccf057a7dd..3a6934bf7131 100644 --- a/trunk/drivers/uio/uio.c +++ b/trunk/drivers/uio/uio.c @@ -67,11 +67,6 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf) return sprintf(buf, "0x%lx\n", mem->size); } -static ssize_t map_offset_show(struct uio_mem *mem, char *buf) -{ - return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK); -} - struct uio_sysfs_entry { struct attribute attr; ssize_t (*show)(struct uio_mem *, char *); @@ -82,13 +77,10 @@ static struct uio_sysfs_entry addr_attribute = __ATTR(addr, S_IRUGO, map_addr_show, NULL); static struct uio_sysfs_entry size_attribute = __ATTR(size, S_IRUGO, map_size_show, NULL); -static struct uio_sysfs_entry offset_attribute = - __ATTR(offset, S_IRUGO, map_offset_show, NULL); static struct attribute *attrs[] = { &addr_attribute.attr, &size_attribute.attr, - &offset_attribute.attr, NULL, /* need to NULL terminate the list of attributes */ }; @@ -490,23 +482,15 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct uio_device *idev = vma->vm_private_data; struct page *page; - unsigned long offset; int mi = uio_find_mem_index(vma); if (mi < 0) return VM_FAULT_SIGBUS; - /* - * We need to subtract mi because userspace uses offset = N*PAGE_SIZE - * to use mem[N]. - */ - offset = (vmf->pgoff - mi) << PAGE_SHIFT; - if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL) - page = virt_to_page(idev->info->mem[mi].addr + offset); + page = virt_to_page(idev->info->mem[mi].addr); else - page = vmalloc_to_page((void *)idev->info->mem[mi].addr - + offset); + page = vmalloc_to_page((void*)idev->info->mem[mi].addr); get_page(page); vmf->page = page; return 0; @@ -698,9 +682,9 @@ int __uio_register_device(struct module *owner, if (ret) goto err_get_minor; - idev->dev = device_create(uio_class->class, parent, - MKDEV(uio_major, idev->minor), idev, - "uio%d", idev->minor); + idev->dev = device_create_drvdata(uio_class->class, parent, + MKDEV(uio_major, idev->minor), idev, + "uio%d", idev->minor); if (IS_ERR(idev->dev)) { printk(KERN_ERR "UIO: device register failed\n"); ret = PTR_ERR(idev->dev); diff --git a/trunk/drivers/uio/uio_pdrv.c b/trunk/drivers/uio/uio_pdrv.c index d494ce9288c3..0b4ef39cd85d 100644 --- a/trunk/drivers/uio/uio_pdrv.c +++ b/trunk/drivers/uio/uio_pdrv.c @@ -12,7 +12,7 @@ #include #include -#define DRIVER_NAME "uio_pdrv" +#define DRIVER_NAME "uio" struct uio_platdata { struct uio_info *uioinfo; diff --git a/trunk/drivers/uio/uio_sercos3.c b/trunk/drivers/uio/uio_sercos3.c deleted file mode 100644 index a6d1b2bc47f3..000000000000 --- a/trunk/drivers/uio/uio_sercos3.c +++ /dev/null @@ -1,243 +0,0 @@ -/* sercos3: UIO driver for the Automata Sercos III PCI card - - Copyright (C) 2008 Linutronix GmbH - Author: John Ogness - - This is a straight-forward UIO driver, where interrupts are disabled - by the interrupt handler and re-enabled via a write to the UIO device - by the userspace-part. - - The only part that may seem odd is the use of a logical OR when - storing and restoring enabled interrupts. This is done because the - userspace-part could directly modify the Interrupt Enable Register - at any time. To reduce possible conflicts, the kernel driver uses - a logical OR to make more controlled changes (rather than blindly - overwriting previous values). - - Race conditions exist if the userspace-part directly modifies the - Interrupt Enable Register while in operation. The consequences are - that certain interrupts would fail to be enabled or disabled. For - this reason, the userspace-part should only directly modify the - Interrupt Enable Register at the beginning (to get things going). - The userspace-part can safely disable interrupts at any time using - a write to the UIO device. -*/ - -#include -#include -#include -#include -#include - -/* ID's for SERCOS III PCI card (PLX 9030) */ -#define SERCOS_SUB_VENDOR_ID 0x1971 -#define SERCOS_SUB_SYSID_3530 0x3530 -#define SERCOS_SUB_SYSID_3535 0x3535 -#define SERCOS_SUB_SYSID_3780 0x3780 - -/* Interrupt Enable Register */ -#define IER0_OFFSET 0x08 - -/* Interrupt Status Register */ -#define ISR0_OFFSET 0x18 - -struct sercos3_priv { - u32 ier0_cache; - spinlock_t ier0_cache_lock; -}; - -/* this function assumes ier0_cache_lock is locked! */ -static void sercos3_disable_interrupts(struct uio_info *info, - struct sercos3_priv *priv) -{ - void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET; - - /* add enabled interrupts to cache */ - priv->ier0_cache |= ioread32(ier0); - - /* disable interrupts */ - iowrite32(0, ier0); -} - -/* this function assumes ier0_cache_lock is locked! */ -static void sercos3_enable_interrupts(struct uio_info *info, - struct sercos3_priv *priv) -{ - void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET; - - /* restore previously enabled interrupts */ - iowrite32(ioread32(ier0) | priv->ier0_cache, ier0); - priv->ier0_cache = 0; -} - -static irqreturn_t sercos3_handler(int irq, struct uio_info *info) -{ - struct sercos3_priv *priv = info->priv; - void __iomem *isr0 = info->mem[3].internal_addr + ISR0_OFFSET; - void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET; - - if (!(ioread32(isr0) & ioread32(ier0))) - return IRQ_NONE; - - spin_lock(&priv->ier0_cache_lock); - sercos3_disable_interrupts(info, priv); - spin_unlock(&priv->ier0_cache_lock); - - return IRQ_HANDLED; -} - -static int sercos3_irqcontrol(struct uio_info *info, s32 irq_on) -{ - struct sercos3_priv *priv = info->priv; - - spin_lock_irq(&priv->ier0_cache_lock); - if (irq_on) - sercos3_enable_interrupts(info, priv); - else - sercos3_disable_interrupts(info, priv); - spin_unlock_irq(&priv->ier0_cache_lock); - - return 0; -} - -static int sercos3_setup_iomem(struct pci_dev *dev, struct uio_info *info, - int n, int pci_bar) -{ - info->mem[n].addr = pci_resource_start(dev, pci_bar); - if (!info->mem[n].addr) - return -1; - info->mem[n].internal_addr = ioremap(pci_resource_start(dev, pci_bar), - pci_resource_len(dev, pci_bar)); - if (!info->mem[n].internal_addr) - return -1; - info->mem[n].size = pci_resource_len(dev, pci_bar); - info->mem[n].memtype = UIO_MEM_PHYS; - return 0; -} - -static int __devinit sercos3_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - struct uio_info *info; - struct sercos3_priv *priv; - int i; - - info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - priv = kzalloc(sizeof(struct sercos3_priv), GFP_KERNEL); - if (!priv) - goto out_free; - - if (pci_enable_device(dev)) - goto out_free_priv; - - if (pci_request_regions(dev, "sercos3")) - goto out_disable; - - /* we only need PCI BAR's 0, 2, 3, 4, 5 */ - if (sercos3_setup_iomem(dev, info, 0, 0)) - goto out_unmap; - if (sercos3_setup_iomem(dev, info, 1, 2)) - goto out_unmap; - if (sercos3_setup_iomem(dev, info, 2, 3)) - goto out_unmap; - if (sercos3_setup_iomem(dev, info, 3, 4)) - goto out_unmap; - if (sercos3_setup_iomem(dev, info, 4, 5)) - goto out_unmap; - - spin_lock_init(&priv->ier0_cache_lock); - info->priv = priv; - info->name = "Sercos_III_PCI"; - info->version = "0.0.1"; - info->irq = dev->irq; - info->irq_flags = IRQF_DISABLED | IRQF_SHARED; - info->handler = sercos3_handler; - info->irqcontrol = sercos3_irqcontrol; - - pci_set_drvdata(dev, info); - - if (uio_register_device(&dev->dev, info)) - goto out_unmap; - - return 0; - -out_unmap: - for (i = 0; i < 5; i++) { - if (info->mem[i].internal_addr) - iounmap(info->mem[i].internal_addr); - } - pci_release_regions(dev); -out_disable: - pci_disable_device(dev); -out_free_priv: - kfree(priv); -out_free: - kfree(info); - return -ENODEV; -} - -static void sercos3_pci_remove(struct pci_dev *dev) -{ - struct uio_info *info = pci_get_drvdata(dev); - int i; - - uio_unregister_device(info); - pci_release_regions(dev); - pci_disable_device(dev); - pci_set_drvdata(dev, NULL); - for (i = 0; i < 5; i++) { - if (info->mem[i].internal_addr) - iounmap(info->mem[i].internal_addr); - } - kfree(info->priv); - kfree(info); -} - -static struct pci_device_id sercos3_pci_ids[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_PLX, - .device = PCI_DEVICE_ID_PLX_9030, - .subvendor = SERCOS_SUB_VENDOR_ID, - .subdevice = SERCOS_SUB_SYSID_3530, - }, - { - .vendor = PCI_VENDOR_ID_PLX, - .device = PCI_DEVICE_ID_PLX_9030, - .subvendor = SERCOS_SUB_VENDOR_ID, - .subdevice = SERCOS_SUB_SYSID_3535, - }, - { - .vendor = PCI_VENDOR_ID_PLX, - .device = PCI_DEVICE_ID_PLX_9030, - .subvendor = SERCOS_SUB_VENDOR_ID, - .subdevice = SERCOS_SUB_SYSID_3780, - }, - { 0, } -}; - -static struct pci_driver sercos3_pci_driver = { - .name = "sercos3", - .id_table = sercos3_pci_ids, - .probe = sercos3_pci_probe, - .remove = sercos3_pci_remove, -}; - -static int __init sercos3_init_module(void) -{ - return pci_register_driver(&sercos3_pci_driver); -} - -static void __exit sercos3_exit_module(void) -{ - pci_unregister_driver(&sercos3_pci_driver); -} - -module_init(sercos3_init_module); -module_exit(sercos3_exit_module); - -MODULE_DESCRIPTION("UIO driver for the Automata Sercos III PCI card"); -MODULE_AUTHOR("John Ogness "); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 7a4fa791dc19..20290c5b1562 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -1729,9 +1729,9 @@ static int usb_classdev_add(struct usb_device *dev) { struct device *cldev; - cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt, - NULL, "usbdev%d.%d", dev->bus->busnum, - dev->devnum); + cldev = device_create_drvdata(usb_classdev_class, &dev->dev, + dev->dev.devt, NULL, "usbdev%d.%d", + dev->bus->busnum, dev->devnum); if (IS_ERR(cldev)) return PTR_ERR(cldev); dev->usb_classdev = cldev; diff --git a/trunk/drivers/usb/core/file.c b/trunk/drivers/usb/core/file.c index 55f7f310924b..6b1b229e38cd 100644 --- a/trunk/drivers/usb/core/file.c +++ b/trunk/drivers/usb/core/file.c @@ -196,9 +196,9 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->usb_dev = device_create(usb_class->class, &intf->dev, - MKDEV(USB_MAJOR, minor), NULL, - "%s", temp); + intf->usb_dev = device_create_drvdata(usb_class->class, &intf->dev, + MKDEV(USB_MAJOR, minor), NULL, + "%s", temp); if (IS_ERR(intf->usb_dev)) { down_write(&minor_rwsem); usb_minors[intf->minor] = NULL; diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index c8035a8216bd..8ab389dca2b9 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -818,8 +818,9 @@ static int usb_register_bus(struct usb_bus *bus) set_bit (busnum, busmap.busmap); bus->busnum = busnum; - bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), - bus, "usb_host%d", busnum); + bus->dev = device_create_drvdata(usb_host_class, bus->controller, + MKDEV(0, 0), bus, + "usb_host%d", busnum); result = PTR_ERR(bus->dev); if (IS_ERR(bus->dev)) goto error_create_class_dev; diff --git a/trunk/drivers/usb/core/inode.c b/trunk/drivers/usb/core/inode.c index 77fa7a080801..db410e92c80d 100644 --- a/trunk/drivers/usb/core/inode.c +++ b/trunk/drivers/usb/core/inode.c @@ -97,7 +97,7 @@ enum { Opt_err, }; -static const match_table_t tokens = { +static match_table_t tokens = { {Opt_devuid, "devuid=%u"}, {Opt_devgid, "devgid=%u"}, {Opt_devmode, "devmode=%o"}, diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index 2267fa0b51b2..fcb5cb9094d9 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -22,15 +22,24 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o # # USB gadget drivers # -g_zero-objs := zero.o -g_ether-objs := ether.o -g_serial-objs := serial.o -g_midi-objs := gmidi.o +C_UTILS = composite.o usbstring.o config.o epautoconf.o + +g_zero-objs := zero.o f_sourcesink.o f_loopback.o $(C_UTILS) +g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS) +g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS) +g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o gadgetfs-objs := inode.o -g_file_storage-objs := file_storage.o -g_printer-objs := printer.o -g_cdc-objs := cdc2.o +g_file_storage-objs := file_storage.o usbstring.o config.o \ + epautoconf.o +g_printer-objs := printer.o usbstring.o config.o \ + epautoconf.o +g_cdc-objs := cdc2.o u_ether.o f_ecm.o \ + u_serial.o f_acm.o $(C_UTILS) +ifeq ($(CONFIG_USB_ETH_RNDIS),y) + g_ether-objs += f_rndis.o rndis.o +endif + obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_ETH) += g_ether.o obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o diff --git a/trunk/drivers/usb/gadget/cdc2.c b/trunk/drivers/usb/gadget/cdc2.c index a724fc149850..a39a4b940c33 100644 --- a/trunk/drivers/usb/gadget/cdc2.c +++ b/trunk/drivers/usb/gadget/cdc2.c @@ -43,25 +43,6 @@ /*-------------------------------------------------------------------------*/ -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ - -#include "composite.c" -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" -#include "u_serial.c" -#include "f_acm.c" -#include "f_ecm.c" -#include "u_ether.c" - -/*-------------------------------------------------------------------------*/ - static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, @@ -167,8 +148,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) int status; if (!can_support_ecm(cdev->gadget)) { - dev_err(&gadget->dev, "controller '%s' not usable\n", - gadget->name); + ERROR(cdev, "controller '%s' not usable\n", gadget->name); return -EINVAL; } @@ -223,8 +203,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail1; - dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", - DRIVER_DESC); + INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); return 0; diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 944c8e889ab4..bcac2e68660d 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -96,28 +96,6 @@ static inline bool has_rndis(void) /*-------------------------------------------------------------------------*/ -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "composite.c" -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - -#include "f_ecm.c" -#include "f_subset.c" -#ifdef CONFIG_USB_ETH_RNDIS -#include "f_rndis.c" -#include "rndis.c" -#endif -#include "u_ether.c" - -/*-------------------------------------------------------------------------*/ - /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! * Instead: allocate your own, using normal USB-IF procedures. */ @@ -315,8 +293,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev) * but if the controller isn't recognized at all then * that assumption is a bit more likely to be wrong. */ - dev_warn(&gadget->dev, - "controller '%s' not recognized; trying %s\n", + WARNING(cdev, "controller '%s' not recognized; trying %s\n", gadget->name, eth_config_driver.label); device_desc.bcdDevice = @@ -355,8 +332,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail; - dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", - DRIVER_DESC); + INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); return 0; diff --git a/trunk/drivers/usb/gadget/f_ecm.c b/trunk/drivers/usb/gadget/f_ecm.c index 4ae579948e54..a2b5c092bda0 100644 --- a/trunk/drivers/usb/gadget/f_ecm.c +++ b/trunk/drivers/usb/gadget/f_ecm.c @@ -83,7 +83,7 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f) } /* peak (theoretical) bulk transfer rate in bits-per-second */ -static inline unsigned ecm_bitrate(struct usb_gadget *g) +static inline unsigned bitrate(struct usb_gadget *g) { if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) return 13 * 512 * 8 * 1000 * 8; @@ -107,7 +107,7 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g) */ #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ -#define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */ +#define STATUS_BYTECOUNT 16 /* 8 byte header + data */ /* interface descriptor: */ @@ -125,8 +125,8 @@ static struct usb_interface_descriptor ecm_control_intf __initdata = { /* .iInterface = DYNAMIC */ }; -static struct usb_cdc_header_desc ecm_header_desc __initdata = { - .bLength = sizeof ecm_header_desc, +static struct usb_cdc_header_desc header_desc __initdata = { + .bLength = sizeof header_desc, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_HEADER_TYPE, @@ -141,8 +141,8 @@ static struct usb_cdc_union_desc ecm_union_desc __initdata = { /* .bSlaveInterface0 = DYNAMIC */ }; -static struct usb_cdc_ether_desc ecm_desc __initdata = { - .bLength = sizeof ecm_desc, +static struct usb_cdc_ether_desc ether_desc __initdata = { + .bLength = sizeof ether_desc, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_ETHERNET_TYPE, @@ -186,17 +186,17 @@ static struct usb_interface_descriptor ecm_data_intf __initdata = { /* full speed support: */ -static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = { +static struct usb_endpoint_descriptor fs_notify_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT), + .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT), .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, }; -static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = { +static struct usb_endpoint_descriptor fs_in_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -204,7 +204,7 @@ static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = { +static struct usb_endpoint_descriptor fs_out_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -212,34 +212,34 @@ static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *ecm_fs_function[] __initdata = { +static struct usb_descriptor_header *eth_fs_function[] __initdata = { /* CDC ECM control descriptors */ (struct usb_descriptor_header *) &ecm_control_intf, - (struct usb_descriptor_header *) &ecm_header_desc, + (struct usb_descriptor_header *) &header_desc, (struct usb_descriptor_header *) &ecm_union_desc, - (struct usb_descriptor_header *) &ecm_desc, + (struct usb_descriptor_header *) ðer_desc, /* NOTE: status endpoint might need to be removed */ - (struct usb_descriptor_header *) &fs_ecm_notify_desc, + (struct usb_descriptor_header *) &fs_notify_desc, /* data interface, altsettings 0 and 1 */ (struct usb_descriptor_header *) &ecm_data_nop_intf, (struct usb_descriptor_header *) &ecm_data_intf, - (struct usb_descriptor_header *) &fs_ecm_in_desc, - (struct usb_descriptor_header *) &fs_ecm_out_desc, + (struct usb_descriptor_header *) &fs_in_desc, + (struct usb_descriptor_header *) &fs_out_desc, NULL, }; /* high speed support: */ -static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = { +static struct usb_endpoint_descriptor hs_notify_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT), + .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT), .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, }; -static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { +static struct usb_endpoint_descriptor hs_in_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { .wMaxPacketSize = __constant_cpu_to_le16(512), }; -static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { +static struct usb_endpoint_descriptor hs_out_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -257,19 +257,19 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { .wMaxPacketSize = __constant_cpu_to_le16(512), }; -static struct usb_descriptor_header *ecm_hs_function[] __initdata = { +static struct usb_descriptor_header *eth_hs_function[] __initdata = { /* CDC ECM control descriptors */ (struct usb_descriptor_header *) &ecm_control_intf, - (struct usb_descriptor_header *) &ecm_header_desc, + (struct usb_descriptor_header *) &header_desc, (struct usb_descriptor_header *) &ecm_union_desc, - (struct usb_descriptor_header *) &ecm_desc, + (struct usb_descriptor_header *) ðer_desc, /* NOTE: status endpoint might need to be removed */ - (struct usb_descriptor_header *) &hs_ecm_notify_desc, + (struct usb_descriptor_header *) &hs_notify_desc, /* data interface, altsettings 0 and 1 */ (struct usb_descriptor_header *) &ecm_data_nop_intf, (struct usb_descriptor_header *) &ecm_data_intf, - (struct usb_descriptor_header *) &hs_ecm_in_desc, - (struct usb_descriptor_header *) &hs_ecm_out_desc, + (struct usb_descriptor_header *) &hs_in_desc, + (struct usb_descriptor_header *) &hs_out_desc, NULL, }; @@ -329,14 +329,14 @@ static void ecm_do_notify(struct f_ecm *ecm) event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE; event->wValue = cpu_to_le16(0); event->wLength = cpu_to_le16(8); - req->length = ECM_STATUS_BYTECOUNT; + req->length = STATUS_BYTECOUNT; /* SPEED_CHANGE data is up/down speeds in bits/sec */ data = req->buf + sizeof *event; - data[0] = cpu_to_le32(ecm_bitrate(cdev->gadget)); + data[0] = cpu_to_le32(bitrate(cdev->gadget)); data[1] = data[0]; - DBG(cdev, "notify speed %d\n", ecm_bitrate(cdev->gadget)); + DBG(cdev, "notify speed %d\n", bitrate(cdev->gadget)); ecm->notify_state = ECM_NOTIFY_NONE; break; } @@ -628,13 +628,13 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) status = -ENODEV; /* allocate instance-specific endpoints */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc); + ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc); if (!ep) goto fail; ecm->port.in_ep = ep; ep->driver_data = cdev; /* claim */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); + ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); if (!ep) goto fail; ecm->port.out_ep = ep; @@ -644,7 +644,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) * don't treat it that way. It's simpler, and some newer CDC * profiles (wireless handsets) no longer treat it as optional. */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc); + ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc); if (!ep) goto fail; ecm->notify = ep; @@ -656,47 +656,47 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); if (!ecm->notify_req) goto fail; - ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); + ecm->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL); if (!ecm->notify_req->buf) goto fail; ecm->notify_req->context = ecm; ecm->notify_req->complete = ecm_notify_complete; /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(ecm_fs_function); + f->descriptors = usb_copy_descriptors(eth_fs_function); if (!f->descriptors) goto fail; - ecm->fs.in = usb_find_endpoint(ecm_fs_function, - f->descriptors, &fs_ecm_in_desc); - ecm->fs.out = usb_find_endpoint(ecm_fs_function, - f->descriptors, &fs_ecm_out_desc); - ecm->fs.notify = usb_find_endpoint(ecm_fs_function, - f->descriptors, &fs_ecm_notify_desc); + ecm->fs.in = usb_find_endpoint(eth_fs_function, + f->descriptors, &fs_in_desc); + ecm->fs.out = usb_find_endpoint(eth_fs_function, + f->descriptors, &fs_out_desc); + ecm->fs.notify = usb_find_endpoint(eth_fs_function, + f->descriptors, &fs_notify_desc); /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_ecm_in_desc.bEndpointAddress = - fs_ecm_in_desc.bEndpointAddress; - hs_ecm_out_desc.bEndpointAddress = - fs_ecm_out_desc.bEndpointAddress; - hs_ecm_notify_desc.bEndpointAddress = - fs_ecm_notify_desc.bEndpointAddress; + hs_in_desc.bEndpointAddress = + fs_in_desc.bEndpointAddress; + hs_out_desc.bEndpointAddress = + fs_out_desc.bEndpointAddress; + hs_notify_desc.bEndpointAddress = + fs_notify_desc.bEndpointAddress; /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(ecm_hs_function); + f->hs_descriptors = usb_copy_descriptors(eth_hs_function); if (!f->hs_descriptors) goto fail; - ecm->hs.in = usb_find_endpoint(ecm_hs_function, - f->hs_descriptors, &hs_ecm_in_desc); - ecm->hs.out = usb_find_endpoint(ecm_hs_function, - f->hs_descriptors, &hs_ecm_out_desc); - ecm->hs.notify = usb_find_endpoint(ecm_hs_function, - f->hs_descriptors, &hs_ecm_notify_desc); + ecm->hs.in = usb_find_endpoint(eth_hs_function, + f->hs_descriptors, &hs_in_desc); + ecm->hs.out = usb_find_endpoint(eth_hs_function, + f->hs_descriptors, &hs_out_desc); + ecm->hs.notify = usb_find_endpoint(eth_hs_function, + f->hs_descriptors, &hs_notify_desc); } /* NOTE: all that is done without knowing or caring about @@ -795,7 +795,7 @@ int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) if (status < 0) return status; ecm_string_defs[1].id = status; - ecm_desc.iMACAddress = status; + ether_desc.iMACAddress = status; } /* allocate and initialize one new instance */ diff --git a/trunk/drivers/usb/gadget/f_loopback.c b/trunk/drivers/usb/gadget/f_loopback.c index 87dde012dacc..eda4cde72c82 100644 --- a/trunk/drivers/usb/gadget/f_loopback.c +++ b/trunk/drivers/usb/gadget/f_loopback.c @@ -70,7 +70,7 @@ static struct usb_interface_descriptor loopback_intf = { /* full speed support: */ -static struct usb_endpoint_descriptor fs_loop_source_desc = { +static struct usb_endpoint_descriptor fs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -78,7 +78,7 @@ static struct usb_endpoint_descriptor fs_loop_source_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor fs_loop_sink_desc = { +static struct usb_endpoint_descriptor fs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -88,14 +88,14 @@ static struct usb_endpoint_descriptor fs_loop_sink_desc = { static struct usb_descriptor_header *fs_loopback_descs[] = { (struct usb_descriptor_header *) &loopback_intf, - (struct usb_descriptor_header *) &fs_loop_sink_desc, - (struct usb_descriptor_header *) &fs_loop_source_desc, + (struct usb_descriptor_header *) &fs_sink_desc, + (struct usb_descriptor_header *) &fs_source_desc, NULL, }; /* high speed support: */ -static struct usb_endpoint_descriptor hs_loop_source_desc = { +static struct usb_endpoint_descriptor hs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -103,7 +103,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = { .wMaxPacketSize = __constant_cpu_to_le16(512), }; -static struct usb_endpoint_descriptor hs_loop_sink_desc = { +static struct usb_endpoint_descriptor hs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -113,8 +113,8 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = { static struct usb_descriptor_header *hs_loopback_descs[] = { (struct usb_descriptor_header *) &loopback_intf, - (struct usb_descriptor_header *) &hs_loop_source_desc, - (struct usb_descriptor_header *) &hs_loop_sink_desc, + (struct usb_descriptor_header *) &hs_source_desc, + (struct usb_descriptor_header *) &hs_sink_desc, NULL, }; @@ -152,7 +152,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) /* allocate endpoints */ - loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc); + loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc); if (!loop->in_ep) { autoconf_fail: ERROR(cdev, "%s: can't autoconfigure on %s\n", @@ -161,17 +161,17 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) } loop->in_ep->driver_data = cdev; /* claim */ - loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc); + loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc); if (!loop->out_ep) goto autoconf_fail; loop->out_ep->driver_data = cdev; /* claim */ /* support high speed hardware */ if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_loop_source_desc.bEndpointAddress = - fs_loop_source_desc.bEndpointAddress; - hs_loop_sink_desc.bEndpointAddress = - fs_loop_sink_desc.bEndpointAddress; + hs_source_desc.bEndpointAddress = + fs_source_desc.bEndpointAddress; + hs_sink_desc.bEndpointAddress = + fs_sink_desc.bEndpointAddress; f->hs_descriptors = hs_loopback_descs; } @@ -255,10 +255,8 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) struct usb_request *req; unsigned i; - src = ep_choose(cdev->gadget, - &hs_loop_source_desc, &fs_loop_source_desc); - sink = ep_choose(cdev->gadget, - &hs_loop_sink_desc, &fs_loop_sink_desc); + src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc); + sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc); /* one endpoint writes data back IN to the host */ ep = loop->in_ep; diff --git a/trunk/drivers/usb/gadget/f_subset.c b/trunk/drivers/usb/gadget/f_subset.c index fe1832875771..acb8d233aa1d 100644 --- a/trunk/drivers/usb/gadget/f_subset.c +++ b/trunk/drivers/usb/gadget/f_subset.c @@ -103,8 +103,8 @@ static struct usb_interface_descriptor subset_data_intf __initdata = { /* .iInterface = DYNAMIC */ }; -static struct usb_cdc_header_desc mdlm_header_desc __initdata = { - .bLength = sizeof mdlm_header_desc, +static struct usb_cdc_header_desc header_desc __initdata = { + .bLength = sizeof header_desc, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_HEADER_TYPE, @@ -152,7 +152,7 @@ static struct usb_cdc_ether_desc ether_desc __initdata = { /* full speed support: */ -static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = { +static struct usb_endpoint_descriptor fs_in_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -160,7 +160,7 @@ static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = { +static struct usb_endpoint_descriptor fs_out_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -170,18 +170,18 @@ static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = { static struct usb_descriptor_header *fs_eth_function[] __initdata = { (struct usb_descriptor_header *) &subset_data_intf, - (struct usb_descriptor_header *) &mdlm_header_desc, + (struct usb_descriptor_header *) &header_desc, (struct usb_descriptor_header *) &mdlm_desc, (struct usb_descriptor_header *) &mdlm_detail_desc, (struct usb_descriptor_header *) ðer_desc, - (struct usb_descriptor_header *) &fs_subset_in_desc, - (struct usb_descriptor_header *) &fs_subset_out_desc, + (struct usb_descriptor_header *) &fs_in_desc, + (struct usb_descriptor_header *) &fs_out_desc, NULL, }; /* high speed support: */ -static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = { +static struct usb_endpoint_descriptor hs_in_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -189,7 +189,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = { .wMaxPacketSize = __constant_cpu_to_le16(512), }; -static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { +static struct usb_endpoint_descriptor hs_out_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -199,12 +199,12 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { static struct usb_descriptor_header *hs_eth_function[] __initdata = { (struct usb_descriptor_header *) &subset_data_intf, - (struct usb_descriptor_header *) &mdlm_header_desc, + (struct usb_descriptor_header *) &header_desc, (struct usb_descriptor_header *) &mdlm_desc, (struct usb_descriptor_header *) &mdlm_detail_desc, (struct usb_descriptor_header *) ðer_desc, - (struct usb_descriptor_header *) &hs_subset_in_desc, - (struct usb_descriptor_header *) &hs_subset_out_desc, + (struct usb_descriptor_header *) &hs_in_desc, + (struct usb_descriptor_header *) &hs_out_desc, NULL, }; @@ -281,13 +281,13 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) status = -ENODEV; /* allocate instance-specific endpoints */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_in_desc); + ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc); if (!ep) goto fail; geth->port.in_ep = ep; ep->driver_data = cdev; /* claim */ - ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc); + ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); if (!ep) goto fail; geth->port.out_ep = ep; @@ -297,9 +297,9 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) f->descriptors = usb_copy_descriptors(fs_eth_function); geth->fs.in = usb_find_endpoint(fs_eth_function, - f->descriptors, &fs_subset_in_desc); + f->descriptors, &fs_in_desc); geth->fs.out = usb_find_endpoint(fs_eth_function, - f->descriptors, &fs_subset_out_desc); + f->descriptors, &fs_out_desc); /* support all relevant hardware speeds... we expect that when @@ -307,18 +307,18 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_subset_in_desc.bEndpointAddress = - fs_subset_in_desc.bEndpointAddress; - hs_subset_out_desc.bEndpointAddress = - fs_subset_out_desc.bEndpointAddress; + hs_in_desc.bEndpointAddress = + fs_in_desc.bEndpointAddress; + hs_out_desc.bEndpointAddress = + fs_out_desc.bEndpointAddress; /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(hs_eth_function); geth->hs.in = usb_find_endpoint(hs_eth_function, - f->hs_descriptors, &hs_subset_in_desc); + f->hs_descriptors, &hs_in_desc); geth->hs.out = usb_find_endpoint(hs_eth_function, - f->hs_descriptors, &hs_subset_out_desc); + f->hs_descriptors, &hs_out_desc); } /* NOTE: all that is done without knowing or caring about diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 0c632d22a631..ea2c31d18080 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -245,18 +245,6 @@ #include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - /*-------------------------------------------------------------------------*/ #define DRIVER_DESC "File-backed Storage Gadget" diff --git a/trunk/drivers/usb/gadget/gmidi.c b/trunk/drivers/usb/gadget/gmidi.c index 6eee760410d6..ea8651e3da1a 100644 --- a/trunk/drivers/usb/gadget/gmidi.c +++ b/trunk/drivers/usb/gadget/gmidi.c @@ -35,21 +35,6 @@ #include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - -/*-------------------------------------------------------------------------*/ - - MODULE_AUTHOR("Ben Williamson"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/usb/gadget/printer.c b/trunk/drivers/usb/gadget/printer.c index 2b3b9e1dd2ee..e0090085b78e 100644 --- a/trunk/drivers/usb/gadget/printer.c +++ b/trunk/drivers/usb/gadget/printer.c @@ -53,20 +53,6 @@ #include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - -/*-------------------------------------------------------------------------*/ - #define DRIVER_DESC "Printer Gadget" #define DRIVER_VERSION "2007 OCT 06" @@ -1374,8 +1360,8 @@ printer_bind(struct usb_gadget *gadget) /* Setup the sysfs files for the printer gadget. */ - dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, - NULL, "g_printer"); + dev->pdev = device_create_drvdata(usb_gadget_class, NULL, + g_printer_devno, NULL, "g_printer"); if (IS_ERR(dev->pdev)) { ERROR(dev, "Failed to create device: g_printer\n"); goto fail; diff --git a/trunk/drivers/usb/gadget/rndis.c b/trunk/drivers/usb/gadget/rndis.c index 8c26f5ea2b83..7228e8562236 100644 --- a/trunk/drivers/usb/gadget/rndis.c +++ b/trunk/drivers/usb/gadget/rndis.c @@ -57,6 +57,11 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging"); #define rndis_debug 0 #endif +#define DBG(str,args...) do { \ + if (rndis_debug) \ + pr_debug(str , ## args); \ + } while (0) + #define RNDIS_MAX_CONFIGS 1 @@ -178,9 +183,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, if (!resp) return -ENOMEM; if (buf_len && rndis_debug > 1) { - pr_debug("query OID %08x value, len %d:\n", OID, buf_len); + DBG("query OID %08x value, len %d:\n", OID, buf_len); for (i = 0; i < buf_len; i += 16) { - pr_debug("%03d: %08x %08x %08x %08x\n", i, + DBG("%03d: %08x %08x %08x %08x\n", i, get_unaligned_le32(&buf[i]), get_unaligned_le32(&buf[i + 4]), get_unaligned_le32(&buf[i + 8]), @@ -204,7 +209,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_SUPPORTED_LIST: - pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__); + DBG("%s: OID_GEN_SUPPORTED_LIST\n", __func__); length = sizeof (oid_supported_list); count = length / sizeof (u32); for (i = 0; i < count; i++) @@ -214,7 +219,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_HARDWARE_STATUS: - pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__); + DBG("%s: OID_GEN_HARDWARE_STATUS\n", __func__); /* Bogus question! * Hardware must be ready to receive high level protocols. * BTW: @@ -227,14 +232,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_MEDIA_SUPPORTED: - pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); + DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); retval = 0; break; /* mandatory */ case OID_GEN_MEDIA_IN_USE: - pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__); + DBG("%s: OID_GEN_MEDIA_IN_USE\n", __func__); /* one medium, one transport... (maybe you do it better) */ *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); retval = 0; @@ -242,7 +247,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: - pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); + DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); if (rndis_per_dev_params [configNr].dev) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].dev->mtu); @@ -253,7 +258,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_LINK_SPEED: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); + DBG("%s: OID_GEN_LINK_SPEED\n", __func__); if (rndis_per_dev_params [configNr].media_state == NDIS_MEDIA_STATE_DISCONNECTED) *outbuf = __constant_cpu_to_le32 (0); @@ -265,7 +270,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_TRANSMIT_BLOCK_SIZE: - pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); + DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params [configNr].dev) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].dev->mtu); @@ -275,7 +280,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RECEIVE_BLOCK_SIZE: - pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); + DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params [configNr].dev) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].dev->mtu); @@ -285,7 +290,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_VENDOR_ID: - pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__); + DBG("%s: OID_GEN_VENDOR_ID\n", __func__); *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].vendorID); retval = 0; @@ -293,7 +298,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: - pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); + DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); length = strlen (rndis_per_dev_params [configNr].vendorDescr); memcpy (outbuf, rndis_per_dev_params [configNr].vendorDescr, length); @@ -301,7 +306,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_VENDOR_DRIVER_VERSION: - pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); + DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); /* Created as LE */ *outbuf = rndis_driver_version; retval = 0; @@ -309,14 +314,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_CURRENT_PACKET_FILTER: - pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); + DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter); retval = 0; break; /* mandatory */ case OID_GEN_MAXIMUM_TOTAL_SIZE: - pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); + DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); retval = 0; break; @@ -324,14 +329,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_MEDIA_CONNECT_STATUS: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); + DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .media_state); retval = 0; break; case OID_GEN_PHYSICAL_MEDIUM: - pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); + DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; @@ -341,7 +346,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! */ case OID_GEN_MAC_OPTIONS: /* from WinME */ - pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); + DBG("%s: OID_GEN_MAC_OPTIONS\n", __func__); *outbuf = __constant_cpu_to_le32( NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_FULL_DUPLEX); @@ -353,7 +358,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_XMIT_OK: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_XMIT_OK\n", __func__); + DBG("%s: OID_GEN_XMIT_OK\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->tx_packets - stats->tx_errors - stats->tx_dropped); @@ -364,7 +369,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RCV_OK: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_RCV_OK\n", __func__); + DBG("%s: OID_GEN_RCV_OK\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_packets - stats->rx_errors - stats->rx_dropped); @@ -375,7 +380,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_XMIT_ERROR: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__); + DBG("%s: OID_GEN_XMIT_ERROR\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->tx_errors); retval = 0; @@ -385,7 +390,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RCV_ERROR: if (rndis_debug > 1) - pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__); + DBG("%s: OID_GEN_RCV_ERROR\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_errors); retval = 0; @@ -394,7 +399,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RCV_NO_BUFFER: - pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); + DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_dropped); retval = 0; @@ -405,7 +410,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_PERMANENT_ADDRESS: - pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); + DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; memcpy (outbuf, @@ -417,7 +422,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_CURRENT_ADDRESS: - pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); + DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; memcpy (outbuf, @@ -429,7 +434,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_MULTICAST_LIST: - pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); + DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); /* Multicast base address only */ *outbuf = __constant_cpu_to_le32 (0xE0000000); retval = 0; @@ -437,21 +442,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_MAXIMUM_LIST_SIZE: - pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); + DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); /* Multicast base address only */ *outbuf = __constant_cpu_to_le32 (1); retval = 0; break; case OID_802_3_MAC_OPTIONS: - pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); + DBG("%s: OID_802_3_MAC_OPTIONS\n", __func__); break; /* ieee802.3 statistics OIDs (table 4-4) */ /* mandatory */ case OID_802_3_RCV_ERROR_ALIGNMENT: - pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); + DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_frame_errors); retval = 0; @@ -460,14 +465,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: - pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); + DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: - pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); + DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; @@ -499,9 +504,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, return -ENOMEM; if (buf_len && rndis_debug > 1) { - pr_debug("set OID %08x value, len %d:\n", OID, buf_len); + DBG("set OID %08x value, len %d:\n", OID, buf_len); for (i = 0; i < buf_len; i += 16) { - pr_debug("%03d: %08x %08x %08x %08x\n", i, + DBG("%03d: %08x %08x %08x %08x\n", i, get_unaligned_le32(&buf[i]), get_unaligned_le32(&buf[i + 4]), get_unaligned_le32(&buf[i + 8]), @@ -520,7 +525,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, * MULTICAST, ALL_MULTICAST, BROADCAST */ *params->filter = (u16)get_unaligned_le32(buf); - pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", + DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", __func__, *params->filter); /* this call has a significant side effect: it's @@ -542,7 +547,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, case OID_802_3_MULTICAST_LIST: /* I think we can ignore this */ - pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); + DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); retval = 0; break; @@ -601,7 +606,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) rndis_resp_t *r; struct rndis_params *params = rndis_per_dev_params + configNr; - /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ + // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); if (!params->dev) return -ENOTSUPP; @@ -654,15 +659,15 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) BufOffset = le32_to_cpu (buf->InformationBufferOffset); #ifdef VERBOSE_DEBUG - pr_debug("%s: Length: %d\n", __func__, BufLength); - pr_debug("%s: Offset: %d\n", __func__, BufOffset); - pr_debug("%s: InfoBuffer: ", __func__); + DBG("%s: Length: %d\n", __func__, BufLength); + DBG("%s: Offset: %d\n", __func__, BufOffset); + DBG("%s: InfoBuffer: ", __func__); for (i = 0; i < BufLength; i++) { - pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); + DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); } - pr_debug("\n"); + DBG("\n"); #endif resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); @@ -816,14 +821,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf) /* For USB: responses may take up to 10 seconds */ switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: - pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", + DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __func__ ); params->state = RNDIS_INITIALIZED; return rndis_init_response (configNr, (rndis_init_msg_type *) buf); case REMOTE_NDIS_HALT_MSG: - pr_debug("%s: REMOTE_NDIS_HALT_MSG\n", + DBG("%s: REMOTE_NDIS_HALT_MSG\n", __func__ ); params->state = RNDIS_UNINITIALIZED; if (params->dev) { @@ -841,7 +846,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) (rndis_set_msg_type *) buf); case REMOTE_NDIS_RESET_MSG: - pr_debug("%s: REMOTE_NDIS_RESET_MSG\n", + DBG("%s: REMOTE_NDIS_RESET_MSG\n", __func__ ); return rndis_reset_response (configNr, (rndis_reset_msg_type *) buf); @@ -849,7 +854,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) - pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", + DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __func__ ); return rndis_keepalive_response (configNr, (rndis_keepalive_msg_type *) @@ -865,7 +870,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) { unsigned i; for (i = 0; i < MsgLength; i += 16) { - pr_debug("%03d: " + DBG("%03d: " " %02x %02x %02x %02x" " %02x %02x %02x %02x" " %02x %02x %02x %02x" @@ -900,18 +905,18 @@ int rndis_register(void (*resp_avail)(void *v), void *v) rndis_per_dev_params [i].used = 1; rndis_per_dev_params [i].resp_avail = resp_avail; rndis_per_dev_params [i].v = v; - pr_debug("%s: configNr = %d\n", __func__, i); + DBG("%s: configNr = %d\n", __func__, i); return i; } } - pr_debug("failed\n"); + DBG("failed\n"); return -ENODEV; } void rndis_deregister (int configNr) { - pr_debug("%s: \n", __func__); + DBG("%s: \n", __func__ ); if (configNr >= RNDIS_MAX_CONFIGS) return; rndis_per_dev_params [configNr].used = 0; @@ -921,7 +926,7 @@ void rndis_deregister (int configNr) int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) { - pr_debug("%s:\n", __func__); + DBG("%s:\n", __func__ ); if (!dev) return -EINVAL; if (configNr >= RNDIS_MAX_CONFIGS) return -1; @@ -934,7 +939,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) { - pr_debug("%s:\n", __func__); + DBG("%s:\n", __func__ ); if (!vendorDescr) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; @@ -946,7 +951,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) { - pr_debug("%s: %u %u\n", __func__, medium, speed); + DBG("%s: %u %u\n", __func__, medium, speed); if (configNr >= RNDIS_MAX_CONFIGS) return -1; rndis_per_dev_params [configNr].medium = medium; @@ -1109,7 +1114,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, break; default: if (fl_speed) p->speed = speed; - else pr_debug("%c is not valid\n", c); + else DBG("%c is not valid\n", c); break; } @@ -1154,12 +1159,12 @@ int __init rndis_init (void) &rndis_proc_fops, (void *)(rndis_per_dev_params + i)))) { - pr_debug("%s :remove entries", __func__); + DBG("%s :remove entries", __func__); while (i) { sprintf (name, NAME_TEMPLATE, --i); remove_proc_entry (name, NULL); } - pr_debug("\n"); + DBG("\n"); return -EIO; } #endif diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 3faa7a7022df..b3699afff002 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -30,24 +30,6 @@ /*-------------------------------------------------------------------------*/ -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "composite.c" -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - -#include "f_acm.c" -#include "f_serial.c" -#include "u_serial.c" - -/*-------------------------------------------------------------------------*/ - /* Thanks to NetChip Technologies for donating this product ID. * * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index dbd575a194f3..3791e6271903 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -52,7 +52,7 @@ * this single "physical" link to be used by multiple virtual links.) */ -#define UETH__VERSION "29-May-2008" +#define DRIVER_VERSION "29-May-2008" struct eth_dev { /* lock is held while accessing port_usb @@ -170,7 +170,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) struct eth_dev *dev = netdev_priv(net); strlcpy(p->driver, "g_ether", sizeof p->driver); - strlcpy(p->version, UETH__VERSION, sizeof p->version); + strlcpy(p->version, DRIVER_VERSION, sizeof p->version); strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version); strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); } diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index 361d9659ac48..aa0bd4f126a1 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -57,23 +57,6 @@ #include "gadget_chips.h" -/*-------------------------------------------------------------------------*/ - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "composite.c" -#include "usbstring.c" -#include "config.c" -#include "epautoconf.c" - -#include "f_sourcesink.c" -#include "f_loopback.c" - /*-------------------------------------------------------------------------*/ #define DRIVER_VERSION "Cinco de Mayo 2008" diff --git a/trunk/drivers/usb/host/ohci-omap.c b/trunk/drivers/usb/host/ohci-omap.c index 522185629624..95b3ec89c126 100644 --- a/trunk/drivers/usb/host/ohci-omap.c +++ b/trunk/drivers/usb/host/ohci-omap.c @@ -344,12 +344,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, goto err1; } - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&pdev->dev, "can't ioremap OHCI HCD\n"); - retval = -ENOMEM; - goto err2; - } + hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start); ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); @@ -360,11 +355,11 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, irq = platform_get_irq(pdev, 0); if (irq < 0) { retval = -ENXIO; - goto err3; + goto err2; } retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); if (retval) - goto err3; + goto err2; host_initialized = 1; @@ -372,8 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, omap_ohci_clock_power(0); return 0; -err3: - iounmap(hcd->regs); err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: @@ -408,7 +401,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) } if (machine_is_omap_osk()) omap_free_gpio(9); - iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_dc_ck); diff --git a/trunk/drivers/usb/host/sl811_cs.c b/trunk/drivers/usb/host/sl811_cs.c index 516848dd9b48..5da63f535005 100644 --- a/trunk/drivers/usb/host/sl811_cs.c +++ b/trunk/drivers/usb/host/sl811_cs.c @@ -112,8 +112,7 @@ static struct platform_device platform_dev = { .num_resources = ARRAY_SIZE(resources), }; -static int sl811_hc_init(struct device *parent, resource_size_t base_addr, - int irq) +static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) { if (platform_dev.dev.parent) return -EBUSY; @@ -156,72 +155,97 @@ static void sl811_cs_release(struct pcmcia_device * link) platform_device_unregister(&platform_dev); } -static int sl811_cs_config_check(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) -{ - if (cfg->index == 0) - return -ENODEV; - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000 != vcc) - return -ENODEV; - } else if (dflt->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000 != vcc) - return -ENODEV; - } - - if (cfg->vpp1.present & (1<conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt->vpp1.present & (1<conf.Vpp = - dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; - - /* we need an interrupt */ - if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - - return pcmcia_request_io(p_dev, &p_dev->io); - } - pcmcia_disable_device(p_dev); - return -ENODEV; -} - - static int sl811_cs_config(struct pcmcia_device *link) { struct device *parent = &handle_to_dev(link); local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; int last_fn, last_ret; + u_char buf[64]; + config_info_t conf; + cistpl_cftable_entry_t dflt = { 0 }; DBG(0, "sl811_cs_config(0x%p)\n", link); - if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) - goto failed; + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, + pcmcia_get_configuration_info(link, &conf)); + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + while (1) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + + if (pcmcia_get_tuple_data(link, &tuple) != 0 + || pcmcia_parse_tuple(link, &tuple, &parse) + != 0) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { + dflt = *cfg; + } + + if (cfg->index == 0) + goto next_entry; + + link->conf.ConfigIndex = cfg->index; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000 + != conf.Vcc) + goto next_entry; + } else if (dflt.vcc.present & (1<vpp1.present & (1<conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vpp1.present & (1<conf.Vpp = + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; + + /* we need an interrupt */ + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) + link->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + + if (pcmcia_request_io(link, &link->io) != 0) + goto next_entry; + } + break; + +next_entry: + pcmcia_disable_device(link); + last_ret = pcmcia_get_next_tuple(link, &tuple); + } /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) - goto failed; + goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); else - goto failed; + goto cs_failed; CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -242,9 +266,8 @@ static int sl811_cs_config(struct pcmcia_device *link) if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: + printk("sl811_cs_config failed\n"); cs_error(link, last_fn, last_ret); -failed: - printk(KERN_WARNING "sl811_cs_config failed\n"); sl811_cs_release(link); return -ENODEV; } diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 1f0c2cf26e5d..db645936eedd 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -123,10 +123,14 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) { - if (!list_empty(&td->list)) - dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td); - if (!list_empty(&td->fl_list)) - dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td); + if (!list_empty(&td->list)) { + dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); + WARN_ON(1); + } + if (!list_empty(&td->fl_list)) { + dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); + WARN_ON(1); + } dma_pool_free(uhci->td_pool, td, td->dma_handle); } @@ -291,8 +295,10 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) { WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); - if (!list_empty(&qh->queue)) - dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh); + if (!list_empty(&qh->queue)) { + dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh); + WARN_ON(1); + } list_del(&qh->node); if (qh->udev) { @@ -740,9 +746,11 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, { struct uhci_td *td, *tmp; - if (!list_empty(&urbp->node)) - dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n", + if (!list_empty(&urbp->node)) { + dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", urbp->urb); + WARN_ON(1); + } list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { uhci_remove_td_from_urbp(td); diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index cc8e0a926f99..4cfa25b0f44e 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -595,8 +595,9 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic } while(value); kit->dev_no = bit; - kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0), - kit, "interfacekit%d", kit->dev_no); + kit->dev = device_create_drvdata(phidget_class, &kit->udev->dev, + MKDEV(0, 0), kit, + "interfacekit%d", kit->dev_no); if (IS_ERR(kit->dev)) { rc = PTR_ERR(kit->dev); kit->dev = NULL; diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index 38088b44349e..9b4696f21b22 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -365,8 +365,9 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic } while(value); mc->dev_no = bit; - mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc, - "motorcontrol%d", mc->dev_no); + mc->dev = device_create_drvdata(phidget_class, &mc->udev->dev, + MKDEV(0, 0), mc, + "motorcontrol%d", mc->dev_no); if (IS_ERR(mc->dev)) { rc = PTR_ERR(mc->dev); mc->dev = NULL; diff --git a/trunk/drivers/usb/misc/phidgetservo.c b/trunk/drivers/usb/misc/phidgetservo.c index bef6fe16364b..1ca7ddb41d4d 100644 --- a/trunk/drivers/usb/misc/phidgetservo.c +++ b/trunk/drivers/usb/misc/phidgetservo.c @@ -275,8 +275,9 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) } while (value); dev->dev_no = bit; - dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0), - dev, "servo%d", dev->dev_no); + dev->dev = device_create_drvdata(phidget_class, &dev->udev->dev, + MKDEV(0, 0), dev, + "servo%d", dev->dev_no); if (IS_ERR(dev->dev)) { rc = PTR_ERR(dev->dev); dev->dev = NULL; diff --git a/trunk/drivers/usb/mon/mon_bin.c b/trunk/drivers/usb/mon/mon_bin.c index c9de3f027aab..6566fc0a3228 100644 --- a/trunk/drivers/usb/mon/mon_bin.c +++ b/trunk/drivers/usb/mon/mon_bin.c @@ -1162,9 +1162,9 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus) if (minor >= MON_BIN_MAX_MINOR) return 0; - dev = device_create(mon_bin_class, ubus ? ubus->controller : NULL, - MKDEV(MAJOR(mon_bin_dev0), minor), NULL, - "usbmon%d", minor); + dev = device_create_drvdata(mon_bin_class, ubus? ubus->controller: NULL, + MKDEV(MAJOR(mon_bin_dev0), minor), NULL, + "usbmon%d", minor); if (IS_ERR(dev)) return 0; diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index 99fb7dc59c45..79ea98c66fa8 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -272,7 +272,7 @@ static void aircable_read(struct work_struct *work) * 64 bytes, to ensure I do not get throttled. * Ask USB mailing list for better aproach. */ - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (!tty) { schedule_work(&priv->rx_work); @@ -283,13 +283,12 @@ static void aircable_read(struct work_struct *work) count = min(64, serial_buf_data_avail(priv->rx_buf)); if (count <= 0) - goto out; /* We have finished sending everything. */ + return; /* We have finished sending everything. */ tty_prepare_flip_string(tty, &data, count); if (!data) { - dev_err(&port->dev, "%s- kzalloc(%d) failed.", - __func__, count); - goto out; + err("%s- kzalloc(%d) failed.", __func__, count); + return; } serial_buf_get(priv->rx_buf, data, count); @@ -298,8 +297,7 @@ static void aircable_read(struct work_struct *work) if (serial_buf_data_avail(priv->rx_buf)) schedule_work(&priv->rx_work); -out: - tty_kref_put(tty); + return; } /* End of private methods */ @@ -497,7 +495,7 @@ static void aircable_read_bulk_callback(struct urb *urb) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, urb->transfer_buffer); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { if (urb->actual_length <= 2) { /* This is an incomplete package */ @@ -529,7 +527,6 @@ static void aircable_read_bulk_callback(struct urb *urb) } aircable_read(&priv->rx_work); } - tty_kref_put(tty); /* Schedule the next read _if_ we are still open */ if (port->port.count) { diff --git a/trunk/drivers/usb/serial/belkin_sa.c b/trunk/drivers/usb/serial/belkin_sa.c index 1913bc7c5f0b..2ebe06c3405a 100644 --- a/trunk/drivers/usb/serial/belkin_sa.c +++ b/trunk/drivers/usb/serial/belkin_sa.c @@ -322,7 +322,7 @@ static void belkin_sa_read_int_callback(struct urb *urb) * to look in to this before committing any code. */ if (priv->last_lsr & BELKIN_SA_LSR_ERR) { - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; /* Overrun Error */ if (priv->last_lsr & BELKIN_SA_LSR_OE) { } @@ -335,7 +335,6 @@ static void belkin_sa_read_int_callback(struct urb *urb) /* Break Indicator */ if (priv->last_lsr & BELKIN_SA_LSR_BI) { } - tty_kref_put(tty); } #endif spin_unlock_irqrestore(&priv->lock, flags); diff --git a/trunk/drivers/usb/serial/console.c b/trunk/drivers/usb/serial/console.c index 5b20de130e08..e980766bb84b 100644 --- a/trunk/drivers/usb/serial/console.c +++ b/trunk/drivers/usb/serial/console.c @@ -117,7 +117,7 @@ static int usb_console_setup(struct console *co, char *options) } port = serial->port[0]; - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; info->port = port; @@ -143,7 +143,7 @@ static int usb_console_setup(struct console *co, char *options) } memset(&dummy, 0, sizeof(struct ktermios)); tty->termios = termios; - tty_port_tty_set(&port->port, tty); + port->port.tty = tty; } /* only call the device specific open if this @@ -163,7 +163,7 @@ static int usb_console_setup(struct console *co, char *options) tty_termios_encode_baud_rate(termios, baud, baud); serial->type->set_termios(tty, port, &dummy); - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; kfree(termios); kfree(tty); } @@ -176,7 +176,7 @@ static int usb_console_setup(struct console *co, char *options) return retval; free_termios: kfree(termios); - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; free_tty: kfree(tty); reset_open_count: diff --git a/trunk/drivers/usb/serial/cyberjack.c b/trunk/drivers/usb/serial/cyberjack.c index 94ef36c4764b..b4d72351cb96 100644 --- a/trunk/drivers/usb/serial/cyberjack.c +++ b/trunk/drivers/usb/serial/cyberjack.c @@ -384,7 +384,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb) return; } - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (!tty) { dbg("%s - ignoring since device not open\n", __func__); return; @@ -394,7 +394,6 @@ static void cyberjack_read_bulk_callback(struct urb *urb) tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); spin_lock(&priv->lock); diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index f3514a91f915..22837a3f2f89 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/drivers/usb/serial/cypress_m8.c @@ -1286,7 +1286,7 @@ static void cypress_read_int_callback(struct urb *urb) } spin_unlock_irqrestore(&priv->lock, flags); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (!tty) { dbg("%s - bad tty pointer - exiting", __func__); return; @@ -1362,7 +1362,7 @@ static void cypress_read_int_callback(struct urb *urb) data[i]); tty_insert_flip_char(tty, data[i], tty_flag); } - tty_flip_buffer_push(tty); + tty_flip_buffer_push(port->port.tty); } spin_lock_irqsave(&priv->lock, flags); @@ -1371,7 +1371,6 @@ static void cypress_read_int_callback(struct urb *urb) spin_unlock_irqrestore(&priv->lock, flags); continue_read: - tty_kref_put(tty); /* Continue trying to always read... unless the port has closed. */ diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index 5756ac6d6c92..240aad1acaab 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -604,9 +604,7 @@ static void digi_wakeup_write_lock(struct work_struct *work) static void digi_wakeup_write(struct usb_serial_port *port) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - tty_wakeup(tty); - tty_kref_put(tty); + tty_wakeup(port->port.tty); } @@ -1670,7 +1668,7 @@ static int digi_read_inb_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; - struct tty_struct *tty; + struct tty_struct *tty = port->port.tty; struct digi_port *priv = usb_get_serial_port_data(port); int opcode = ((unsigned char *)urb->transfer_buffer)[0]; int len = ((unsigned char *)urb->transfer_buffer)[1]; @@ -1694,7 +1692,6 @@ static int digi_read_inb_callback(struct urb *urb) return -1; } - tty = tty_port_tty_get(&port->port); spin_lock(&priv->dp_port_lock); /* check for throttle; if set, do not resubmit read urb */ @@ -1738,7 +1735,6 @@ static int digi_read_inb_callback(struct urb *urb) } } spin_unlock(&priv->dp_port_lock); - tty_kref_put(tty); if (opcode == DIGI_CMD_RECEIVE_DISABLE) dbg("%s: got RECEIVE_DISABLE", __func__); @@ -1764,7 +1760,6 @@ static int digi_read_oob_callback(struct urb *urb) struct usb_serial_port *port = urb->context; struct usb_serial *serial = port->serial; - struct tty_struct *tty; struct digi_port *priv = usb_get_serial_port_data(port); int opcode, line, status, val; int i; @@ -1792,11 +1787,10 @@ static int digi_read_oob_callback(struct urb *urb) if (priv == NULL) return -1; - tty = tty_port_tty_get(&port->port); rts = 0; if (port->port.count) - rts = tty->termios->c_cflag & CRTSCTS; - + rts = port->port.tty->termios->c_cflag & CRTSCTS; + if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { spin_lock(&priv->dp_port_lock); /* convert from digi flags to termiox flags */ @@ -1804,14 +1798,14 @@ static int digi_read_oob_callback(struct urb *urb) priv->dp_modem_signals |= TIOCM_CTS; /* port must be open to use tty struct */ if (rts) { - tty->hw_stopped = 0; + port->port.tty->hw_stopped = 0; digi_wakeup_write(port); } } else { priv->dp_modem_signals &= ~TIOCM_CTS; /* port must be open to use tty struct */ if (rts) - tty->hw_stopped = 1; + port->port.tty->hw_stopped = 1; } if (val & DIGI_READ_INPUT_SIGNALS_DSR) priv->dp_modem_signals |= TIOCM_DSR; @@ -1836,7 +1830,6 @@ static int digi_read_oob_callback(struct urb *urb) } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { wake_up_interruptible(&priv->dp_flush_wait); } - tty_kref_put(tty); } return 0; diff --git a/trunk/drivers/usb/serial/empeg.c b/trunk/drivers/usb/serial/empeg.c index 1072e847280f..a6ab5b58d9ca 100644 --- a/trunk/drivers/usb/serial/empeg.c +++ b/trunk/drivers/usb/serial/empeg.c @@ -33,8 +33,9 @@ * Moved MOD_DEC_USE_COUNT to end of empeg_close(). * * (12/03/2000) gb - * Added tty->ldisc.set_termios(port, tty, NULL) to empeg_open(). - * This notifies the tty driver that the termios have changed. + * Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to + * empeg_open(). This notifies the tty driver that the termios have + * changed. * * (11/13/2000) gb * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to @@ -353,7 +354,7 @@ static void empeg_read_bulk_callback(struct urb *urb) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); @@ -361,7 +362,6 @@ static void empeg_read_bulk_callback(struct urb *urb) tty_flip_buffer_push(tty); bytes_in += urb->actual_length; } - tty_kref_put(tty); /* Continue trying to always read */ usb_fill_bulk_urb( diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index c2ac129557aa..3dc93b542b30 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -860,7 +860,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, kfree(buf); if (rv < 0) { - dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", + err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", __func__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", @@ -1808,7 +1808,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) if (port->port.count <= 0) return; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (!tty) { dbg("%s - bad tty pointer - exiting", __func__); return; @@ -1817,7 +1817,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) priv = usb_get_serial_port_data(port); if (!priv) { dbg("%s - bad port private data pointer - exiting", __func__); - goto out; + return; } if (urb != port->read_urb) @@ -1827,7 +1827,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) /* This will happen at close every time so it is a dbg not an err */ dbg("(this is ok on close) nonzero read bulk status received: %d", status); - goto out; + return; } /* count data bytes, but not status bytes */ @@ -1838,8 +1838,7 @@ static void ftdi_read_bulk_callback(struct urb *urb) spin_unlock_irqrestore(&priv->rx_lock, flags); ftdi_process_read(&priv->rx_work.work); -out: - tty_kref_put(tty); + } /* ftdi_read_bulk_callback */ @@ -1864,7 +1863,7 @@ static void ftdi_process_read(struct work_struct *work) if (port->port.count <= 0) return; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (!tty) { dbg("%s - bad tty pointer - exiting", __func__); return; @@ -1873,13 +1872,13 @@ static void ftdi_process_read(struct work_struct *work) priv = usb_get_serial_port_data(port); if (!priv) { dbg("%s - bad port private data pointer - exiting", __func__); - goto out; + return; } urb = port->read_urb; if (!urb) { dbg("%s - bad read_urb pointer - exiting", __func__); - goto out; + return; } data = urb->transfer_buffer; @@ -2021,7 +2020,7 @@ static void ftdi_process_read(struct work_struct *work) schedule_delayed_work(&priv->rx_work, 1); else dbg("%s - port is closed", __func__); - goto out; + return; } /* urb is completely processed */ @@ -2042,8 +2041,6 @@ static void ftdi_process_read(struct work_struct *work) err("%s - failed resubmitting read urb, error %d", __func__, result); } -out: - tty_kref_put(tty); } /* ftdi_process_read */ @@ -2259,7 +2256,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) 0, 0, buf, 1, WDR_TIMEOUT); if (ret < 0) { - dbg("%s Could not get modem status of device - err: %d", __func__, + err("%s Could not get modem status of device - err: %d", __func__, ret); return ret; } @@ -2278,7 +2275,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) 0, priv->interface, buf, 2, WDR_TIMEOUT); if (ret < 0) { - dbg("%s Could not get modem status of device - err: %d", __func__, + err("%s Could not get modem status of device - err: %d", __func__, ret); return ret; } diff --git a/trunk/drivers/usb/serial/garmin_gps.c b/trunk/drivers/usb/serial/garmin_gps.c index 2ad0569bcf19..d95382088075 100644 --- a/trunk/drivers/usb/serial/garmin_gps.c +++ b/trunk/drivers/usb/serial/garmin_gps.c @@ -276,7 +276,7 @@ static inline int isAbortTrfCmnd(const unsigned char *buf) static void send_to_tty(struct usb_serial_port *port, char *data, unsigned int actual_length) { - struct tty_struct *tty = tty_port_tty_get(&port->port); + struct tty_struct *tty = port->port.tty; if (tty && actual_length) { @@ -287,7 +287,6 @@ static void send_to_tty(struct usb_serial_port *port, tty_insert_flip_string(tty, data, actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); } diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index 814909f1ee63..fe84c88ec20c 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -330,7 +330,7 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) static void flush_and_resubmit_read_urb(struct usb_serial_port *port) { struct urb *urb = port->read_urb; - struct tty_struct *tty = tty_port_tty_get(&port->port); + struct tty_struct *tty = port->port.tty; int room; /* Push data to tty */ @@ -341,7 +341,6 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port) tty_flip_buffer_push(tty); } } - tty_kref_put(tty); resubmit_read_urb(port, GFP_ATOMIC); } diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index 611f97fd62f1..bfa508ddb0fe 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/drivers/usb/serial/io_edgeport.c @@ -600,7 +600,6 @@ static void edge_interrupt_callback(struct urb *urb) struct edgeport_serial *edge_serial = urb->context; struct edgeport_port *edge_port; struct usb_serial_port *port; - struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int length = urb->actual_length; int bytes_avail; @@ -676,12 +675,9 @@ static void edge_interrupt_callback(struct urb *urb) /* tell the tty driver that something has changed */ - tty = tty_port_tty_get( - &edge_port->port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + if (edge_port->port->port.tty) + tty_wakeup(edge_port->port->port.tty); + /* Since we have more credit, check if more data can be sent */ send_more_port_data(edge_serial, @@ -782,14 +778,13 @@ static void edge_bulk_out_data_callback(struct urb *urb) __func__, status); } - tty = tty_port_tty_get(&edge_port->port->port); + tty = edge_port->port->port.tty; if (tty && edge_port->open) { /* let the tty driver wakeup if it has a special write_wakeup function */ tty_wakeup(tty); } - tty_kref_put(tty); /* Release the Write URB */ edge_port->write_in_progress = false; @@ -831,12 +826,11 @@ static void edge_bulk_out_cmd_callback(struct urb *urb) } /* Get pointer to tty */ - tty = tty_port_tty_get(&edge_port->port->port); + tty = edge_port->port->port.tty; /* tell the tty driver that something has changed */ if (tty && edge_port->open) tty_wakeup(tty); - tty_kref_put(tty); /* we have completed the command */ edge_port->commandPending = false; @@ -1938,13 +1932,11 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, edge_serial->rxPort]; edge_port = usb_get_serial_port_data(port); if (edge_port->open) { - tty = tty_port_tty_get( - &edge_port->port->port); + tty = edge_port->port->port.tty; if (tty) { dbg("%s - Sending %d bytes to TTY for port %d", __func__, rxLen, edge_serial->rxPort); edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); - tty_kref_put(tty); } edge_port->icount.rx += rxLen; } @@ -1979,7 +1971,6 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, { struct usb_serial_port *port; struct edgeport_port *edge_port; - struct tty_struct *tty; __u8 code = edge_serial->rxStatusCode; /* switch the port pointer to the one being currently talked about */ @@ -2029,12 +2020,10 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, /* send the current line settings to the port so we are in sync with any further termios calls */ - tty = tty_port_tty_get(&edge_port->port->port); - if (tty) { - change_port_settings(tty, - edge_port, tty->termios); - tty_kref_put(tty); - } + /* FIXME: locking on tty */ + if (edge_port->port->port.tty) + change_port_settings(edge_port->port->port.tty, + edge_port, edge_port->port->port.tty->termios); /* we have completed the open */ edge_port->openPending = false; @@ -2174,14 +2163,10 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, } /* Place LSR data byte into Rx buffer */ - if (lsrData) { - struct tty_struct *tty = - tty_port_tty_get(&edge_port->port->port); - if (tty) { - edge_tty_recv(&edge_port->port->dev, tty, &data, 1); - tty_kref_put(tty); - } - } + if (lsrData && edge_port->port->port.tty) + edge_tty_recv(&edge_port->port->dev, + edge_port->port->port.tty, &data, 1); + /* update input line counters */ icount = &edge_port->icount; if (newLsr & LSR_BREAK) diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 541dd8e6e7a2..cb4c54316cf5 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -572,7 +572,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, int flush) { int baud_rate; - struct tty_struct *tty = tty_port_tty_get(&port->port->port); + struct tty_struct *tty = port->port->port.tty; wait_queue_t wait; unsigned long flags; @@ -599,7 +599,6 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, if (flush) edge_buf_clear(port->ep_out_buf); spin_unlock_irqrestore(&port->ep_lock, flags); - tty_kref_put(tty); /* wait for data to drain from the device */ timeout += jiffies; @@ -1555,7 +1554,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) /* Save the new modem status */ edge_port->shadow_msr = msr & 0xf0; - tty = tty_port_tty_get(&edge_port->port->port); + tty = edge_port->port->port.tty; /* handle CTS flow control */ if (tty && C_CRTSCTS(tty)) { if (msr & EDGEPORT_MSR_CTS) { @@ -1565,7 +1564,6 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) tty->hw_stopped = 1; } } - tty_kref_put(tty); return; } @@ -1576,7 +1574,6 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, struct async_icount *icount; __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK)); - struct tty_struct *tty; dbg("%s - %02x", __func__, new_lsr); @@ -1590,13 +1587,8 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); /* Place LSR data byte into Rx buffer */ - if (lsr_data) { - tty = tty_port_tty_get(&edge_port->port->port); - if (tty) { - edge_tty_recv(&edge_port->port->dev, tty, &data, 1); - tty_kref_put(tty); - } - } + if (lsr_data && edge_port->port->port.tty) + edge_tty_recv(&edge_port->port->dev, edge_port->port->port.tty, &data, 1); /* update input line counters */ icount = &edge_port->icount; @@ -1757,7 +1749,7 @@ static void edge_bulk_in_callback(struct urb *urb) ++data; } - tty = tty_port_tty_get(&edge_port->port->port); + tty = edge_port->port->port.tty; if (tty && urb->actual_length) { usb_serial_debug_data(debug, &edge_port->port->dev, __func__, urb->actual_length, data); @@ -1769,7 +1761,6 @@ static void edge_bulk_in_callback(struct urb *urb) urb->actual_length); edge_port->icount.rx += urb->actual_length; } - tty_kref_put(tty); exit: /* continue read unless stopped */ @@ -1805,7 +1796,6 @@ static void edge_bulk_out_callback(struct urb *urb) struct usb_serial_port *port = urb->context; struct edgeport_port *edge_port = usb_get_serial_port_data(port); int status = urb->status; - struct tty_struct *tty; dbg("%s - port %d", __func__, port->number); @@ -1828,9 +1818,7 @@ static void edge_bulk_out_callback(struct urb *urb) } /* send any buffered data */ - tty = tty_port_tty_get(&port->port); - edge_send(tty); - tty_kref_put(tty); + edge_send(port->port.tty); } static int edge_open(struct tty_struct *tty, @@ -1888,7 +1876,7 @@ static int edge_open(struct tty_struct *tty, /* set up the port settings */ if (tty) - edge_set_termios(tty, port, tty->termios); + edge_set_termios(tty, port, port->port.tty->termios); /* open up the port */ diff --git a/trunk/drivers/usb/serial/ipaq.c b/trunk/drivers/usb/serial/ipaq.c index 2affa9c118b2..cd9a2e138c8b 100644 --- a/trunk/drivers/usb/serial/ipaq.c +++ b/trunk/drivers/usb/serial/ipaq.c @@ -764,14 +764,13 @@ static void ipaq_read_bulk_callback(struct urb *urb) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); bytes_in += urb->actual_length; } - tty_kref_put(tty); /* Continue trying to always read */ usb_fill_bulk_urb(port->read_urb, port->serial->dev, diff --git a/trunk/drivers/usb/serial/ipw.c b/trunk/drivers/usb/serial/ipw.c index 480cac27d646..a842025b9b57 100644 --- a/trunk/drivers/usb/serial/ipw.c +++ b/trunk/drivers/usb/serial/ipw.c @@ -170,13 +170,12 @@ static void ipw_read_bulk_callback(struct urb *urb) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* Continue trying to always read */ usb_fill_bulk_urb(port->read_urb, port->serial->dev, diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index 45d4043e04ab..e59155c6607d 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/drivers/usb/serial/ir-usb.c @@ -465,12 +465,11 @@ static void ir_read_bulk_callback(struct urb *urb) ir_baud = *data & 0x0f; usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty_buffer_request_room(tty, urb->actual_length - 1)) { tty_insert_flip_string(tty, data+1, urb->actual_length - 1); tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* * No break here. diff --git a/trunk/drivers/usb/serial/iuu_phoenix.c b/trunk/drivers/usb/serial/iuu_phoenix.c index 53710aa7eadd..ddff37fa6339 100644 --- a/trunk/drivers/usb/serial/iuu_phoenix.c +++ b/trunk/drivers/usb/serial/iuu_phoenix.c @@ -629,14 +629,13 @@ static void read_buf_callback(struct urb *urb) } dbg("%s - %i chars to write", __func__, urb->actual_length); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (data == NULL) dbg("%s - data is NULL !!!", __func__); if (tty && urb->actual_length && data) { tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); iuu_led_activity_on(urb); } diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index 15447af48691..704716f6f6d3 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/drivers/usb/serial/keyspan.c @@ -430,7 +430,7 @@ static void usa26_indat_callback(struct urb *urb) } port = urb->context; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { /* 0x80 bit is error flag */ if ((data[0] & 0x80) == 0) { @@ -459,7 +459,6 @@ static void usa26_indat_callback(struct urb *urb) } tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* Resubmit urb so we continue receiving */ urb->dev = port->serial->dev; @@ -514,7 +513,6 @@ static void usa26_instat_callback(struct urb *urb) struct usb_serial *serial; struct usb_serial_port *port; struct keyspan_port_private *p_priv; - struct tty_struct *tty; int old_dcd_state, err; int status = urb->status; @@ -555,11 +553,12 @@ static void usa26_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); + if (port->port.tty && !C_CLOCAL(port->port.tty) + && old_dcd_state != p_priv->dcd_state) { + if (old_dcd_state) + tty_hangup(port->port.tty); + /* else */ + /* wake_up_interruptible(&p_priv->open_wait); */ } /* Resubmit urb so we continue receiving */ @@ -605,12 +604,11 @@ static void usa28_indat_callback(struct urb *urb) p_priv = usb_get_serial_port_data(port); data = urb->transfer_buffer; - tty =tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { + tty = port->port.tty; + if (urb->actual_length) { tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* Resubmit urb so we continue receiving */ urb->dev = port->serial->dev; @@ -654,7 +652,6 @@ static void usa28_instat_callback(struct urb *urb) struct usb_serial *serial; struct usb_serial_port *port; struct keyspan_port_private *p_priv; - struct tty_struct *tty; int old_dcd_state; int status = urb->status; @@ -692,11 +689,12 @@ static void usa28_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if( old_dcd_state != p_priv->dcd_state && old_dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); + if (port->port.tty && !C_CLOCAL(port->port.tty) + && old_dcd_state != p_priv->dcd_state) { + if (old_dcd_state) + tty_hangup(port->port.tty); + /* else */ + /* wake_up_interruptible(&p_priv->open_wait); */ } /* Resubmit urb so we continue receiving */ @@ -787,11 +785,12 @@ static void usa49_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); + if (port->port.tty && !C_CLOCAL(port->port.tty) + && old_dcd_state != p_priv->dcd_state) { + if (old_dcd_state) + tty_hangup(port->port.tty); + /* else */ + /* wake_up_interruptible(&p_priv->open_wait); */ } /* Resubmit urb so we continue receiving */ @@ -828,7 +827,7 @@ static void usa49_indat_callback(struct urb *urb) } port = urb->context; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { /* 0x80 bit is error flag */ if ((data[0] & 0x80) == 0) { @@ -851,7 +850,6 @@ static void usa49_indat_callback(struct urb *urb) } tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* Resubmit urb so we continue receiving */ urb->dev = port->serial->dev; @@ -895,7 +893,7 @@ static void usa49wg_indat_callback(struct urb *urb) return; } port = serial->port[data[i++]]; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; len = data[i++]; /* 0x80 bit is error flag */ @@ -929,7 +927,6 @@ static void usa49wg_indat_callback(struct urb *urb) } if (port->port.count) tty_flip_buffer_push(tty); - tty_kref_put(tty); } } @@ -970,8 +967,8 @@ static void usa90_indat_callback(struct urb *urb) port = urb->context; p_priv = usb_get_serial_port_data(port); + tty = port->port.tty; if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); /* if current mode is DMA, looks like usa28 format otherwise looks like usa26 data format */ @@ -1007,7 +1004,6 @@ static void usa90_indat_callback(struct urb *urb) } } tty_flip_buffer_push(tty); - tty_kref_put(tty); } /* Resubmit urb so we continue receiving */ @@ -1029,7 +1025,6 @@ static void usa90_instat_callback(struct urb *urb) struct usb_serial *serial; struct usb_serial_port *port; struct keyspan_port_private *p_priv; - struct tty_struct *tty; int old_dcd_state, err; int status = urb->status; @@ -1058,11 +1053,12 @@ static void usa90_instat_callback(struct urb *urb) p_priv->dcd_state = ((msg->dcd) ? 1 : 0); p_priv->ri_state = ((msg->ri) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); + if (port->port.tty && !C_CLOCAL(port->port.tty) + && old_dcd_state != p_priv->dcd_state) { + if (old_dcd_state) + tty_hangup(port->port.tty); + /* else */ + /* wake_up_interruptible(&p_priv->open_wait); */ } /* Resubmit urb so we continue receiving */ @@ -1134,11 +1130,12 @@ static void usa67_instat_callback(struct urb *urb) p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); + if (port->port.tty && !C_CLOCAL(port->port.tty) + && old_dcd_state != p_priv->dcd_state) { + if (old_dcd_state) + tty_hangup(port->port.tty); + /* else */ + /* wake_up_interruptible(&p_priv->open_wait); */ } /* Resubmit urb so we continue receiving */ @@ -1335,7 +1332,7 @@ static void keyspan_close(struct tty_struct *tty, stop_urb(p_priv->out_urbs[i]); } } - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; } /* download the firmware to a pre-renumeration device */ diff --git a/trunk/drivers/usb/serial/keyspan_pda.c b/trunk/drivers/usb/serial/keyspan_pda.c index 99e9a14c5bf6..040040a267d9 100644 --- a/trunk/drivers/usb/serial/keyspan_pda.c +++ b/trunk/drivers/usb/serial/keyspan_pda.c @@ -172,9 +172,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) struct keyspan_pda_private *priv = container_of(work, struct keyspan_pda_private, wakeup_work); struct usb_serial_port *port = priv->port; - struct tty_struct *tty = tty_port_tty_get(&port->port); - tty_wakeup(tty); - tty_kref_put(tty); + + tty_wakeup(port->port.tty); } static void keyspan_pda_request_unthrottle(struct work_struct *work) @@ -206,7 +205,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) static void keyspan_pda_rx_interrupt(struct urb *urb) { struct usb_serial_port *port = urb->context; - struct tty_struct *tty = tty_port_tty_get(&port->port); + struct tty_struct *tty = port->port.tty; unsigned char *data = urb->transfer_buffer; int retval; int status = urb->status; @@ -223,7 +222,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __func__, status); - goto out; + return; default: dbg("%s - nonzero urb status received: %d", __func__, status); @@ -262,11 +261,8 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) - dev_err(&port->dev, - "%s - usb_submit_urb failed with result %d", - __func__, retval); -out: - tty_kref_put(tty); + err("%s - usb_submit_urb failed with result %d", + __func__, retval); } diff --git a/trunk/drivers/usb/serial/kl5kusb105.c b/trunk/drivers/usb/serial/kl5kusb105.c index ff3a07f5102f..b84dddc71124 100644 --- a/trunk/drivers/usb/serial/kl5kusb105.c +++ b/trunk/drivers/usb/serial/kl5kusb105.c @@ -658,7 +658,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb) } else { int bytes_sent = ((__u8 *) data)[0] + ((unsigned int) ((__u8 *) data)[1] << 8); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; /* we should immediately resubmit the URB, before attempting * to pass the data on to the tty layer. But that needs locking * against re-entry an then mixed-up data because of @@ -679,7 +679,6 @@ static void klsi_105_read_bulk_callback(struct urb *urb) tty_buffer_request_room(tty, bytes_sent); tty_insert_flip_string(tty, data + 2, bytes_sent); tty_flip_buffer_push(tty); - tty_kref_put(tty); /* again lockless, but debug info only */ priv->bytes_in += bytes_sent; diff --git a/trunk/drivers/usb/serial/kobil_sct.c b/trunk/drivers/usb/serial/kobil_sct.c index cfcf37c2b957..deba28ec77e8 100644 --- a/trunk/drivers/usb/serial/kobil_sct.c +++ b/trunk/drivers/usb/serial/kobil_sct.c @@ -383,7 +383,7 @@ static void kobil_read_int_callback(struct urb *urb) return; } - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (urb->actual_length) { /* BEGIN DEBUG */ @@ -405,7 +405,6 @@ static void kobil_read_int_callback(struct urb *urb) tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* someone sets the dev to 0 if the close method has been called */ port->interrupt_in_urb->dev = port->serial->dev; diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index 9b2cef81cde0..0ded8bd6ec85 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/drivers/usb/serial/mct_u232.c @@ -563,11 +563,10 @@ static void mct_u232_read_int_callback(struct urb *urb) * Work-a-round: handle the 'usual' bulk-in pipe here */ if (urb->transfer_buffer_length > 2) { - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (urb->actual_length) { tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); - tty_kref_put(tty); } goto exit; } @@ -592,7 +591,7 @@ static void mct_u232_read_int_callback(struct urb *urb) * to look in to this before committing any code. */ if (priv->last_lsr & MCT_U232_LSR_ERR) { - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; /* Overrun Error */ if (priv->last_lsr & MCT_U232_LSR_OE) { } @@ -605,7 +604,6 @@ static void mct_u232_read_int_callback(struct urb *urb) /* Break Indicator */ if (priv->last_lsr & MCT_U232_LSR_BI) { } - tty_kref_put(tty); } #endif spin_unlock_irqrestore(&priv->lock, flags); diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index 7b538caec37f..7c4917d77c0a 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -216,13 +216,12 @@ static void mos7720_bulk_in_callback(struct urb *urb) data = urb->transfer_buffer; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); if (!port->read_urb) { dbg("URB KILLED !!!"); @@ -263,11 +262,10 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) dbg("Entering ........."); - tty = tty_port_tty_get(&mos7720_port->port->port); + tty = mos7720_port->port->port.tty; if (tty && mos7720_port->open) tty_wakeup(tty); - tty_kref_put(tty); } /* @@ -1269,6 +1267,29 @@ static int get_lsr_info(struct tty_struct *tty, return 0; } +/* + * get_number_bytes_avail - get number of bytes available + * + * Purpose: Let user call ioctl to get the count of number of bytes available. + */ +static int get_number_bytes_avail(struct moschip_port *mos7720_port, + unsigned int __user *value) +{ + unsigned int result = 0; + struct tty_struct *tty = mos7720_port->port->port.tty; + + if (!tty) + return -ENOIOCTLCMD; + + result = tty->read_cnt; + + dbg("%s(%d) = %d", __func__, mos7720_port->port->number, result); + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + + return -ENOIOCTLCMD; +} + static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, unsigned int __user *value) { @@ -1388,6 +1409,13 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file, dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); switch (cmd) { + case TIOCINQ: + /* return number of bytes available */ + dbg("%s (%d) TIOCINQ", __func__, port->number); + return get_number_bytes_avail(mos7720_port, + (unsigned int __user *)arg); + break; + case TIOCSERGETLSR: dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); return get_lsr_info(tty, mos7720_port, diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 60543d79ef56..09d82062b973 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -709,13 +709,12 @@ static void mos7840_bulk_in_callback(struct urb *urb) dbg("%s", "Entering ........... \n"); if (urb->actual_length) { - tty = tty_port_tty_get(&mos7840_port->port->port); + tty = mos7840_port->port->port.tty; if (tty) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); dbg(" %s \n", data); tty_flip_buffer_push(tty); - tty_kref_put(tty); } mos7840_port->icount.rx += urb->actual_length; smp_wmb(); @@ -774,10 +773,10 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) dbg("%s \n", "Entering ........."); - tty = tty_port_tty_get(&mos7840_port->port->port); + tty = mos7840_port->port->port.tty; + if (tty && mos7840_port->open) tty_wakeup(tty); - tty_kref_put(tty); } diff --git a/trunk/drivers/usb/serial/navman.c b/trunk/drivers/usb/serial/navman.c index bcdcbb822705..d6736531a0fa 100644 --- a/trunk/drivers/usb/serial/navman.c +++ b/trunk/drivers/usb/serial/navman.c @@ -64,13 +64,12 @@ static void navman_read_int_callback(struct urb *urb) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); exit: result = usb_submit_urb(urb, GFP_ATOMIC); diff --git a/trunk/drivers/usb/serial/omninet.c b/trunk/drivers/usb/serial/omninet.c index c4d70b0f1e48..ae8e227f3db2 100644 --- a/trunk/drivers/usb/serial/omninet.c +++ b/trunk/drivers/usb/serial/omninet.c @@ -172,7 +172,7 @@ static int omninet_open(struct tty_struct *tty, dbg("%s - port %d", __func__, port->number); wport = serial->port[1]; - tty_port_tty_set(&wport->port, tty); + wport->port.tty = tty; /* FIXME */ /* Start reading from the device */ usb_fill_bulk_urb(port->read_urb, serial->dev, @@ -229,11 +229,9 @@ static void omninet_read_bulk_callback(struct urb *urb) } if (urb->actual_length && header->oh_len) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, - header->oh_len); - tty_flip_buffer_push(tty); - tty_kref_put(tty); + tty_insert_flip_string(port->port.tty, + data + OMNINET_DATAOFFSET, header->oh_len); + tty_flip_buffer_push(port->port.tty); } /* Continue trying to always read */ diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 6b1727e751e3..73f8277f88f2 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -571,14 +571,14 @@ static void option_indat_callback(struct urb *urb) dbg("%s: nonzero status: %d on endpoint %02x.", __func__, status, endpoint); } else { - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); - } else + } else { dbg("%s: empty read urb received", __func__); - tty_kref_put(tty); + } /* Resubmit urb so we continue receiving */ if (port->port.count && status != -ESHUTDOWN) { @@ -647,13 +647,9 @@ static void option_instat_callback(struct urb *urb) portdata->dsr_state = ((signals & 0x02) ? 1 : 0); portdata->ri_state = ((signals & 0x08) ? 1 : 0); - if (old_dcd_state && !portdata->dcd_state) { - struct tty_struct *tty = - tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } + if (port->port.tty && !C_CLOCAL(port->port.tty) && + old_dcd_state && !portdata->dcd_state) + tty_hangup(port->port.tty); } else { dbg("%s: type %x req %x", __func__, req_pkt->bRequestType, req_pkt->bRequest); @@ -797,7 +793,7 @@ static void option_close(struct tty_struct *tty, for (i = 0; i < N_OUT_URB; i++) usb_kill_urb(portdata->out_urbs[i]); } - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; /* FIXME */ } /* Helper functions used by option_setup_urbs */ diff --git a/trunk/drivers/usb/serial/oti6858.c b/trunk/drivers/usb/serial/oti6858.c index ba551f00f16f..81db5715ee25 100644 --- a/trunk/drivers/usb/serial/oti6858.c +++ b/trunk/drivers/usb/serial/oti6858.c @@ -224,6 +224,10 @@ struct oti6858_private { struct usb_serial_port *port; /* USB port with which associated */ }; +#undef dbg +/* #define dbg(format, arg...) printk(KERN_INFO "%s: " format "\n", __FILE__, ## arg) */ +#define dbg(format, arg...) printk(KERN_INFO "" format "\n", ## arg) + static void setup_line(struct work_struct *work) { struct oti6858_private *priv = container_of(work, @@ -998,12 +1002,11 @@ static void oti6858_read_bulk_callback(struct urb *urb) return; } - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty != NULL && urb->actual_length > 0) { tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* schedule the interrupt urb if we are still open */ if (port->port.count != 0) { diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index 908437847165..1ede1441cb1b 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -154,6 +154,7 @@ struct pl2303_private { wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; + u8 termios_initialized; enum pl2303_type type; }; @@ -525,6 +526,16 @@ static void pl2303_set_termios(struct tty_struct *tty, dbg("%s - port %d", __func__, port->number); + spin_lock_irqsave(&priv->lock, flags); + if (!priv->termios_initialized) { + *(tty->termios) = tty_std_termios; + tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->termios->c_ispeed = 9600; + tty->termios->c_ospeed = 9600; + priv->termios_initialized = 1; + } + spin_unlock_irqrestore(&priv->lock, flags); + /* The PL2303 is reported to lose bytes if you change serial settings even to the same values as before. Thus we actually need to filter in this specific case */ @@ -1046,7 +1057,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) tty_flag = TTY_FRAME; dbg("%s - tty_flag = %d", __func__, tty_flag); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length + 1); /* overrun is special, not associated with a char */ @@ -1056,7 +1067,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) tty_insert_flip_char(tty, data[i], tty_flag); tty_flip_buffer_push(tty); } - tty_kref_put(tty); + /* Schedule the next read _if_ we are still open */ if (port->port.count) { urb->dev = port->serial->dev; diff --git a/trunk/drivers/usb/serial/safe_serial.c b/trunk/drivers/usb/serial/safe_serial.c index 72903ac9f5c0..def52d07a4ea 100644 --- a/trunk/drivers/usb/serial/safe_serial.c +++ b/trunk/drivers/usb/serial/safe_serial.c @@ -217,7 +217,6 @@ static void safe_read_bulk_callback(struct urb *urb) struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; unsigned char length = urb->actual_length; - struct tty_struct *tty; int result; int status = urb->status; @@ -243,7 +242,6 @@ static void safe_read_bulk_callback(struct urb *urb) printk("\n"); } #endif - tty = tty_port_tty_get(&port->port); if (safe) { __u16 fcs; fcs = fcs_compute10(data, length, CRC10_INITFCS); @@ -252,9 +250,9 @@ static void safe_read_bulk_callback(struct urb *urb) if (actual_length <= (length - 2)) { info("%s - actual: %d", __func__, actual_length); - tty_insert_flip_string(tty, + tty_insert_flip_string(port->port.tty, data, actual_length); - tty_flip_buffer_push(tty); + tty_flip_buffer_push(port->port.tty); } else { err("%s - inconsistent lengths %d:%d", __func__, actual_length, length); @@ -263,10 +261,9 @@ static void safe_read_bulk_callback(struct urb *urb) err("%s - bad CRC %x", __func__, fcs); } } else { - tty_insert_flip_string(tty, data, length); - tty_flip_buffer_push(tty); + tty_insert_flip_string(port->port.tty, data, length); + tty_flip_buffer_push(port->port.tty); } - tty_kref_put(tty); /* Continue trying to always read */ usb_fill_bulk_urb(urb, port->serial->dev, diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 8b9eaf383679..ea1a103c99be 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -440,14 +440,14 @@ static void sierra_indat_callback(struct urb *urb) dbg("%s: nonzero status: %d on endpoint %02x.", __func__, status, endpoint); } else { + tty = port->port.tty; if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); - tty_kref_put(tty); - } else + } else { dbg("%s: empty read urb received", __func__); + } /* Resubmit urb so we continue receiving */ if (port->port.count && status != -ESHUTDOWN) { @@ -485,7 +485,6 @@ static void sierra_instat_callback(struct urb *urb) unsigned char signals = *((unsigned char *) urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); - struct tty_struct *tty; dbg("%s: signal x%x", __func__, signals); @@ -495,11 +494,9 @@ static void sierra_instat_callback(struct urb *urb) portdata->dsr_state = ((signals & 0x02) ? 1 : 0); portdata->ri_state = ((signals & 0x08) ? 1 : 0); - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty) && + if (port->port.tty && !C_CLOCAL(port->port.tty) && old_dcd_state && !portdata->dcd_state) - tty_hangup(tty); - tty_kref_put(tty); + tty_hangup(port->port.tty); } else { dbg("%s: type %x req %x", __func__, req_pkt->bRequestType, req_pkt->bRequest); @@ -619,7 +616,8 @@ static void sierra_close(struct tty_struct *tty, } usb_kill_urb(port->interrupt_in_urb); - tty_port_tty_set(&port->port, NULL); + + port->port.tty = NULL; /* FIXME */ } static int sierra_startup(struct usb_serial *serial) diff --git a/trunk/drivers/usb/serial/spcp8x5.c b/trunk/drivers/usb/serial/spcp8x5.c index 1533d6e12238..283cf6b36b2c 100644 --- a/trunk/drivers/usb/serial/spcp8x5.c +++ b/trunk/drivers/usb/serial/spcp8x5.c @@ -755,7 +755,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) tty_flag = TTY_FRAME; dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (tty && urb->actual_length) { tty_buffer_request_room(tty, urb->actual_length + 1); /* overrun is special, not associated with a char */ @@ -765,7 +765,6 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) tty_insert_flip_char(tty, data[i], tty_flag); tty_flip_buffer_push(tty); } - tty_kref_put(tty); /* Schedule the next read _if_ we are still open */ if (port->port.count) { diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index c90237d48b0e..9a3e495c769c 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -179,7 +179,7 @@ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); static int ti_get_lsr(struct ti_port *tport); static int ti_get_serial_info(struct ti_port *tport, struct serial_struct __user *ret_arg); -static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, +static int ti_set_serial_info(struct ti_port *tport, struct serial_struct __user *new_arg); static void ti_handle_new_msr(struct ti_port *tport, __u8 msr); @@ -857,8 +857,8 @@ static int ti_ioctl(struct tty_struct *tty, struct file *file, (struct serial_struct __user *)arg); case TIOCSSERIAL: dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); - return ti_set_serial_info(tty, tport, - (struct serial_struct __user *)arg); + return ti_set_serial_info(tport, + (struct serial_struct __user *)arg); case TIOCMIWAIT: dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); cprev = tport->tp_icount; @@ -1211,7 +1211,6 @@ static void ti_bulk_in_callback(struct urb *urb) struct device *dev = &urb->dev->dev; int status = urb->status; int retval = 0; - struct tty_struct *tty; dbg("%s", __func__); @@ -1240,22 +1239,20 @@ static void ti_bulk_in_callback(struct urb *urb) return; } - tty = tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { + if (port->port.tty && urb->actual_length) { usb_serial_debug_data(debug, dev, __func__, urb->actual_length, urb->transfer_buffer); if (!tport->tp_is_open) dbg("%s - port closed, dropping data", __func__); else - ti_recv(&urb->dev->dev, tty, + ti_recv(&urb->dev->dev, port->port.tty, urb->transfer_buffer, urb->actual_length); spin_lock(&tport->tp_lock); tport->tp_icount.rx += urb->actual_length; spin_unlock(&tport->tp_lock); - tty_kref_put(tty); } exit: @@ -1333,7 +1330,7 @@ static void ti_send(struct ti_port *tport) { int count, result; struct usb_serial_port *port = tport->tp_port; - struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */ + struct tty_struct *tty = port->port.tty; /* FIXME */ unsigned long flags; @@ -1341,15 +1338,19 @@ static void ti_send(struct ti_port *tport) spin_lock_irqsave(&tport->tp_lock, flags); - if (tport->tp_write_urb_in_use) - goto unlock; + if (tport->tp_write_urb_in_use) { + spin_unlock_irqrestore(&tport->tp_lock, flags); + return; + } count = ti_buf_get(tport->tp_write_buf, port->write_urb->transfer_buffer, port->bulk_out_size); - if (count == 0) - goto unlock; + if (count == 0) { + spin_unlock_irqrestore(&tport->tp_lock, flags); + return; + } tport->tp_write_urb_in_use = 1; @@ -1379,13 +1380,7 @@ static void ti_send(struct ti_port *tport) /* more room in the buffer for new writes, wakeup */ if (tty) tty_wakeup(tty); - tty_kref_put(tty); wake_up_interruptible(&tport->tp_write_wait); - return; -unlock: - spin_unlock_irqrestore(&tport->tp_lock, flags); - tty_kref_put(tty); - return; } @@ -1469,16 +1464,20 @@ static int ti_get_serial_info(struct ti_port *tport, } -static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, +static int ti_set_serial_info(struct ti_port *tport, struct serial_struct __user *new_arg) { + struct usb_serial_port *port = tport->tp_port; struct serial_struct new_serial; if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) return -EFAULT; tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; - tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0; + /* FIXME */ + if (port->port.tty) + port->port.tty->low_latency = + (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0; tport->tp_closing_wait = new_serial.closing_wait; return 0; @@ -1511,7 +1510,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) tport->tp_msr = msr & TI_MSR_MASK; /* handle CTS flow control */ - tty = tty_port_tty_get(&tport->tp_port->port); + tty = tport->tp_port->port.tty; if (tty && C_CRTSCTS(tty)) { if (msr & TI_MSR_CTS) { tty->hw_stopped = 0; @@ -1520,7 +1519,6 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) tty->hw_stopped = 1; } } - tty_kref_put(tty); } diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index e7d4246027b2..4f7f9e3ae0a4 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -214,7 +214,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) /* set up our port structure making the tty driver * remember our port object, and us it */ tty->driver_data = port; - tty_port_tty_set(&port->port, tty); + port->port.tty = tty; if (port->port.count == 1) { @@ -246,7 +246,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) bailout_mutex_unlock: port->port.count = 0; tty->driver_data = NULL; - tty_port_tty_set(&port->port, NULL); + port->port.tty = NULL; mutex_unlock(&port->mutex); bailout_kref_put: usb_serial_put(serial); @@ -276,11 +276,10 @@ static void serial_close(struct tty_struct *tty, struct file *filp) port->serial->type->close(tty, port, filp); if (port->port.count == (port->console? 1 : 0)) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) { - if (tty->driver_data) - tty->driver_data = NULL; - tty_port_tty_set(&port->port, NULL); + if (port->port.tty) { + if (port->port.tty->driver_data) + port->port.tty->driver_data = NULL; + port->port.tty = NULL; } } @@ -509,12 +508,11 @@ static void usb_serial_port_work(struct work_struct *work) if (!port) return; - tty = tty_port_tty_get(&port->port); + tty = port->port.tty; if (!tty) return; tty_wakeup(tty); - tty_kref_put(tty); } static void port_release(struct device *dev) @@ -821,7 +819,6 @@ int usb_serial_probe(struct usb_interface *interface, port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); if (!port) goto probe_error; - tty_port_init(&port->port); port->serial = serial; spin_lock_init(&port->lock); mutex_init(&port->mutex); @@ -1043,11 +1040,8 @@ void usb_serial_disconnect(struct usb_interface *interface) for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; if (port) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } + if (port->port.tty) + tty_hangup(port->port.tty); kill_traffic(port); } } diff --git a/trunk/drivers/usb/serial/visor.c b/trunk/drivers/usb/serial/visor.c index a6d1c75a1c89..cf8924f9a2cc 100644 --- a/trunk/drivers/usb/serial/visor.c +++ b/trunk/drivers/usb/serial/visor.c @@ -499,7 +499,7 @@ static void visor_read_bulk_callback(struct urb *urb) int status = urb->status; struct tty_struct *tty; int result; - int available_room = 0; + int available_room; dbg("%s - port %d", __func__, port->number); @@ -512,17 +512,13 @@ static void visor_read_bulk_callback(struct urb *urb) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); - if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); - if (tty) { - available_room = tty_buffer_request_room(tty, + tty = port->port.tty; + if (tty && urb->actual_length) { + available_room = tty_buffer_request_room(tty, urb->actual_length); - if (available_room) { - tty_insert_flip_string(tty, data, - available_room); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); + if (available_room) { + tty_insert_flip_string(tty, data, available_room); + tty_flip_buffer_push(tty); } spin_lock(&priv->lock); priv->bytes_in += available_room; diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index 11c8b97a5177..3a9d14384a43 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/drivers/usb/serial/whiteheat.c @@ -1481,7 +1481,7 @@ static void rx_data_softint(struct work_struct *work) struct whiteheat_private *info = container_of(work, struct whiteheat_private, rx_work); struct usb_serial_port *port = info->port; - struct tty_struct *tty = tty_port_tty_get(&port->port); + struct tty_struct *tty = port->port.tty; struct whiteheat_urb_wrap *wrap; struct urb *urb; unsigned long flags; @@ -1493,7 +1493,7 @@ static void rx_data_softint(struct work_struct *work) spin_lock_irqsave(&info->lock, flags); if (info->flags & THROTTLED) { spin_unlock_irqrestore(&info->lock, flags); - goto out; + return; } list_for_each_safe(tmp, tmp2, &info->rx_urb_q) { @@ -1513,7 +1513,7 @@ static void rx_data_softint(struct work_struct *work) spin_unlock_irqrestore(&info->lock, flags); tty_flip_buffer_push(tty); schedule_work(&info->rx_work); - goto out; + return; } tty_insert_flip_string(tty, urb->transfer_buffer, len); sent += len; @@ -1536,8 +1536,6 @@ static void rx_data_softint(struct work_struct *work) if (sent) tty_flip_buffer_push(tty); -out: - tty_kref_put(tty); } diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 0f13448c6f79..f79c2040758b 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -76,14 +76,6 @@ config FB_DDC select I2C default n -config FB_BOOT_VESA_SUPPORT - bool - depends on FB - default n - ---help--- - If true, at least one selected framebuffer driver can take advantage - of VESA video modes set at an early boot stage via the vga= parameter. - config FB_CFB_FILLRECT tristate depends on FB @@ -262,24 +254,16 @@ config FB_PM2 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help - This is the frame buffer device driver for cards based on - the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. - The driver was tested on the following cards: - Diamond FireGL 1000 PRO AGP - ELSA Gloria Synergy PCI - Appian Jeronimo PRO (both heads) PCI - 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI - Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC - ASK Graphic Blaster Exxtreme AGP - - To compile this driver as a module, choose M here: the - module will be called pm2fb. + This is the frame buffer device driver for the Permedia2 AGP frame + buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a + product page at + . config FB_PM2_FIFO_DISCONNECT bool "enable FIFO disconnect feature" depends on FB_PM2 && PCI help - Support the Permedia2 FIFO disconnect feature. + Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2). config FB_ARMCLCD tristate "ARM PrimeCell PL110 support" @@ -689,7 +673,6 @@ config FB_VESA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_BOOT_VESA_SUPPORT help This is the frame buffer device driver for generic VESA 2.0 compliant graphic cards. The older VESA 1.2 cards are not supported. @@ -698,14 +681,23 @@ config FB_VESA config FB_EFI bool "EFI-based Framebuffer Support" - depends on (FB = y) && X86 && EFI + depends on (FB = y) && X86 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help This is the EFI frame buffer device driver. If the firmware on - your platform is EFI 1.10 or UEFI 2.0, select Y to add support for - using the EFI framebuffer as your console. + your platform is UEFI2.0, select Y to add support for + Graphics Output Protocol for early console messages to appear. + +config FB_IMAC + bool "Intel-based Macintosh Framebuffer Support" + depends on (FB = y) && X86 && EFI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Intel-based Macintosh config FB_N411 tristate "N411 Apollo/Hecuba devkit support" @@ -1126,7 +1118,6 @@ config FB_INTEL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_BOOT_VESA_SUPPORT help This driver supports the on-board graphics built in to the Intel 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. @@ -1479,7 +1470,6 @@ config FB_SIS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_BOOT_VESA_SUPPORT help This is the frame buffer device driver for the SiS 300, 315, 330 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. @@ -1502,24 +1492,6 @@ config FB_SIS_315 (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well as XGI V3XT, V5, V8 and Z7. -config FB_VIA - tristate "VIA UniChrome (Pro) and Chrome9 display support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_SOFT_CURSOR - select I2C_ALGOBIT - select I2C - help - This is the frame buffer device driver for Graphics chips of VIA - UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ - CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 - /P4M900,VX800) - Say Y if you have a VIA UniChrome graphics board. - - To compile this driver as a module, choose M here: the - module will be called viafb. config FB_NEOMAGIC tristate "NeoMagic display support" depends on FB && PCI @@ -1549,25 +1521,25 @@ config FB_KYRO module will be called kyrofb. config FB_3DFX - tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" + tristate "3Dfx Banshee/Voodoo3 display support" depends on FB && PCI select FB_CFB_IMAGEBLIT select FB_CFB_FILLRECT select FB_CFB_COPYAREA help - This driver supports graphics boards with the 3Dfx Banshee, - Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have - such a graphics board. + This driver supports graphics boards with the 3Dfx Banshee/Voodoo3 + chips. Say Y if you have such a graphics board. To compile this driver as a module, choose M here: the module will be called tdfxfb. config FB_3DFX_ACCEL - bool "3Dfx Acceleration functions (EXPERIMENTAL)" + bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)" depends on FB_3DFX && EXPERIMENTAL ---help--- - This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer - device driver with acceleration functions. + This will compile the 3Dfx Banshee/Voodoo3 frame buffer device + with acceleration functions. + config FB_VOODOO1 tristate "3Dfx Voodoo Graphics (sst1) support" @@ -1632,16 +1604,17 @@ config FB_TRIDENT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT ---help--- - This is the frame buffer device driver for Trident PCI/AGP chipsets. - Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D - and Blade XP. - There are also integrated versions of these chips called CyberXXXX, - CyberImage or CyberBlade. These chips are mostly found in laptops + This driver is supposed to support graphics boards with the + Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops but also on some motherboards. For more information, read + Cyberblade/i1 support will be removed soon, use the cyblafb driver + instead. + Say Y if you have such a graphics board. + To compile this driver as a module, choose M here: the module will be called tridentfb. @@ -1896,28 +1869,6 @@ config FB_SH_MOBILE_LCDC ---help--- Frame buffer driver for the on-chip SH-Mobile LCD controller. -config FB_TMIO - tristate "Toshiba Mobile IO FrameBuffer support" - depends on FB && MFD_CORE - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the Toshiba Mobile IO integrated as found - on the Sharp SL-6000 series - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called tmiofb. If you want to compile it as a module, - say M here and read . - - If unsure, say N. - -config FB_TMIO_ACCELL - bool "tmiofb acceleration" - depends on FB_TMIO - default y - config FB_S3C2410 tristate "S3C2410 LCD framebuffer support" depends on FB && ARCH_S3C2410 diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 248bddc8d0b0..ad0330bf9be3 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o obj-$(CONFIG_FB_RADEON) += aty/ obj-$(CONFIG_FB_SIS) += sis/ -obj-$(CONFIG_FB_VIA) += via/ obj-$(CONFIG_FB_KYRO) += kyro/ obj-$(CONFIG_FB_SAVAGE) += savage/ obj-$(CONFIG_FB_GEODE) += geode/ @@ -98,7 +97,6 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o obj-$(CONFIG_FB_PXA) += pxafb.o obj-$(CONFIG_FB_W100) += w100fb.o -obj-$(CONFIG_FB_TMIO) += tmiofb.o obj-$(CONFIG_FB_AU1100) += au1100fb.o obj-$(CONFIG_FB_AU1200) += au1200fb.o obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o @@ -126,6 +124,7 @@ obj-$(CONFIG_FB_CARMINE) += carminefb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o obj-$(CONFIG_FB_VESA) += vesafb.o +obj-$(CONFIG_FB_IMAC) += imacfb.o obj-$(CONFIG_FB_EFI) += efifb.o obj-$(CONFIG_FB_VGA16) += vga16fb.o obj-$(CONFIG_FB_OF) += offb.o diff --git a/trunk/drivers/video/atmel_lcdfb.c b/trunk/drivers/video/atmel_lcdfb.c index f8d0a57a07cb..d38fd5217422 100644 --- a/trunk/drivers/video/atmel_lcdfb.c +++ b/trunk/drivers/video/atmel_lcdfb.c @@ -372,13 +372,6 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, var->transp.offset = var->transp.length = 0; var->xoffset = var->yoffset = 0; - if (info->fix.smem_len) { - unsigned int smem_len = (var->xres_virtual * var->yres_virtual - * ((var->bits_per_pixel + 7) / 8)); - if (smem_len > info->fix.smem_len) - return -EINVAL; - } - /* Saturate vertical and horizontal timings at maximum values */ var->vsync_len = min_t(u32, var->vsync_len, (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); diff --git a/trunk/drivers/video/aty/radeon_accel.c b/trunk/drivers/video/aty/radeon_accel.c index 8718f7349d6b..aa95f8350242 100644 --- a/trunk/drivers/video/aty/radeon_accel.c +++ b/trunk/drivers/video/aty/radeon_accel.c @@ -5,61 +5,61 @@ * --dte */ -#define FLUSH_CACHE_WORKAROUND 1 - -void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries) +static void radeon_fixup_offset(struct radeonfb_info *rinfo) { - int i; + u32 local_base; + + /* *** Ugly workaround *** */ + /* + * On some platforms, the video memory is mapped at 0 in radeon chip space + * (like PPCs) by the firmware. X will always move it up so that it's seen + * by the chip to be at the same address as the PCI BAR. + * That means that when switching back from X, there is a mismatch between + * the offsets programmed into the engine. This means that potentially, + * accel operations done before radeonfb has a chance to re-init the engine + * will have incorrect offsets, and potentially trash system memory ! + * + * The correct fix is for fbcon to never call any accel op before the engine + * has properly been re-initialized (by a call to set_var), but this is a + * complex fix. This workaround in the meantime, called before every accel + * operation, makes sure the offsets are in sync. + */ - for (i=0; i<2000000; i++) { - rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f; - if (rinfo->fifo_free >= entries) - return; - udelay(10); - } - printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); - /* XXX Todo: attempt to reset the engine */ -} + radeon_fifo_wait (1); + local_base = INREG(MC_FB_LOCATION) << 16; + if (local_base == rinfo->fb_local_base) + return; -static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) -{ - if (entries <= rinfo->fifo_free) - rinfo->fifo_free -= entries; - else - radeon_fifo_update_and_wait(rinfo, entries); -} + rinfo->fb_local_base = local_base; -static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg, - u32 *cache, u32 new_val) -{ - if (new_val == *cache) - return; - *cache = new_val; - radeon_fifo_wait(rinfo, 1); - OUTREG(reg, new_val); + radeon_fifo_wait (3); + OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | + (rinfo->fb_local_base >> 10)); + OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); + OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); } static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, const struct fb_fillrect *region) { - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache, - region->color); - - /* Ensure the dst cache is flushed and the engine idle before - * issuing the operation. - * - * This works around engine lockups on some cards - */ -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait(4); + + OUTREG(DP_GUI_MASTER_CNTL, + rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ + | GMC_BRUSH_SOLID_COLOR + | ROP3_P); + if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) + OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); + else + OUTREG(DP_BRUSH_FRGD_CLR, region->color); + OUTREG(DP_WRITE_MSK, 0xffffffff); + OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); + + radeon_fifo_wait(2); OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - radeon_fifo_wait(rinfo, 2); + + radeon_fifo_wait(2); OUTREG(DST_Y_X, (region->dy << 16) | region->dx); OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); } @@ -70,14 +70,15 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) struct fb_fillrect modded; int vxres, vyres; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) + if (info->state != FBINFO_STATE_RUNNING) return; if (info->flags & FBINFO_HWACCEL_DISABLED) { cfb_fillrect(info, region); return; } + radeon_fixup_offset(rinfo); + vxres = info->var.xres_virtual; vyres = info->var.yres_virtual; @@ -90,10 +91,6 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR ) - modded.color = ((u32 *) (info->pseudo_palette))[region->color]; - radeonfb_prim_fillrect(rinfo, &modded); } @@ -112,22 +109,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo, if ( xdir < 0 ) { sx += w-1; dx += w-1; } if ( ydir < 0 ) { sy += h-1; dy += h-1; } - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | - GMC_BRUSH_NONE | - GMC_SRC_DATATYPE_COLOR | - ROP3_S | - DP_SRC_SOURCE_MEMORY); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | - (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); - -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait(3); + OUTREG(DP_GUI_MASTER_CNTL, + rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */ + | GMC_BRUSH_NONE + | GMC_SRC_DSTCOLOR + | ROP3_S + | DP_SRC_SOURCE_MEMORY ); + OUTREG(DP_WRITE_MSK, 0xffffffff); + OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) + | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); + + radeon_fifo_wait(2); OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - radeon_fifo_wait(rinfo, 3); + + radeon_fifo_wait(3); OUTREG(SRC_Y_X, (sy << 16) | sx); OUTREG(DST_Y_X, (dy << 16) | dx); OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); @@ -146,14 +143,15 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) modded.width = area->width; modded.height = area->height; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) + if (info->state != FBINFO_STATE_RUNNING) return; if (info->flags & FBINFO_HWACCEL_DISABLED) { cfb_copyarea(info, area); return; } + radeon_fixup_offset(rinfo); + vxres = info->var.xres_virtual; vyres = info->var.yres_virtual; @@ -170,112 +168,13 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) radeonfb_prim_copyarea(rinfo, &modded); } -static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, - const struct fb_image *image, - u32 fg, u32 bg) -{ - unsigned int src_bytes, dwords; - u32 *bits; - - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | - GMC_BRUSH_NONE | - GMC_SRC_DATATYPE_MONO_FG_BG | - ROP3_S | - GMC_BYTE_ORDER_MSB_TO_LSB | - DP_SRC_SOURCE_HOST_DATA); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg); - radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg); - - radeon_fifo_wait(rinfo, 1); - OUTREG(DST_Y_X, (image->dy << 16) | image->dx); - - /* Ensure the dst cache is flushed and the engine idle before - * issuing the operation. - * - * This works around engine lockups on some cards - */ -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); - OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); - OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - - /* X here pads width to a multiple of 32 and uses the clipper to - * adjust the result. Is that really necessary ? Things seem to - * work ok for me without that and the doco doesn't seem to imply - * there is such a restriction. - */ - OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height); - - src_bytes = (((image->width * image->depth) + 7) / 8) * image->height; - dwords = (src_bytes + 3) / 4; - bits = (u32*)(image->data); - - while(dwords >= 8) { - radeon_fifo_wait(rinfo, 8); -#if BITS_PER_LONG == 64 - __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0); - __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2); - __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4); - __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6); - bits += 8; -#else - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7); -#endif - dwords -= 8; - } - while(dwords--) { - radeon_fifo_wait(rinfo, 1); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); - } -} - void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct radeonfb_info *rinfo = info->par; - u32 fg, bg; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) - return; - - if (!image->width || !image->height) + if (info->state != FBINFO_STATE_RUNNING) return; - - /* We only do 1 bpp color expansion for now */ - if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) - goto fallback; - - /* Fallback if running out of the screen. We may do clipping - * in the future */ - if ((image->dx + image->width) > info->var.xres_virtual || - (image->dy + image->height) > info->var.yres_virtual) - goto fallback; - - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fg = ((u32*)(info->pseudo_palette))[image->fg_color]; - bg = ((u32*)(info->pseudo_palette))[image->bg_color]; - } else { - fg = image->fg_color; - bg = image->bg_color; - } - - radeonfb_prim_imageblit(rinfo, image, fg, bg); - return; - - fallback: - radeon_engine_idle(rinfo); + radeon_engine_idle(); cfb_imageblit(info, image); } @@ -286,8 +185,7 @@ int radeonfb_sync(struct fb_info *info) if (info->state != FBINFO_STATE_RUNNING) return 0; - - radeon_engine_idle(rinfo); + radeon_engine_idle(); return 0; } @@ -313,7 +211,9 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo) host_path_cntl = INREG(HOST_PATH_CNTL); rbbm_soft_reset = INREG(RBBM_SOFT_RESET); - if (IS_R300_VARIANT(rinfo)) { + if (rinfo->family == CHIP_FAMILY_R300 || + rinfo->family == CHIP_FAMILY_R350 || + rinfo->family == CHIP_FAMILY_RV350) { u32 tmp; OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset | @@ -349,7 +249,9 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo) INREG(HOST_PATH_CNTL); OUTREG(HOST_PATH_CNTL, host_path_cntl); - if (!IS_R300_VARIANT(rinfo)) + if (rinfo->family != CHIP_FAMILY_R300 && + rinfo->family != CHIP_FAMILY_R350 && + rinfo->family != CHIP_FAMILY_RV350) OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); @@ -363,24 +265,15 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) /* disable 3D engine */ OUTREG(RB3D_CNTL, 0); - rinfo->fifo_free = 0; radeonfb_engine_reset(rinfo); - radeon_fifo_wait(rinfo, 1); - if (IS_R300_VARIANT(rinfo)) { - OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) | - RB2D_DC_AUTOFLUSH_ENABLE | - RB2D_DC_DC_DISABLE_IGNORE_PE); - } else { - /* This needs to be double checked with ATI. Latest X driver - * completely "forgets" to set this register on < r3xx, and - * we used to just write 0 there... I'll keep the 0 and update - * that when we have sorted things out on X side. - */ + radeon_fifo_wait (1); + if ((rinfo->family != CHIP_FAMILY_R300) && + (rinfo->family != CHIP_FAMILY_R350) && + (rinfo->family != CHIP_FAMILY_RV350)) OUTREG(RB2D_DSTCACHE_MODE, 0); - } - radeon_fifo_wait(rinfo, 3); + radeon_fifo_wait (3); /* We re-read MC_FB_LOCATION from card as it can have been * modified by XFree drivers (ouch !) */ @@ -391,57 +284,41 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); - radeon_fifo_wait(rinfo, 1); -#ifdef __BIG_ENDIAN + radeon_fifo_wait (1); +#if defined(__BIG_ENDIAN) OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); #else OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); #endif - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait (2); OUTREG(DEFAULT_SC_TOP_LEFT, 0); OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX)); - /* set default DP_GUI_MASTER_CNTL */ temp = radeon_get_dstbpp(rinfo->depth); - rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); + rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); - rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base | - GMC_BRUSH_SOLID_COLOR | - GMC_SRC_DATATYPE_COLOR; - radeon_fifo_wait(rinfo, 1); - OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache); + radeon_fifo_wait (1); + OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | + GMC_BRUSH_SOLID_COLOR | + GMC_SRC_DATATYPE_COLOR)); + radeon_fifo_wait (7); /* clear line drawing regs */ - radeon_fifo_wait(rinfo, 2); OUTREG(DST_LINE_START, 0); OUTREG(DST_LINE_END, 0); - /* set brush and source color regs */ - rinfo->dp_brush_fg_cache = 0xffffffff; - rinfo->dp_brush_bg_cache = 0x00000000; - rinfo->dp_src_fg_cache = 0xffffffff; - rinfo->dp_src_bg_cache = 0x00000000; - radeon_fifo_wait(rinfo, 4); - OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache); - OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache); - OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache); - OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache); - - /* Default direction */ - rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM; - radeon_fifo_wait(rinfo, 1); - OUTREG(DP_CNTL, rinfo->dp_cntl_cache); + /* set brush color regs */ + OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); + + /* set source color regs */ + OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(DP_SRC_BKGD_CLR, 0x00000000); /* default write mask */ - radeon_fifo_wait(rinfo, 1); OUTREG(DP_WRITE_MSK, 0xffffffff); - /* Default to no swapping of host data */ - radeon_fifo_wait(rinfo, 1); - OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE); - - /* Make sure it's settled */ - radeon_engine_idle(rinfo); + radeon_engine_idle (); } diff --git a/trunk/drivers/video/aty/radeon_backlight.c b/trunk/drivers/video/aty/radeon_backlight.c index f343ba83f0ae..1a056adb61c8 100644 --- a/trunk/drivers/video/aty/radeon_backlight.c +++ b/trunk/drivers/video/aty/radeon_backlight.c @@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd) level = bd->props.brightness; del_timer_sync(&rinfo->lvds_timer); - radeon_engine_idle(rinfo); + radeon_engine_idle(); lvds_gen_cntl = INREG(LVDS_GEN_CNTL); if (level > 0) { diff --git a/trunk/drivers/video/aty/radeon_base.c b/trunk/drivers/video/aty/radeon_base.c index 9a5821c65ebf..652273e9f5f9 100644 --- a/trunk/drivers/video/aty/radeon_base.c +++ b/trunk/drivers/video/aty/radeon_base.c @@ -852,6 +852,7 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var, if (rinfo->asleep) return 0; + radeon_fifo_wait(2); OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7); return 0; @@ -881,6 +882,7 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd, if (rc) return rc; + radeon_fifo_wait(2); if (value & 0x01) { tmp = INREG(LVDS_GEN_CNTL); @@ -938,7 +940,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch) if (rinfo->lock_blank) return 0; - radeon_engine_idle(rinfo); + radeon_engine_idle(); val = INREG(CRTC_EXT_CNTL); val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | @@ -1046,7 +1048,7 @@ static int radeonfb_blank (int blank, struct fb_info *info) if (rinfo->asleep) return 0; - + return radeon_screen_blank(rinfo, blank, 0); } @@ -1072,6 +1074,8 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, pindex = regno; if (!rinfo->asleep) { + radeon_fifo_wait(9); + if (rinfo->bpp == 16) { pindex = regno * 8; @@ -1240,6 +1244,8 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg { int i; + radeon_fifo_wait(20); + /* Workaround from XFree */ if (rinfo->is_mobility) { /* A temporal workaround for the occational blanking on certain laptop @@ -1280,10 +1286,11 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg radeon_pll_errata_after_data(rinfo); /* Set PPLL ref. div */ - if (IS_R300_VARIANT(rinfo) || + if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_RS300 || - rinfo->family == CHIP_FAMILY_RS400 || - rinfo->family == CHIP_FAMILY_RS480) { + rinfo->family == CHIP_FAMILY_R350 || + rinfo->family == CHIP_FAMILY_RV350 || + rinfo->family == CHIP_FAMILY_RV380 ) { if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { /* When restoring console mode, use saved PPLL_REF_DIV * setting. @@ -1335,7 +1342,7 @@ static void radeon_lvds_timer_func(unsigned long data) { struct radeonfb_info *rinfo = (struct radeonfb_info *)data; - radeon_engine_idle(rinfo); + radeon_engine_idle(); OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); } @@ -1353,11 +1360,10 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, if (nomodeset) return; - radeon_engine_idle(rinfo); - if (!regs_only) radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); + radeon_fifo_wait(31); for (i=0; i<10; i++) OUTREG(common_regs[i].reg, common_regs[i].val); @@ -1385,6 +1391,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, radeon_write_pll_regs(rinfo, mode); if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { + radeon_fifo_wait(10); OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); @@ -1399,6 +1406,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, if (!regs_only) radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); + radeon_fifo_wait(2); OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); return; @@ -1453,7 +1461,10 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs /* Not all chip revs have the same format for this register, * extract the source selection */ - if (rinfo->family == CHIP_FAMILY_R200 || IS_R300_VARIANT(rinfo)) { + if (rinfo->family == CHIP_FAMILY_R200 || + rinfo->family == CHIP_FAMILY_R300 || + rinfo->family == CHIP_FAMILY_R350 || + rinfo->family == CHIP_FAMILY_RV350) { source = (fp2_gen_cntl >> 10) & 0x3; /* sourced from transform unit, check for transform unit * own source @@ -1549,7 +1560,7 @@ static int radeonfb_set_par(struct fb_info *info) /* We always want engine to be idle on a mode switch, even * if we won't actually change the mode */ - radeon_engine_idle(rinfo); + radeon_engine_idle(); hSyncStart = mode->xres + mode->right_margin; hSyncEnd = hSyncStart + mode->hsync_len; @@ -1844,6 +1855,7 @@ static int radeonfb_set_par(struct fb_info *info) return 0; } + static struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, .fb_check_var = radeonfb_check_var, @@ -1867,7 +1879,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->par = rinfo; info->pseudo_palette = rinfo->pseudo_palette; info->flags = FBINFO_DEFAULT - | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_XPAN @@ -1994,11 +2005,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) (rinfo->family == CHIP_FAMILY_RS200) || (rinfo->family == CHIP_FAMILY_RS300) || (rinfo->family == CHIP_FAMILY_RC410) || - (rinfo->family == CHIP_FAMILY_RS400) || (rinfo->family == CHIP_FAMILY_RS480) ) { u32 tom = INREG(NB_TOM); tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); + radeon_fifo_wait(6); OUTREG(MC_FB_LOCATION, tom); OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); diff --git a/trunk/drivers/video/aty/radeon_i2c.c b/trunk/drivers/video/aty/radeon_i2c.c index 2c5567175dca..8c8fa35f1b7c 100644 --- a/trunk/drivers/video/aty/radeon_i2c.c +++ b/trunk/drivers/video/aty/radeon_i2c.c @@ -139,8 +139,12 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid) { + u32 reg = rinfo->i2c[conn-1].ddc_reg; u8 *edid; + OUTREG(reg, INREG(reg) & + ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); + edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); if (out_edid) diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index 3df5015f1d13..675abdafc2d8 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { /* Make sure engine is reset */ - radeon_engine_idle(rinfo); + radeon_engine_idle(); radeonfb_engine_reset(rinfo); - radeon_engine_idle(rinfo); + radeon_engine_idle(); } /* Blank display and LCD */ @@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev) rinfo->asleep = 0; } else - radeon_engine_idle(rinfo); + radeon_engine_idle(); /* Restore display & engine */ radeon_write_mode (rinfo, &rinfo->state, 1); diff --git a/trunk/drivers/video/aty/radeonfb.h b/trunk/drivers/video/aty/radeonfb.h index ea0b5b47acaf..ccbfffd12805 100644 --- a/trunk/drivers/video/aty/radeonfb.h +++ b/trunk/drivers/video/aty/radeonfb.h @@ -53,7 +53,6 @@ enum radeon_family { CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ CHIP_FAMILY_R420, /* R420/R423/M18 */ CHIP_FAMILY_RC410, - CHIP_FAMILY_RS400, CHIP_FAMILY_RS480, CHIP_FAMILY_LAST, }; @@ -336,15 +335,7 @@ struct radeonfb_info { int mon2_type; u8 *mon2_EDID; - /* accel bits */ - u32 dp_gui_mc_base; - u32 dp_gui_mc_cache; - u32 dp_cntl_cache; - u32 dp_brush_fg_cache; - u32 dp_brush_bg_cache; - u32 dp_src_fg_cache; - u32 dp_src_bg_cache; - u32 fifo_free; + u32 dp_gui_master_cntl; struct pll_info pll; @@ -356,7 +347,6 @@ struct radeonfb_info { int lock_blank; int dynclk; int no_schedule; - int gfx_mode; enum radeon_pm_mode pm_mode; reinit_function_ptr reinit_func; @@ -401,14 +391,8 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) #define INREG16(addr) readw((rinfo->mmio_base)+addr) #define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) - -#ifdef CONFIG_PPC -#define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); }) -#define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0) -#else #define INREG(addr) readl((rinfo->mmio_base)+addr) #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) -#endif static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask) @@ -549,25 +533,16 @@ static inline u32 radeon_get_dstbpp(u16 depth) /* * 2D Engine helper routines */ - -extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries); - static inline void radeon_engine_flush (struct radeonfb_info *rinfo) { int i; - /* Initiate flush */ - OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, + /* initiate flush */ + OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, ~RB2D_DC_FLUSH_ALL); - /* Ensure FIFO is empty, ie, make sure the flush commands - * has reached the cache - */ - radeon_fifo_update_and_wait(rinfo, 64); - - /* Wait for the flush to complete */ for (i=0; i < 2000000; i++) { - if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) + if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) return; udelay(1); } @@ -575,12 +550,25 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo) } -static inline void radeon_engine_idle(struct radeonfb_info *rinfo) +static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) +{ + int i; + + for (i=0; i<2000000; i++) { + if ((INREG(RBBM_STATUS) & 0x7f) >= entries) + return; + udelay(1); + } + printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); +} + + +static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) { int i; /* ensure FIFO is empty before waiting for idle */ - radeon_fifo_update_and_wait (rinfo, 64); + _radeon_fifo_wait (rinfo, 64); for (i=0; i<2000000; i++) { if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { @@ -593,6 +581,8 @@ static inline void radeon_engine_idle(struct radeonfb_info *rinfo) } +#define radeon_engine_idle() _radeon_engine_idle(rinfo) +#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) #define radeon_msleep(ms) _radeon_msleep(rinfo,ms) @@ -622,7 +612,6 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image); extern int radeonfb_sync(struct fb_info *info); extern void radeonfb_engine_init (struct radeonfb_info *rinfo); extern void radeonfb_engine_reset(struct radeonfb_info *rinfo); -extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo); /* Other functions */ extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch); diff --git a/trunk/drivers/video/backlight/mbp_nvidia_bl.c b/trunk/drivers/video/backlight/mbp_nvidia_bl.c index 06964af761c6..385cba40ea87 100644 --- a/trunk/drivers/video/backlight/mbp_nvidia_bl.c +++ b/trunk/drivers/video/backlight/mbp_nvidia_bl.c @@ -111,4 +111,6 @@ module_exit(mbp_exit); MODULE_AUTHOR("Matthew Garrett "); MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver"); MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(dmi, mbp_device_table); +MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,1"); +MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,2"); +MODULE_ALIAS("svnAppleInc.:pnMacBookPro4,1"); diff --git a/trunk/drivers/video/carminefb.c b/trunk/drivers/video/carminefb.c index c9b191319a9a..e15bb447440a 100644 --- a/trunk/drivers/video/carminefb.c +++ b/trunk/drivers/video/carminefb.c @@ -535,7 +535,7 @@ static struct fb_ops carminefb_ops = { .fb_setcolreg = carmine_setcolreg, }; -static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base, +static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base, int smem_offset, struct device *device, struct fb_info **rinfo) { int ret; diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index 048b139f0e50..e729fb279645 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -327,7 +327,29 @@ static const struct { #endif /* CONFIG_ZORRO */ struct cirrusfb_regs { - int multiplexing; + long freq; + long nom; + long den; + long div; + long multiplexing; + long mclk; + long divMCLK; + + long HorizRes; /* The x resolution in pixel */ + long HorizTotal; + long HorizDispEnd; + long HorizBlankStart; + long HorizBlankEnd; + long HorizSyncStart; + long HorizSyncEnd; + + long VertRes; /* the physical y resolution in scanlines */ + long VertTotal; + long VertDispEnd; + long VertSyncStart; + long VertSyncEnd; + long VertBlankStart; + long VertBlankEnd; }; #ifdef CIRRUSFB_DEBUG @@ -345,13 +367,110 @@ struct cirrusfb_info { struct cirrusfb_regs currentmode; int blank_mode; - u32 pseudo_palette[16]; + u32 pseudo_palette[16]; + +#ifdef CONFIG_ZORRO + struct zorro_dev *zdev; +#endif +#ifdef CONFIG_PCI + struct pci_dev *pdev; +#endif void (*unmap)(struct fb_info *info); }; -static int noaccel __devinitdata; -static char *mode_option __devinitdata = "640x480@60"; +static unsigned cirrusfb_def_mode = 1; +static int noaccel; + +/* + * Predefined Video Modes + */ + +static const struct { + const char *name; + struct fb_var_screeninfo var; +} cirrusfb_predefined[] = { + { + /* autodetect mode */ + .name = "Autodetect", + }, { + /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */ + .name = "640x480", + .var = { + .xres = 640, + .yres = 480, + .xres_virtual = 640, + .yres_virtual = 480, + .bits_per_pixel = 8, + .red = { .length = 8 }, + .green = { .length = 8 }, + .blue = { .length = 8 }, + .width = -1, + .height = -1, + .pixclock = 40000, + .left_margin = 48, + .right_margin = 16, + .upper_margin = 32, + .lower_margin = 8, + .hsync_len = 96, + .vsync_len = 4, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED + } + }, { + /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */ + .name = "800x600", + .var = { + .xres = 800, + .yres = 600, + .xres_virtual = 800, + .yres_virtual = 600, + .bits_per_pixel = 8, + .red = { .length = 8 }, + .green = { .length = 8 }, + .blue = { .length = 8 }, + .width = -1, + .height = -1, + .pixclock = 20000, + .left_margin = 128, + .right_margin = 16, + .upper_margin = 24, + .lower_margin = 2, + .hsync_len = 96, + .vsync_len = 6, + .vmode = FB_VMODE_NONINTERLACED + } + }, { + /* + * Modeline from XF86Config: + * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805 + */ + /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */ + .name = "1024x768", + .var = { + .xres = 1024, + .yres = 768, + .xres_virtual = 1024, + .yres_virtual = 768, + .bits_per_pixel = 8, + .red = { .length = 8 }, + .green = { .length = 8 }, + .blue = { .length = 8 }, + .width = -1, + .height = -1, + .pixclock = 12500, + .left_margin = 144, + .right_margin = 32, + .upper_margin = 30, + .lower_margin = 2, + .hsync_len = 192, + .vsync_len = 6, + .vmode = FB_VMODE_NONINTERLACED + } + } +}; + +#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined) /****************************************************************************/ /**** BEGIN PROTOTYPES ******************************************************/ @@ -395,6 +514,10 @@ static struct fb_ops cirrusfb_ops = { .fb_imageblit = cirrusfb_imageblit, }; +/*--- Hardware Specific Routines -------------------------------------------*/ +static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, + struct cirrusfb_regs *regs, + struct fb_info *info); /*--- Internal routines ----------------------------------------------------*/ static void init_vgachip(struct fb_info *info); static void switch_monitor(struct cirrusfb_info *cinfo, int on); @@ -423,7 +546,9 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, u_short width, u_short height, u_char color, u_short line_length); -static void bestclock(long freq, int *nom, int *den, int *div); +static void bestclock(long freq, long *best, + long *nom, long *den, + long *div, long maxfreq); #ifdef CIRRUSFB_DEBUG static void cirrusfb_dump(void); @@ -459,28 +584,45 @@ static int cirrusfb_release(struct fb_info *info, int user) /****************************************************************************/ /**** BEGIN Hardware specific Routines **************************************/ -/* Check if the MCLK is not a better clock source */ -static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq) +/* Get a good MCLK value */ +static long cirrusfb_get_mclk(long freq, int bpp, long *div) { - long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; + long mclk; - /* Read MCLK value */ - mclk = (14318 * mclk) >> 3; - DPRINTK("Read MCLK of %ld kHz\n", mclk); + assert(div != NULL); - /* Determine if we should use MCLK instead of VCLK, and if so, what we - * should divide it by to get VCLK - */ + /* Calculate MCLK, in case VCLK is high enough to require > 50MHz. + * Assume a 64-bit data path for now. The formula is: + * ((B * PCLK * 2)/W) * 1.2 + * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */ + mclk = ((bpp / 8) * freq * 2) / 4; + mclk = (mclk * 12) / 10; + if (mclk < 50000) + mclk = 50000; + DPRINTK("Use MCLK of %ld kHz\n", mclk); + + /* Calculate value for SR1F. Multiply by 2 so we can round up. */ + mclk = ((mclk * 16) / 14318); + mclk = (mclk + 1) / 2; + DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk); - if (abs(freq - mclk) < 250) { - DPRINTK("Using VCLK = MCLK\n"); - return 1; - } else if (abs(freq - (mclk / 2)) < 250) { + /* Determine if we should use MCLK instead of VCLK, and if so, what we + * should divide it by to get VCLK */ + switch (freq) { + case 24751 ... 25249: + *div = 2; DPRINTK("Using VCLK = MCLK/2\n"); - return 2; + break; + case 49501 ... 50499: + *div = 1; + DPRINTK("Using VCLK = MCLK\n"); + break; + default: + *div = 0; + break; } - return 0; + return mclk; } static int cirrusfb_check_var(struct fb_var_screeninfo *var, @@ -496,6 +638,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, break; /* 8 pixel per byte, only 1/4th of mem usable */ case 8: case 16: + case 24: case 32: break; /* 1 pixel == 1 byte */ default: @@ -570,6 +713,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, var->blue.length = 5; break; + case 24: case 32: if (isPReP) { var->red.offset = 8; @@ -623,6 +767,8 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, long maxclock; int maxclockidx = var->bits_per_pixel >> 3; struct cirrusfb_info *cinfo = info->par; + int xres, hfront, hsync, hback; + int yres, vfront, vsync, vback; switch (var->bits_per_pixel) { case 1: @@ -636,9 +782,10 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, break; case 16: + case 24: case 32: info->fix.line_length = var->xres_virtual * maxclockidx; - info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.visual = FB_VISUAL_DIRECTCOLOR; break; default: @@ -680,33 +827,90 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, switch (var->bits_per_pixel) { case 16: case 32: - if (var->xres <= 800) + if (regs->HorizRes <= 800) /* Xbh has this type of clock for 32-bit */ freq /= 2; break; } #endif + + bestclock(freq, ®s->freq, ®s->nom, ®s->den, ®s->div, + maxclock); + regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel, + ®s->divMCLK); + + xres = var->xres; + hfront = var->right_margin; + hsync = var->hsync_len; + hback = var->left_margin; + + yres = var->yres; + vfront = var->lower_margin; + vsync = var->vsync_len; + vback = var->upper_margin; + + if (var->vmode & FB_VMODE_DOUBLE) { + yres *= 2; + vfront *= 2; + vsync *= 2; + vback *= 2; + } else if (var->vmode & FB_VMODE_INTERLACED) { + yres = (yres + 1) / 2; + vfront = (vfront + 1) / 2; + vsync = (vsync + 1) / 2; + vback = (vback + 1) / 2; + } + regs->HorizRes = xres; + regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5; + regs->HorizDispEnd = xres / 8 - 1; + regs->HorizBlankStart = xres / 8; + /* does not count with "-5" */ + regs->HorizBlankEnd = regs->HorizTotal + 5; + regs->HorizSyncStart = (xres + hfront) / 8 + 1; + regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1; + + regs->VertRes = yres; + regs->VertTotal = yres + vfront + vsync + vback - 2; + regs->VertDispEnd = yres - 1; + regs->VertBlankStart = yres; + regs->VertBlankEnd = regs->VertTotal; + regs->VertSyncStart = yres + vfront - 1; + regs->VertSyncEnd = yres + vfront + vsync - 1; + + if (regs->VertRes >= 1024) { + regs->VertTotal /= 2; + regs->VertSyncStart /= 2; + regs->VertSyncEnd /= 2; + regs->VertDispEnd /= 2; + } + if (regs->multiplexing) { + regs->HorizTotal /= 2; + regs->HorizSyncStart /= 2; + regs->HorizSyncEnd /= 2; + regs->HorizDispEnd /= 2; + } + return 0; } -static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo, - int div) +static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val, + int div) { - unsigned char old1f, old1e; assert(cinfo != NULL); - old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40; - - if (div) { - DPRINTK("Set %s as pixclock source.\n", - (div == 2) ? "MCLK/2" : "MCLK"); - old1f |= 0x40; - old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1; - if (div == 2) - old1e |= 1; - vga_wseq(cinfo->regbase, CL_SEQR1E, old1e); + if (div == 2) { + /* VCLK = MCLK/2 */ + unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E); + vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1); + vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); + } else if (div == 1) { + /* VCLK = MCLK */ + unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E); + vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1); + vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); + } else { + vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f); } - vga_wseq(cinfo->regbase, CL_SEQR1F, old1f); } /************************************************************************* @@ -723,10 +927,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info) unsigned char tmp; int offset = 0, err; const struct cirrusfb_board_info_rec *bi; - int hdispend, hsyncstart, hsyncend, htotal; - int yres, vdispend, vsyncstart, vsyncend, vtotal; - long freq; - int nom, den, div; DPRINTK("ENTER\n"); DPRINTK("Requested mode: %dx%dx%d\n", @@ -744,117 +944,76 @@ static int cirrusfb_set_par_foo(struct fb_info *info) bi = &cirrusfb_board_info[cinfo->btype]; - hsyncstart = var->xres + var->right_margin; - hsyncend = hsyncstart + var->hsync_len; - htotal = (hsyncend + var->left_margin) / 8 - 5; - hdispend = var->xres / 8 - 1; - hsyncstart = hsyncstart / 8 + 1; - hsyncend = hsyncend / 8 + 1; - - yres = var->yres; - vsyncstart = yres + var->lower_margin; - vsyncend = vsyncstart + var->vsync_len; - vtotal = vsyncend + var->upper_margin; - vdispend = yres - 1; - - if (var->vmode & FB_VMODE_DOUBLE) { - yres *= 2; - vsyncstart *= 2; - vsyncend *= 2; - vtotal *= 2; - } else if (var->vmode & FB_VMODE_INTERLACED) { - yres = (yres + 1) / 2; - vsyncstart = (vsyncstart + 1) / 2; - vsyncend = (vsyncend + 1) / 2; - vtotal = (vtotal + 1) / 2; - } - - vtotal -= 2; - vsyncstart -= 1; - vsyncend -= 1; - - if (yres >= 1024) { - vtotal /= 2; - vsyncstart /= 2; - vsyncend /= 2; - vdispend /= 2; - } - if (regs.multiplexing) { - htotal /= 2; - hsyncstart /= 2; - hsyncend /= 2; - hdispend /= 2; - } /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ /* if debugging is enabled, all parameters get output before writing */ - DPRINTK("CRT0: %d\n", htotal); - vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal); + DPRINTK("CRT0: %ld\n", regs.HorizTotal); + vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal); - DPRINTK("CRT1: %d\n", hdispend); - vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend); + DPRINTK("CRT1: %ld\n", regs.HorizDispEnd); + vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd); - DPRINTK("CRT2: %d\n", var->xres / 8); - vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8); + DPRINTK("CRT2: %ld\n", regs.HorizBlankStart); + vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart); /* + 128: Compatible read */ - DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32); + DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32); vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, - 128 + ((htotal + 5) % 32)); + 128 + (regs.HorizBlankEnd % 32)); - DPRINTK("CRT4: %d\n", hsyncstart); - vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart); + DPRINTK("CRT4: %ld\n", regs.HorizSyncStart); + vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart); - tmp = hsyncend % 32; - if ((htotal + 5) & 32) + tmp = regs.HorizSyncEnd % 32; + if (regs.HorizBlankEnd & 32) tmp += 128; DPRINTK("CRT5: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); - DPRINTK("CRT6: %d\n", vtotal & 0xff); - vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff); + DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff); + vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff)); tmp = 16; /* LineCompare bit #9 */ - if (vtotal & 256) + if (regs.VertTotal & 256) tmp |= 1; - if (vdispend & 256) + if (regs.VertDispEnd & 256) tmp |= 2; - if (vsyncstart & 256) + if (regs.VertSyncStart & 256) tmp |= 4; - if ((vdispend + 1) & 256) + if (regs.VertBlankStart & 256) tmp |= 8; - if (vtotal & 512) + if (regs.VertTotal & 512) tmp |= 32; - if (vdispend & 512) + if (regs.VertDispEnd & 512) tmp |= 64; - if (vsyncstart & 512) + if (regs.VertSyncStart & 512) tmp |= 128; DPRINTK("CRT7: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); tmp = 0x40; /* LineCompare bit #8 */ - if ((vdispend + 1) & 512) + if (regs.VertBlankStart & 512) tmp |= 0x20; if (var->vmode & FB_VMODE_DOUBLE) tmp |= 0x80; DPRINTK("CRT9: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); - DPRINTK("CRT10: %d\n", vsyncstart & 0xff); - vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff); + DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff); + vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff); - DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16); - vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32); + DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16); + vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32); - DPRINTK("CRT12: %d\n", vdispend & 0xff); - vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff); + DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff); + vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff); - DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff); - vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff); + DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff); + vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff); - DPRINTK("CRT16: %d\n", vtotal & 0xff); - vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff); + DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff); + vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff); DPRINTK("CRT18: 0xff\n"); vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); @@ -862,53 +1021,38 @@ static int cirrusfb_set_par_foo(struct fb_info *info) tmp = 0; if (var->vmode & FB_VMODE_INTERLACED) tmp |= 1; - if ((htotal + 5) & 64) + if (regs.HorizBlankEnd & 64) tmp |= 16; - if ((htotal + 5) & 128) + if (regs.HorizBlankEnd & 128) tmp |= 32; - if (vtotal & 256) + if (regs.VertBlankEnd & 256) tmp |= 64; - if (vtotal & 512) + if (regs.VertBlankEnd & 512) tmp |= 128; DPRINTK("CRT1a: %d\n", tmp); vga_wcrt(regbase, CL_CRT1A, tmp); - freq = PICOS2KHZ(var->pixclock); - bestclock(freq, &nom, &den, &div); - /* set VCLK0 */ /* hardware RefClock: 14.31818 MHz */ /* formula: VClk = (OSC * N) / (D * (1+P)) */ /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ - if (cinfo->btype == BT_ALPINE) { - /* if freq is close to mclk or mclk/2 select mclk - * as clock source - */ - int divMCLK = cirrusfb_check_mclk(cinfo, freq); - if (divMCLK) { - nom = 0; - cirrusfb_set_mclk_as_source(cinfo, divMCLK); - } - } - if (nom) { - vga_wseq(regbase, CL_SEQRB, nom); - tmp = den << 1; - if (div != 0) - tmp |= 1; + vga_wseq(regbase, CL_SEQRB, regs.nom); + tmp = regs.den << 1; + if (regs.div != 0) + tmp |= 1; - /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ - if ((cinfo->btype == BT_SD64) || - (cinfo->btype == BT_ALPINE) || - (cinfo->btype == BT_GD5480)) - tmp |= 0x80; + /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ + if ((cinfo->btype == BT_SD64) || + (cinfo->btype == BT_ALPINE) || + (cinfo->btype == BT_GD5480)) + tmp |= 0x80; - DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); - vga_wseq(regbase, CL_SEQR1B, tmp); - } + DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); + vga_wseq(regbase, CL_SEQR1B, tmp); - if (yres >= 1024) + if (regs.VertRes >= 1024) /* 1280x1024 */ vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7); else @@ -922,7 +1066,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) /* don't know if it would hurt to also program this if no interlaced */ /* mode is used, but I feel better this way.. :-) */ if (var->vmode & FB_VMODE_INTERLACED) - vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2); + vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2); else vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ @@ -1096,6 +1240,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_ALPINE: DPRINTK(" (for GD543x)\n"); + cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK); /* We already set SRF and SR1F */ break; @@ -1167,7 +1312,11 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_ALPINE: DPRINTK(" (for GD543x)\n"); - vga_wseq(regbase, CL_SEQR7, 0xa7); + if (regs.HorizRes >= 1024) + vga_wseq(regbase, CL_SEQR7, 0xa7); + else + vga_wseq(regbase, CL_SEQR7, 0xa3); + cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK); break; case BT_GD5480: @@ -1211,7 +1360,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else if (var->bits_per_pixel == 32) { - DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n"); switch (cinfo->btype) { case BT_SD64: /* Extended Sequencer Mode: 256c col. mode */ @@ -1245,6 +1394,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_ALPINE: DPRINTK(" (for GD543x)\n"); vga_wseq(regbase, CL_SEQR7, 0xa9); + cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK); break; case BT_GD5480: @@ -1799,6 +1949,8 @@ static void init_vgachip(struct fb_info *info) /* misc... */ WHDR(cinfo, 0); /* Hidden DAC register: - */ + printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n", + info->screen_size); DPRINTK("EXIT\n"); return; } @@ -1970,7 +2122,7 @@ static int release_io_ports; * based on the DRAM bandwidth bit and DRAM bank switching bit. This * works with 1MB, 2MB and 4MB configurations (which the Motorola boards * seem to have. */ -static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase) +static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase) { unsigned long mem; unsigned char SRF; @@ -2036,7 +2188,8 @@ static void get_pci_addrs(const struct pci_dev *pdev, static void cirrusfb_pci_unmap(struct fb_info *info) { - struct pci_dev *pdev = to_pci_dev(info->device); + struct cirrusfb_info *cinfo = info->par; + struct pci_dev *pdev = cinfo->pdev; iounmap(info->screen_base); #if 0 /* if system didn't claim this region, we would... */ @@ -2052,22 +2205,20 @@ static void cirrusfb_pci_unmap(struct fb_info *info) static void __devexit cirrusfb_zorro_unmap(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; - struct zorro_dev *zdev = to_zorro_dev(info->device); - - zorro_release_device(zdev); + zorro_release_device(cinfo->zdev); if (cinfo->btype == BT_PICASSO4) { cinfo->regbase -= 0x600000; iounmap((void *)cinfo->regbase); iounmap(info->screen_base); } else { - if (zorro_resource_start(zdev) > 0x01000000) + if (zorro_resource_start(cinfo->zdev) > 0x01000000) iounmap(info->screen_base); } } #endif /* CONFIG_ZORRO */ -static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) +static int cirrusfb_set_fbinfo(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; struct fb_var_screeninfo *var = &info->var; @@ -2084,7 +2235,7 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) if (cinfo->btype == BT_GD5480) { if (var->bits_per_pixel == 16) info->screen_base += 1 * MB_; - if (var->bits_per_pixel == 32) + if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32) info->screen_base += 2 * MB_; } @@ -2111,7 +2262,7 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) return 0; } -static int __devinit cirrusfb_register(struct fb_info *info) +static int cirrusfb_register(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; int err; @@ -2127,27 +2278,23 @@ static int __devinit cirrusfb_register(struct fb_info *info) /* sanity checks */ assert(btype != BT_NONE); - /* set all the vital stuff */ - cirrusfb_set_fbinfo(info); - DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); - err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); - if (!err) { - DPRINTK("wrong initial video mode\n"); - err = -EINVAL; - goto err_dealloc_cmap; - } - + /* Make pretend we've set the var so our structures are in a "good" */ + /* state, even though we haven't written the mode to the hw yet... */ + info->var = cirrusfb_predefined[cirrusfb_def_mode].var; info->var.activate = FB_ACTIVATE_NOW; err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); if (err < 0) { /* should never happen */ DPRINTK("choking on default var... umm, no good.\n"); - goto err_dealloc_cmap; + goto err_unmap_cirrusfb; } + /* set all the vital stuff */ + cirrusfb_set_fbinfo(info); + err = register_framebuffer(info); if (err < 0) { printk(KERN_ERR "cirrusfb: could not register " @@ -2160,6 +2307,7 @@ static int __devinit cirrusfb_register(struct fb_info *info) err_dealloc_cmap: fb_dealloc_cmap(&info->cmap); +err_unmap_cirrusfb: cinfo->unmap(info); framebuffer_release(info); return err; @@ -2182,8 +2330,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info) } #ifdef CONFIG_PCI -static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int cirrusfb_pci_register(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct cirrusfb_info *cinfo; struct fb_info *info; @@ -2205,6 +2353,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, } cinfo = info->par; + cinfo->pdev = pdev; cinfo->btype = btype = (enum cirrus_board) ent->driver_data; DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", @@ -2310,8 +2459,8 @@ static struct pci_driver cirrusfb_pci_driver = { #endif /* CONFIG_PCI */ #ifdef CONFIG_ZORRO -static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, - const struct zorro_device_id *ent) +static int cirrusfb_zorro_register(struct zorro_dev *z, + const struct zorro_device_id *ent) { struct cirrusfb_info *cinfo; struct fb_info *info; @@ -2340,6 +2489,7 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, assert(z); assert(btype != BT_NONE); + cinfo->zdev = z; board_addr = zorro_resource_start(z); board_size = zorro_resource_len(z); info->screen_size = size; @@ -2471,17 +2621,17 @@ static int __init cirrusfb_setup(char *options) { return 0; while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) - continue; + if (!*this_opt) continue; DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); + for (i = 0; i < NUM_TOTAL_MODES; i++) { + sprintf(s, "mode:%s", cirrusfb_predefined[i].name); + if (strcmp(this_opt, s) == 0) + cirrusfb_def_mode = i; + } if (!strcmp(this_opt, "noaccel")) noaccel = 1; - else if (!strncmp(this_opt, "mode:", 5)) - mode_option = this_opt + 5; - else - mode_option = this_opt; } return 0; } @@ -2507,11 +2657,6 @@ static void __exit cirrusfb_exit(void) module_init(cirrusfb_init); -module_param(mode_option, charp, 0); -MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); -module_param(noaccel, bool, 0); -MODULE_PARM_DESC(noaccel, "Disable acceleration"); - #ifdef MODULE module_exit(cirrusfb_exit); #endif @@ -2905,14 +3050,16 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, * bestclock() - determine closest possible clock lower(?) than the * desired pixel clock **************************************************************************/ -static void bestclock(long freq, int *nom, int *den, int *div) +static void bestclock(long freq, long *best, long *nom, + long *den, long *div, long maxfreq) { - int n, d; - long h, diff; + long n, h, d, f; + assert(best != NULL); assert(nom != NULL); assert(den != NULL); assert(div != NULL); + assert(maxfreq > 0); *nom = 0; *den = 0; @@ -2923,47 +3070,51 @@ static void bestclock(long freq, int *nom, int *den, int *div) if (freq < 8000) freq = 8000; - diff = freq; + if (freq > maxfreq) + freq = maxfreq; - for (n = 32; n < 128; n++) { - int s = 0; + *best = 0; + f = freq * 10; - d = (14318 * n) / freq; + for (n = 32; n < 128; n++) { + d = (143181 * n) / f; if ((d >= 7) && (d <= 63)) { - int temp = d; - - if (temp > 31) { - s = 1; - temp >>= 1; - } - h = ((14318 * n) / temp) >> s; - h = h > freq ? h - freq : freq - h; - if (h < diff) { - diff = h; + if (d > 31) + d = (d / 2) * 2; + h = (14318 * n) / d; + if (abs(h - freq) < abs(*best - freq)) { + *best = h; *nom = n; - *den = temp; - *div = s; + if (d < 32) { + *den = d; + *div = 0; + } else { + *den = d / 2; + *div = 1; + } } } - d++; + d = DIV_ROUND_UP(143181 * n, f); if ((d >= 7) && (d <= 63)) { - if (d > 31) { - s = 1; - d >>= 1; - } - h = ((14318 * n) / d) >> s; - h = h > freq ? h - freq : freq - h; - if (h < diff) { - diff = h; + if (d > 31) + d = (d / 2) * 2; + h = (14318 * n) / d; + if (abs(h - freq) < abs(*best - freq)) { + *best = h; *nom = n; - *den = d; - *div = s; + if (d < 32) { + *den = d; + *div = 0; + } else { + *den = d / 2; + *div = 1; + } } } } DPRINTK("Best possible values for given frequency:\n"); - DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n", + DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n", freq, *nom, *den, *div); DPRINTK("EXIT\n"); diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 64b3d30027b8..9cbff84b787d 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -1855,6 +1855,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; + unsigned short saved_ec; + int ret; if (fbcon_is_inactive(vc, info)) return -EINVAL; @@ -1867,6 +1869,11 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, * whole screen (prevents flicker). */ + saved_ec = vc->vc_video_erase_char; + vc->vc_video_erase_char = vc->vc_scrl_erase_char; + + ret = 0; + switch (dir) { case SM_UP: if (count > vc->vc_rows) /* Maximum realistic size */ @@ -1883,9 +1890,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, scr_memsetw((unsigned short *) (vc->vc_origin + vc->vc_size_row * (b - count)), - vc->vc_video_erase_char, + vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; break; case SCROLL_WRAP_MOVE: @@ -1955,9 +1962,10 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, scr_memsetw((unsigned short *) (vc->vc_origin + vc->vc_size_row * (b - count)), - vc->vc_video_erase_char, + vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; + break; } break; @@ -1974,9 +1982,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, scr_memsetw((unsigned short *) (vc->vc_origin + vc->vc_size_row * t), - vc->vc_video_erase_char, + vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; break; case SCROLL_WRAP_MOVE: @@ -2044,12 +2052,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, scr_memsetw((unsigned short *) (vc->vc_origin + vc->vc_size_row * t), - vc->vc_video_erase_char, + vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; + break; } + break; } - return 0; + vc->vc_video_erase_char = saved_ec; + return ret; } @@ -2511,6 +2522,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, c = vc->vc_video_erase_char; vc->vc_video_erase_char = ((c & 0xfe00) >> 1) | (c & 0xff); + c = vc->vc_scrl_erase_char; + vc->vc_scrl_erase_char = + ((c & 0xFE00) >> 1) | (c & 0xFF); vc->vc_attr >>= 1; } } else if (!vc->vc_hi_font_mask && cnt == 512) { @@ -2541,9 +2555,14 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, if (vc->vc_can_do_color) { vc->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff); + c = vc->vc_scrl_erase_char; + vc->vc_scrl_erase_char = + ((c & 0xFF00) << 1) | (c & 0xFF); vc->vc_attr <<= 1; - } else + } else { vc->vc_video_erase_char = c & ~0x100; + vc->vc_scrl_erase_char = c & ~0x100; + } } } @@ -2977,8 +2996,8 @@ static void fbcon_set_all_vcs(struct fb_info *info) p = &fb_display[vc->vc_num]; set_blitting_type(vc, info); var_to_display(p, &info->var, info); - cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); - rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; vc_resize(vc, cols, rows); @@ -3573,8 +3592,8 @@ static int __init fb_console_init(void) acquire_console_sem(); fb_register_client(&fbcon_event_notifier); - fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL, - "fbcon"); + fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0), + NULL, "fbcon"); if (IS_ERR(fbcon_device)) { printk(KERN_WARNING "Unable to create device " diff --git a/trunk/drivers/video/console/mdacon.c b/trunk/drivers/video/console/mdacon.c index dd3eaaad4441..9901064199bd 100644 --- a/trunk/drivers/video/console/mdacon.c +++ b/trunk/drivers/video/console/mdacon.c @@ -533,7 +533,7 @@ static void mdacon_cursor(struct vc_data *c, int mode) static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines) { - u16 eattr = mda_convert_attr(c->vc_video_erase_char); + u16 eattr = mda_convert_attr(c->vc_scrl_erase_char); if (!lines) return 0; diff --git a/trunk/drivers/video/console/sticon.c b/trunk/drivers/video/console/sticon.c index 491c1c1baf4c..4055dbdd1b42 100644 --- a/trunk/drivers/video/console/sticon.c +++ b/trunk/drivers/video/console/sticon.c @@ -170,12 +170,12 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count) switch (dir) { case SM_UP: sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); - sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); + sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_scrl_erase_char); break; case SM_DOWN: sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); - sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); + sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_scrl_erase_char); break; } diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index 448d209a0bf2..bd1f57b259d9 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -239,7 +239,8 @@ static void vgacon_restore_screen(struct vc_data *c) static int vgacon_scrolldelta(struct vc_data *c, int lines) { - int start, end, count, soff; + int start, end, count, soff, diff; + void *d, *s; if (!lines) { c->vc_visible_origin = c->vc_origin; @@ -286,29 +287,29 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) if (count > c->vc_rows) count = c->vc_rows; - if (count) { - int copysize; + diff = c->vc_rows - count; - int diff = c->vc_rows - count; - void *d = (void *) c->vc_origin; - void *s = (void *) c->vc_screenbuf; + d = (void *) c->vc_origin; + s = (void *) c->vc_screenbuf; - count *= c->vc_size_row; - /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); - d += copysize; - count -= copysize; + while (count--) { + scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row); + d += c->vc_size_row; + soff += c->vc_size_row; - if (count) { - scr_memcpyw(d, vgacon_scrollback, count); - d += count; - } + if (soff >= vgacon_scrollback_size) + soff = 0; + } - if (diff) - scr_memcpyw(d, s, diff * c->vc_size_row); - } else + if (diff == c->vc_rows) { vgacon_cursor(c, CM_MOVE); + } else { + while (diff--) { + scr_memcpyw(d, s, c->vc_size_row); + d += c->vc_size_row; + s += c->vc_size_row; + } + } return 1; } @@ -1349,7 +1350,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, } else c->vc_origin += delta; scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size - - delta), c->vc_video_erase_char, + delta), c->vc_scrl_erase_char, delta); } else { if (oldo - delta < vga_vram_base) { @@ -1362,7 +1363,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, } else c->vc_origin -= delta; c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; - scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char, + scr_memsetw((u16 *) (c->vc_origin), c->vc_scrl_erase_char, delta); } c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; diff --git a/trunk/drivers/video/display/display-sysfs.c b/trunk/drivers/video/display/display-sysfs.c index 4830b1bf51e5..6ef800bdf482 100644 --- a/trunk/drivers/video/display/display-sysfs.c +++ b/trunk/drivers/video/display/display-sysfs.c @@ -153,9 +153,12 @@ struct display_device *display_device_register(struct display_driver *driver, mutex_unlock(&allocated_dsp_lock); if (!ret) { - new_dev->dev = device_create(display_class, parent, - MKDEV(0, 0), new_dev, - "display%d", new_dev->idx); + new_dev->dev = device_create_drvdata(display_class, + parent, + MKDEV(0,0), + new_dev, + "display%d", + new_dev->idx); if (!IS_ERR(new_dev->dev)) { new_dev->parent = parent; new_dev->driver = driver; diff --git a/trunk/drivers/video/efifb.c b/trunk/drivers/video/efifb.c index daf9b81878a4..bd779ae44b1e 100644 --- a/trunk/drivers/video/efifb.c +++ b/trunk/drivers/video/efifb.c @@ -12,7 +12,6 @@ #include #include #include -#include #include